Skip to content

Commit

Permalink
Merge pull request #5 from vulsio/add-php
Browse files Browse the repository at this point in the history
feat: enable PHP scan
  • Loading branch information
maito1201 authored Mar 28, 2022
2 parents 666a49c + 54f2581 commit 0cab382
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 2 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

licensecheck is tool to detect license of OSS.

It supports java/ruby/python/nodejs/go/rust/github.
It supports java/php/ruby/python/nodejs/go/rust/github.

# feature

Expand Down Expand Up @@ -72,6 +72,7 @@ Information of License will be fetched Data Sources below.
| target | data source |
| ------ | --------------------------------- |
| Java | https://repo1.maven.org |
| PHP | https://packagist.org |
| Ruby | https://rubygems.org |
| Python | https://pypi.org |
| Nodejs | https://registry.npmjs.org |
Expand Down
4 changes: 3 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ func main() {
switch c.String("type") {
case "java":
typ = licensecheck.Java
case "php":
typ = licensecheck.PHP
case "ruby":
typ = licensecheck.Ruby
case "python":
Expand All @@ -53,7 +55,7 @@ func main() {
case "github":
typ = licensecheck.GitHub
default:
return errors.New("please specify option -type in java/ruby/python/nodejs/go/rust/github")
return errors.New("please specify option -type in java/php/ruby/python/nodejs/go/rust/github")
}
result, confidence, err := new(licensecheck.Scanner).Scan(name, version, typ)
if err != nil {
Expand Down
68 changes: 68 additions & 0 deletions core/php/scanner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package php

import (
"encoding/json"
"fmt"
"strings"

"github.com/vulsio/licensecheck/shared"
)

const ref = "https://packagist.org/packages/%s.json"

// Scanner is struct to scan license info
// Crawler is exported to modify or make it easy to test by mock
type Scanner struct {
Crawler shared.Crawler
}

// ScanLicense returns result of fetch https://pypi.org
// version is not required (if version is given, the result will be more rigorous)
func (s *Scanner) ScanLicense(name, version string) (string, float64, error) {
if s.Crawler == nil {
s.Crawler = &shared.DefaultCrawler{}
}
b, err := s.Crawler.Crawl(fmt.Sprintf(ref, name))
if err != nil {
return "unknown", 0, err
}
result, confidence, err := parseResponce(b, version)
if err != nil {
return "unknown", 0, err
}
return result, confidence, nil
}

func parseResponce(b []byte, version string) (string, float64, error) {
license := struct {
Package struct {
Versions map[string]struct {
License []string `json:"license"`
} `json:"versions"`
} `json:"package"`
}{}
if err := json.Unmarshal(b, &license); err != nil {
return "", 0, shared.ErrNotFound
}
if version == "" {
if pkg, ok := license.Package.Versions["dev-main"]; ok {
return joinedResult(pkg.License)
}
if pkg, ok := license.Package.Versions["dev-master"]; ok {
return joinedResult(pkg.License)
}
} else {
if pkg, ok := license.Package.Versions[version]; ok {
return joinedResult(pkg.License)
}
}
return "", 0, shared.ErrNotFound
}

func joinedResult(licenses []string) (string, float64, error) {
s := strings.Join(licenses, ",")
if s == "" {
return "", 0, shared.ErrNotFound
}
return s, 1, nil
}
90 changes: 90 additions & 0 deletions core/php/scanner_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package php

import (
"errors"
"io/ioutil"
"math"
"testing"

"github.com/golang/mock/gomock"
"github.com/vulsio/licensecheck/shared"
"github.com/vulsio/licensecheck/shared/mock"
)

func TestScanLicense(t *testing.T) {
ctrl := gomock.NewController(t)
tests := []struct {
name string
in string
version string
result string
confidence float64
wantErr error
}{
{
name: "success",
in: "../../testdata/php/input1.json",
result: "MIT",
confidence: 1,
},
{
name: "no license info",
in: "../../testdata/php/input2.json",
result: "unknown",
confidence: 0,
wantErr: shared.ErrNotFound,
},
{
name: "package that default is dev-master",
in: "../../testdata/php/input3.json",
result: "MIT",
confidence: 1,
},
{
name: "success with version",
in: "../../testdata/php/input1.json",
version: "1.0.0",
result: "MIT",
confidence: 1,
},
{
name: "no license info with version",
in: "../../testdata/php/input2.json",
version: "1.0.0",
result: "unknown",
confidence: 0,
wantErr: shared.ErrNotFound,
},
{
name: "not exist version",
in: "../../testdata/php/input1.json",
version: "999",
result: "unknown",
confidence: 0,
wantErr: shared.ErrNotFound,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b, err := ioutil.ReadFile(tt.in)
if err != nil {
t.Fatal(err)
}
sc := new(Scanner)
cl := mock.NewMockCrawler(ctrl)
cl.EXPECT().Crawl(gomock.Any()).Return(b, nil)
sc.Crawler = cl

result, confidence, err := sc.ScanLicense("test", tt.version)
if err != nil && !errors.Is(err, tt.wantErr) {
t.Fatal(err)
}
if result != tt.result {
t.Errorf("want: %s, got: %s", tt.result, result)
}
if math.Abs(confidence-tt.confidence) >= 1e-6 {
t.Errorf("want: %f, got: %f", tt.confidence, confidence)
}
})
}
}
4 changes: 4 additions & 0 deletions license.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/vulsio/licensecheck/core/golicense"
"github.com/vulsio/licensecheck/core/java"
"github.com/vulsio/licensecheck/core/nodejs"
"github.com/vulsio/licensecheck/core/php"
"github.com/vulsio/licensecheck/core/python"
"github.com/vulsio/licensecheck/core/ruby"
"github.com/vulsio/licensecheck/core/rust"
Expand All @@ -15,6 +16,7 @@ import (

const (
Java = iota
PHP
Ruby
Python
Nodejs
Expand All @@ -38,6 +40,8 @@ func (s *Scanner) Scan(name, version string, scanType int) (string, float64, err
switch scanType {
case Java:
sc = &java.Scanner{Crawler: s.Crawler}
case PHP:
sc = &php.Scanner{Crawler: s.Crawler}
case Ruby:
sc = &ruby.Scanner{Crawler: s.Crawler}
case Python:
Expand Down
16 changes: 16 additions & 0 deletions testdata/php/input1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"package": {
"versions": {
"dev-main": {
"license": [
"MIT"
]
},
"1.0.0": {
"license": [
"MIT"
]
}
}
}
}
12 changes: 12 additions & 0 deletions testdata/php/input2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"package": {
"versions": {
"dev-main": {
"license": []
},
"1.0.0": {
"license": []
}
}
}
}
16 changes: 16 additions & 0 deletions testdata/php/input3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"package": {
"versions": {
"dev-master": {
"license": [
"MIT"
]
},
"1.0.0": {
"license": [
"MIT"
]
}
}
}
}

0 comments on commit 0cab382

Please sign in to comment.