This is an automated email from the ASF dual-hosted git repository. kezhenxu94 pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/skywalking-eyes.git
commit 80e525a476f8d9bee9fe8ed039d8d20b2b2f944b Author: Hoshea <[email protected]> AuthorDate: Sat Nov 21 22:44:42 2020 +0800 dev --- .licenserc.json | 48 ++++++++++++++++++++ Makefile | 69 +++++++++++++++++++++++++++++ cmd/root.go | 116 ++++++++++++++++++++++++++++++++++--------------- config.json | 19 -------- config.yaml | 3 -- main.go | 2 +- test/testcase.go | 18 ++++++++ test/testcase.java | 14 ++++++ test/testcase.md | 0 test/testcase3.py | 16 +++++++ main.go => util/str.go | 31 ++++++++++--- util/str_test.go | 58 +++++++++++++++++++++++++ 12 files changed, 331 insertions(+), 63 deletions(-) diff --git a/.licenserc.json b/.licenserc.json new file mode 100644 index 0000000..3d262cc --- /dev/null +++ b/.licenserc.json @@ -0,0 +1,48 @@ +{ + "licenseStrict": [ + "Licensed to the Apache Software Foundation (ASF) under one or more", + "contributor license agreements. See the NOTICE file distributed with", + "this work for additional information regarding copyright ownership.", + "The ASF licenses this file to You under the Apache License, Version 2.0", + "(the \"License\"); you may not use this file except in compliance with", + "the License. You may obtain a copy of the License at", + "http://www.apache.org/licenses/LICENSE-2.0", + "Unless required by applicable law or agreed to in writing, software", + "distributed under the License is distributed on an \"AS IS\" BASIS,", + "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", + "See the License for the specific language governing permissions and", + "limitations under the License." + ], + "licenseLoose": [ + "Apache License", + "Version 2.0" + ], + "targetFiles": [ + "java", + "go", + "py", + "sh", + "graphql", + "yaml", + "yml" + ], + "exclude": { + "files": [ + ".gitignore", + "NOTICE", + "go.mod", + "go.sum" + ], + "extensions": [ + "md", + "xml", + "json" + ], + "directories": [ + "bin", + ".github", + ".git", + ".idea" + ] + } +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4e83903 --- /dev/null +++ b/Makefile @@ -0,0 +1,69 @@ +# Copyright © 2020 Hoshea Jiang <[email protected]> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +PROJECT = license-checker +VERSION ?= latest +OUT_DIR = bin +CURDIR := $(shell pwd) +FILES := $$(find .$$($(PACKAGE_DIRECTORIES)) -name "*.go") +FAIL_ON_STDOUT := awk '{ print } END { if (NR > 0) { exit 1 } }' + +GO := GO111MODULE=on go +GO_PATH = $$($(GO) env GOPATH) +GO_BUILD = $(GO) build +GO_GET = $(GO) get +GO_TEST = $(GO) test +GO_LINT = $(GO_PATH)/bin/golangci-lint +GO_LICENSER = $(GO_PATH)/bin/go-licenser + +# Ensure GOPATH is set before running build process. +ifeq "$(GOPATH)" "" + $(error Please set the environment variable GOPATH before running `make`) +endif + +all: clean deps lint test build + +tools: + mkdir -p $(GO_PATH)/bin + $(GO_LINT) version || curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GO_PATH)/bin v1.21.0 + $(GO_LICENSER) -version || GO111MODULE=off $(GO_GET) -u github.com/elastic/go-licenser + +deps: tools + $(GO_GET) -v -t -d ./... + +.PHONY: lint +lint: tools + @gofmt -s -l -w $(FILES) 2>&1 | $(FAIL_ON_STDOUT) + $(GO_LINT) run -v ./... + +.PHONE: test +test: clean lint + $(GO_TEST) ./... + @>&2 echo "Great, all tests passed." + +.PHONY: build +build: deps + $(GO_BUILD) -o $(OUT_DIR)/$(PROJECT) + +#.PHONY: license +#license: clean tools +# $(GO_LICENSER) -d -license='ASL2' . + +.PHONY: fix +fix: tools + $(GO_LINT) run -v --fix ./... + +.PHONY: clean +clean: tools + -rm -rf bin diff --git a/cmd/root.go b/cmd/root.go index 14c62b6..841fa46 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,5 +1,5 @@ /* -Copyright © 2020 NAME HERE <EMAIL ADDRESS> +Copyright © 2020 Hoshea Jiang <[email protected]> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,23 +16,33 @@ limitations under the License. package cmd import ( + "encoding/json" "fmt" "github.com/spf13/cobra" + "io/ioutil" + "license-checker/util" "os" - - homedir "github.com/mitchellh/go-homedir" - "github.com/spf13/viper" + "path/filepath" ) var cfgFile string +var checkPath string +var loose bool // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ - Use: "license-checker", - Short: "A brief description of your application", - + Use: "license-checker [flags]", + Long: `license-checker walks the specified path recursively and checks +if the specified files have the license header in the config file.`, Run: func(cmd *cobra.Command, args []string) { - fmt.Println("Hello Cobra CLI!") + config, err := LoadConfig() + if err != nil { + fmt.Println(err) + } + //fmt.Println(config.TargetFiles) + if err := Walk(checkPath, config); err != nil { + fmt.Println(err) + } }, } @@ -46,41 +56,77 @@ func Execute() { } func init() { - cobra.OnInitialize(initConfig) + rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", ".licenserc.json", "the config file") + rootCmd.PersistentFlags().StringVarP(&checkPath, "path", "p", "", "the path to check (required)") + rootCmd.PersistentFlags().BoolVarP(&loose, "loose", "l", false, "loose mode") + if err := rootCmd.MarkPersistentFlagRequired("path"); err != nil { + fmt.Println(err) + } +} - // Here you will define your flags and configuration settings. - // Cobra supports persistent flags, which, if defined here, - // will be global for your application. +type excludeConfig struct { + Files []string `json:"files"` + Extensions []string `json:"extensions"` + Directories []string `json:"directories"` +} - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.license-checker.yaml)") +type Config struct { + LicenseStrict []string `json:"licenseStrict"` + LicenseLoose []string `json:"licenseLoose"` + TargetFiles []string `json:"targetFiles"` + Exclude excludeConfig `json:"exclude"` +} - // Cobra also supports local flags, which will only run - // when this action is called directly. - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +type Result struct { + Success []string `json:"success"` + Failure []string `json:"failure"` } -// initConfig reads in config file and ENV variables if set. -func initConfig() { - if cfgFile != "" { - // Use config file from the flag. - viper.SetConfigFile(cfgFile) - } else { - // Find home directory. - home, err := homedir.Dir() +// LoadConfig reads in config file. +func LoadConfig() (*Config, error) { + var config Config + bytes, err := ioutil.ReadFile(cfgFile) + if err != nil { + return nil, err + } + + err = json.Unmarshal(bytes, &config) + if err != nil { + return nil, err + } + + return &config, nil +} + +func Walk(p string, cfg *Config) error { + inExcludeDir := util.InStrSliceMapKeyFunc(cfg.Exclude.Directories) + inExcludeExt := util.InStrSliceMapKeyFunc(cfg.Exclude.Extensions) + inExcludeFiles := util.InStrSliceMapKeyFunc(cfg.Exclude.Files) + + err := filepath.Walk(p, func(path string, fi os.FileInfo, err error) error { if err != nil { - fmt.Println(err) - os.Exit(1) + fmt.Println(err) // can't walk here, + return nil // but continue walking elsewhere } - // Search config in home directory with name ".license-checker" (without extension). - viper.AddConfigPath(home) - viper.SetConfigName(".license-checker") - } + if fi.IsDir() { + if inExcludeDir(fi.Name()) { + return filepath.SkipDir + } + } else { + ext := util.GetFileExtension(fi.Name()) + if inExcludeFiles(fi.Name()) || inExcludeExt(ext) { + return nil + } + + // TODO: open the file and check + fmt.Println(path) + //curDir := strings.Replace(path, fi.Name(), "", 1) + //fmt.Println(curDir) + } - viper.AutomaticEnv() // read in environment variables that match + return nil + }) - // If a config file is found, read it in. - if err := viper.ReadInConfig(); err == nil { - fmt.Println("Using config file:", viper.ConfigFileUsed()) - } + return err } diff --git a/config.json b/config.json deleted file mode 100644 index 10d2446..0000000 --- a/config.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "**/*.{java, go, py}": [ - "You can put multiline headers like this", - "Copyright Foo, Inc. and other Bar contributors.", - "Permission is hereby granted, free of charge, to any person obtaining a", - "copy of this software and associated documentation files (the", - "\"Software\"), to deal in the Software without restriction, including", - "without limitation the rights to use, copy, modify, merge, publish,", - "distribute, sublicense, and/or sell copies of the Software, and to permit", - "persons to whom the Software is furnished to do so, subject to the", - "following conditions:", - "..." - ], - - "ignore": [ - "lib/vendor/jquery.js", // ignore this file - "vendor/" // ignore all files under vendor - ] -} \ No newline at end of file diff --git a/config.yaml b/config.yaml deleted file mode 100644 index 4845d7a..0000000 --- a/config.yaml +++ /dev/null @@ -1,3 +0,0 @@ -include: - -exclude: \ No newline at end of file diff --git a/main.go b/main.go index d2e9d49..e9f9be6 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,5 @@ /* -Copyright © 2020 NAME HERE <EMAIL ADDRESS> +Copyright © 2020 Hoshea Jiang <[email protected]> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/test/testcase.go b/test/testcase.go new file mode 100644 index 0000000..4020ef8 --- /dev/null +++ b/test/testcase.go @@ -0,0 +1,18 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package test diff --git a/test/testcase.java b/test/testcase.java new file mode 100644 index 0000000..43a94f3 --- /dev/null +++ b/test/testcase.java @@ -0,0 +1,14 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +//limitations under the License. diff --git a/test/testcase.md b/test/testcase.md new file mode 100644 index 0000000..e69de29 diff --git a/test/testcase3.py b/test/testcase3.py new file mode 100644 index 0000000..a9fd83f --- /dev/null +++ b/test/testcase3.py @@ -0,0 +1,16 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/main.go b/util/str.go similarity index 53% copy from main.go copy to util/str.go index d2e9d49..b953e48 100644 --- a/main.go +++ b/util/str.go @@ -1,5 +1,5 @@ /* -Copyright © 2020 NAME HERE <EMAIL ADDRESS> +Copyright © 2020 Hoshea Jiang <[email protected]> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13,10 +13,31 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -package main +package util -import "license-checker/cmd" +import ( + "strings" +) -func main() { - cmd.Execute() +func InStrSliceMapKeyFunc(strs []string) func(string) bool { + set := make(map[string]struct{}) + + for _, e := range strs { + set[e] = struct{}{} + } + + return func(s string) bool { + _, ok := set[s] + return ok + } +} + +func GetFileExtension(filename string) string { + i := strings.LastIndex(filename, ".") + if i != -1 { + if i+1 < len(filename) { + return filename[i+1:] + } + } + return "" } diff --git a/util/str_test.go b/util/str_test.go new file mode 100644 index 0000000..fce8965 --- /dev/null +++ b/util/str_test.go @@ -0,0 +1,58 @@ +/* +Copyright © 2020 Hoshea Jiang <[email protected]> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package util + +import "testing" + +func TestGetFileExtension(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "txt extension", + args: args{ + filename: ".abc.txt", + }, + want: "txt", + }, + { + name: "no file extensions", + args: args{ + filename: ".abc.txt.", + }, + want: "", + }, + { + name: "no file extensions", + args: args{ + filename: "lkjsdl", + }, + want: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := GetFileExtension(tt.args.filename); got != tt.want { + t.Errorf("GetFileExtension() = %v, want %v", got, tt.want) + } + }) + } +}
