-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from tphoney/add_javascript_scanner
(feat) add javascript scanner
- Loading branch information
Showing
8 changed files
with
244 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,17 @@ | ||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= | ||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= | ||
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= | ||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= | ||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= | ||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= | ||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= | ||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= | ||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= | ||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d h1:vtUKgx8dahOomfFzLREU8nSv25YHnTgLBn4rDnWZdU0= | ||
golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= | ||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0= | ||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b h1:2n253B2r0pYSmEV+UNCQoPfU/FiaizQEK5Gu4Bq4JE8= | ||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
package javascript | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/tphoney/best_practice/outputter/dronebuild" | ||
"github.com/tphoney/best_practice/scanner" | ||
"github.com/tphoney/best_practice/types" | ||
"golang.org/x/exp/slices" | ||
) | ||
|
||
type scannerConfig struct { | ||
name string | ||
description string | ||
workingDirectory string | ||
checksToRun []string | ||
runAll bool | ||
} | ||
|
||
const ( | ||
packageLocation = "package.json" | ||
Name = "javascript" | ||
BuildCheck = "build_check" | ||
TestCheck = "test_check" | ||
LintCheck = "lint_check" | ||
) | ||
|
||
func New(opts ...Option) (types.Scanner, error) { | ||
sc := new(scannerConfig) | ||
sc.name = Name | ||
sc.description = "checks for various javascript related best practices" | ||
sc.runAll = true | ||
// apply options | ||
for _, opt := range opts { | ||
opt(sc) | ||
} | ||
|
||
return sc, nil | ||
} | ||
|
||
func (sc *scannerConfig) Name() string { | ||
return sc.name | ||
} | ||
|
||
func (sc *scannerConfig) Description() string { | ||
return sc.description | ||
} | ||
|
||
func (sc *scannerConfig) AvailableChecks() []string { | ||
return []string{BuildCheck} | ||
} | ||
|
||
func (sc *scannerConfig) Scan(ctx context.Context, requestedChecks []string) (returnVal []types.Scanlet, err error) { | ||
// lets look for a package file in the directory | ||
_, err = os.Stat(filepath.Join(sc.workingDirectory, packageLocation)) | ||
if err != nil { | ||
// nothing to see here, lets leave | ||
return returnVal, nil | ||
} | ||
var scriptMap map[string]interface{} | ||
var dependencyMap map[string]interface{} | ||
var reactVersion string | ||
packageStruct, err := scanner.ReadJSONFile(filepath.Join(sc.workingDirectory, packageLocation)) | ||
if err == nil { | ||
// look for declared scripts | ||
if packageStruct["scripts"] != nil { | ||
scriptMap = packageStruct["scripts"].(map[string]interface{}) | ||
} | ||
if packageStruct["dependencies"] != nil { | ||
dependencyMap = packageStruct["dependencies"].(map[string]interface{}) | ||
rawReactVersion := dependencyMap["react"].(string) | ||
v, versionErr := scanner.ReturnVersionObject(rawReactVersion) | ||
if versionErr != nil { | ||
fmt.Printf("error parsing react version: %s\n", versionErr.Error()) | ||
} | ||
reactVersion = fmt.Sprint(v.Major()) | ||
} | ||
} else { | ||
return returnVal, err | ||
} | ||
// check for build | ||
if sc.runAll || slices.Contains(requestedChecks, BuildCheck) { | ||
match, outputResults := sc.buildCheck(scriptMap, reactVersion) | ||
if match { | ||
returnVal = append(returnVal, outputResults...) | ||
} | ||
} | ||
if sc.runAll || slices.Contains(requestedChecks, LintCheck) { | ||
match, outputResults := sc.lintCheck(scriptMap, reactVersion) | ||
if match { | ||
returnVal = append(returnVal, outputResults...) | ||
} | ||
} | ||
if sc.runAll || slices.Contains(requestedChecks, TestCheck) { | ||
match, outputResults := sc.testCheck(scriptMap, reactVersion) | ||
if match { | ||
returnVal = append(returnVal, outputResults...) | ||
} | ||
} | ||
|
||
return returnVal, nil | ||
} | ||
|
||
func (sc *scannerConfig) buildCheck(scriptMap map[string]interface{}, reactVersion string) (match bool, outputResults []types.Scanlet) { | ||
if scriptMap["build"] != "" { | ||
droneBuildResult := types.Scanlet{ | ||
Name: BuildCheck, | ||
ScannerFamily: Name, | ||
Description: "run npm build", | ||
OutputRenderer: dronebuild.Name, | ||
Spec: dronebuild.OutputFields{ | ||
RawYaml: fmt.Sprintf(` - name: run npm build | ||
image: node:%s-alpine | ||
commands: | ||
- npm run build`, reactVersion)}, | ||
} | ||
outputResults = append(outputResults, droneBuildResult) | ||
return true, outputResults | ||
} | ||
return false, outputResults | ||
} | ||
|
||
func (sc *scannerConfig) lintCheck(scriptMap map[string]interface{}, reactVersion string) (match bool, outputResults []types.Scanlet) { | ||
if scriptMap["lint"] != "" { | ||
droneBuildResult := types.Scanlet{ | ||
Name: BuildCheck, | ||
ScannerFamily: Name, | ||
Description: "run npm lint", | ||
OutputRenderer: dronebuild.Name, | ||
Spec: dronebuild.OutputFields{ | ||
RawYaml: fmt.Sprintf(` - name: run npm lint | ||
image: node:%s-alpine | ||
commands: | ||
- npm run lint`, reactVersion)}, | ||
} | ||
outputResults = append(outputResults, droneBuildResult) | ||
return true, outputResults | ||
} | ||
return false, outputResults | ||
} | ||
|
||
func (sc *scannerConfig) testCheck(scriptMap map[string]interface{}, reactVersion string) (match bool, outputResults []types.Scanlet) { | ||
if scriptMap["test"] != "" { | ||
droneBuildResult := types.Scanlet{ | ||
Name: BuildCheck, | ||
ScannerFamily: Name, | ||
Description: "run npm test", | ||
OutputRenderer: dronebuild.Name, | ||
Spec: dronebuild.OutputFields{ | ||
RawYaml: fmt.Sprintf(` - name: run npm test | ||
image: node:%s-alpine | ||
commands: | ||
- npm run test`, reactVersion)}, | ||
} | ||
outputResults = append(outputResults, droneBuildResult) | ||
return true, outputResults | ||
} | ||
|
||
return false, outputResults | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package javascript | ||
|
||
import "golang.org/x/exp/slices" | ||
|
||
type Option func(*scannerConfig) | ||
|
||
func WithChecksToRun(i []string) Option { | ||
return func(p *scannerConfig) { | ||
if len(i) > 0 { | ||
validChecks := []string{} | ||
// only add valid checks | ||
for _, check := range i { | ||
if slices.Contains(p.AvailableChecks(), check) { | ||
validChecks = append(validChecks, check) | ||
} | ||
} | ||
p.runAll = false | ||
p.checksToRun = validChecks | ||
} else { | ||
p.runAll = true | ||
} | ||
} | ||
} | ||
|
||
func WithWorkingDirectory(i string) Option { | ||
return func(p *scannerConfig) { | ||
p.workingDirectory = i | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters