This is an automated email from the ASF dual-hosted git repository. wusheng pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/skywalking-swck.git
commit 43dd88229010e1c43d03105bcdaf8aa746d9bf19 Author: Gao Hongtao <hanahm...@gmail.com> AuthorDate: Tue Nov 3 12:23:01 2020 +0800 Add license checker Signed-off-by: Gao Hongtao <hanahm...@gmail.com> --- Makefile | 7 +- cmd/build/main.go | 66 ++++++++ .../operator.skywalking.apache.org_oapservers.yaml | 18 +++ config/crd/kustomization.yaml | 17 +++ config/crd/kustomizeconfig.yaml | 17 +++ config/crd/patches/cainjection_in_oapservers.yaml | 17 +++ config/crd/patches/webhook_in_oapservers.yaml | 17 +++ config/manager/manager.yaml | 17 +++ config/rbac/auth_proxy_service.yaml | 17 +++ config/rbac/role.yaml | 18 +++ config/samples/oap.yaml | 17 +++ config/webhook/manifests.yaml | 0 go.mod | 2 + go.sum | 4 + pkg/build/license.go | 168 +++++++++++++++++++++ 15 files changed, 400 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f535565..4f12258 100644 --- a/Makefile +++ b/Makefile @@ -45,16 +45,19 @@ deploy: manifests # Generate manifests e.g. CRD, RBAC etc. manifests: controller-gen $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases + go run github.com/skywalking-swck/cmd/build license insert config # Generate code generate: controller-gen $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." + $(MAKE) format GO_LICENSER := $(GOBIN)/go-licenser $(GO_LICENSER): GO111MODULE=off go get -u github.com/elastic/go-licenser -license: clean $(GO_LICENSER) +license: $(GO_LICENSER) $(GO_LICENSER) -d -licensor='Apache Software Foundation (ASF)' -exclude=api/v1alpha1/zz_generated* . + go run github.com/skywalking-swck/cmd/build license check config # Build the docker image docker-build: test @@ -91,7 +94,7 @@ format: ## Format all Go code @goimports -w -local github.com/skywalking-swck . ## Check that the status is consistent with CI. -check: clean generate manifests +check: generate manifests license $(MAKE) format mkdir -p /tmp/artifacts git diff >/tmp/artifacts/check.diff 2>&1 diff --git a/cmd/build/main.go b/cmd/build/main.go new file mode 100644 index 0000000..c507149 --- /dev/null +++ b/cmd/build/main.go @@ -0,0 +1,66 @@ +// Licensed to 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. Apache Software Foundation (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 main + +import ( + "io" + "os" + + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + + "github.com/skywalking-swck/pkg/build" +) + +const ( + cliName = "swck-build-tool" +) + +func main() { + //The verbose flag value + var v string + cmd := &cobra.Command{ + Short: cliName, + Long: "SWCK build tool chain", + SilenceUsage: true, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + if err := setUpLogs(os.Stdout, v); err != nil { + return err + } + return nil + }, + } + cmd.PersistentFlags().StringVarP(&v, "verbosity", "v", logrus.InfoLevel.String(), "Log level (debug, info, warn, error, fatal, panic") + cmd.Use = cliName + cmd.AddCommand(build.NewLicense()) + + if err := cmd.Execute(); err != nil { + os.Exit(1) + } +} + +//setUpLogs set the log output ans the log level +func setUpLogs(out io.Writer, level string) error { + logrus.SetOutput(out) + lvl, err := logrus.ParseLevel(level) + if err != nil { + return err + } + logrus.SetLevel(lvl) + return nil +} diff --git a/config/crd/bases/operator.skywalking.apache.org_oapservers.yaml b/config/crd/bases/operator.skywalking.apache.org_oapservers.yaml index 72a5d6a..4da30d2 100644 --- a/config/crd/bases/operator.skywalking.apache.org_oapservers.yaml +++ b/config/crd/bases/operator.skywalking.apache.org_oapservers.yaml @@ -1,3 +1,20 @@ +# Licensed to 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. Apache Software Foundation (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. + --- apiVersion: apiextensions.k8s.io/v1beta1 @@ -233,3 +250,4 @@ status: plural: "" conditions: [] storedVersions: [] + diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index b391b8e..92c181a 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -1,3 +1,20 @@ +# Licensed to 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. Apache Software Foundation (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. + # This kustomization.yaml is not intended to be run by itself, # since it depends on service name and namespace that are out of this kustomize package. # It should be run by config/default diff --git a/config/crd/kustomizeconfig.yaml b/config/crd/kustomizeconfig.yaml index 6f83d9a..a9ec1ed 100644 --- a/config/crd/kustomizeconfig.yaml +++ b/config/crd/kustomizeconfig.yaml @@ -1,3 +1,20 @@ +# Licensed to 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. Apache Software Foundation (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. + # This file is for teaching kustomize how to substitute name and namespace reference in CRD nameReference: - kind: Service diff --git a/config/crd/patches/cainjection_in_oapservers.yaml b/config/crd/patches/cainjection_in_oapservers.yaml index 17e24cf..6f20cba 100644 --- a/config/crd/patches/cainjection_in_oapservers.yaml +++ b/config/crd/patches/cainjection_in_oapservers.yaml @@ -1,3 +1,20 @@ +# Licensed to 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. Apache Software Foundation (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. + # The following patch adds a directive for certmanager to inject CA into the CRD # CRD conversion requires k8s 1.13 or later. apiVersion: apiextensions.k8s.io/v1beta1 diff --git a/config/crd/patches/webhook_in_oapservers.yaml b/config/crd/patches/webhook_in_oapservers.yaml index b1846c1..ff6b69d 100644 --- a/config/crd/patches/webhook_in_oapservers.yaml +++ b/config/crd/patches/webhook_in_oapservers.yaml @@ -1,3 +1,20 @@ +# Licensed to 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. Apache Software Foundation (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. + # The following patch enables conversion webhook for CRD # CRD conversion requires k8s 1.13 or later. apiVersion: apiextensions.k8s.io/v1beta1 diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index b6c85a5..2eb0b50 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -1,3 +1,20 @@ +# Licensed to 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. Apache Software Foundation (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. + apiVersion: v1 kind: Namespace metadata: diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/auth_proxy_service.yaml index 6cf656b..004cea6 100644 --- a/config/rbac/auth_proxy_service.yaml +++ b/config/rbac/auth_proxy_service.yaml @@ -1,3 +1,20 @@ +# Licensed to 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. Apache Software Foundation (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. + apiVersion: v1 kind: Service metadata: diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 491934b..bde338f 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -1,3 +1,20 @@ +# Licensed to 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. Apache Software Foundation (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. + --- apiVersion: rbac.authorization.k8s.io/v1 @@ -38,3 +55,4 @@ rules: - get - patch - update + diff --git a/config/samples/oap.yaml b/config/samples/oap.yaml index 8afe021..f965e63 100644 --- a/config/samples/oap.yaml +++ b/config/samples/oap.yaml @@ -1,3 +1,20 @@ +# Licensed to 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. Apache Software Foundation (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. + apiVersion: operator.skywalking.apache.org/v1alpha1 kind: OAPServer metadata: diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/go.mod b/go.mod index eee19ae..3103591 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,8 @@ require ( github.com/go-logr/logr v0.1.0 github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.8.1 + github.com/sirupsen/logrus v1.4.2 + github.com/spf13/cobra v0.0.5 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect k8s.io/api v0.17.2 k8s.io/apimachinery v0.17.2 diff --git a/go.sum b/go.sum index 927fb70..7dca6c7 100644 --- a/go.sum +++ b/go.sum @@ -167,6 +167,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -180,6 +181,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +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/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -250,12 +252,14 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= diff --git a/pkg/build/license.go b/pkg/build/license.go new file mode 100644 index 0000000..fd17c7e --- /dev/null +++ b/pkg/build/license.go @@ -0,0 +1,168 @@ +// Licensed to 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. Apache Software Foundation (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 build + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + l "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +const yamlHeader = `# Licensed to 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. Apache Software Foundation (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. + +` + +func NewLicense() *cobra.Command { + cmd := &cobra.Command{ + Use: "license", + Short: "Apply license header to generated manifests", + } + cmd.AddCommand(newInsert()) + cmd.AddCommand(newCheck()) + return cmd +} + +func newInsert() *cobra.Command { + cmd := &cobra.Command{ + Use: "insert", + Short: "Insert license header to generated manifests", + RunE: func(cmd *cobra.Command, args []string) (err error) { + if len(args) < 1 || args[0] == "" { + return fmt.Errorf("lack the path in args") + } + dir, err := os.Getwd() + if err != nil { + return fmt.Errorf("failed to get present directory: %w", err) + } + w := filepath.Join(dir, args[0]) + l.Info("working directory: %s", w) + + err = filepath.Walk(w, + func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + l.Debugf("path: %s", path) + if info.IsDir() { + return nil + } + insertHeader(path) + return nil + }) + if err != nil { + return fmt.Errorf("failed to process files: %w", err) + } + return nil + }, + } + return cmd +} + +func newCheck() *cobra.Command { + + cmd := &cobra.Command{ + Use: "check", + Short: "Check yaml files licenses", + RunE: func(cmd *cobra.Command, args []string) (err error) { + if len(args) < 1 || args[0] == "" { + return fmt.Errorf("lack the path in args") + } + dir, err := os.Getwd() + if err != nil { + return fmt.Errorf("failed to get present directory: %w", err) + } + w := filepath.Join(dir, args[0]) + l.Info("working directory: %s", w) + + err = filepath.Walk(w, + func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + l.Debugf("path: %s", path) + if info.IsDir() { + return nil + } + data, err := ioutil.ReadFile(path) + if err != nil { + l.Errorf("failed to read data from file ", path, err) + } + if checkHeader(data) { + return nil + } + return fmt.Errorf("failed to check %s", path) + }) + if err != nil { + return fmt.Errorf("failed to process files: %w", err) + } + return nil + }, + } + return cmd +} + +func insertHeader(path string) { + l.Debugf("============Processing file %s================", path) + var buff bytes.Buffer + data, err := ioutil.ReadFile(path) + if err != nil { + l.Errorf("failed to read data from file ", path, err) + } + if checkHeader(data) { + return + } + + if _, err = buff.WriteString(yamlHeader); err != nil { + l.Errorf("failed to write header to %s", path, err) + } + if _, err = buff.Write(append(data, '\n')); err != nil { + l.Errorf("failed to write content to %s", path, err) + } + if err = ioutil.WriteFile(path, buff.Bytes(), os.ModePerm); err != nil { + l.Errorf("failed to update %s", path, err) + } + l.Info("updated %s", path) +} + +func checkHeader(data []byte) bool { + if strings.Index(string(data), "Apache Software Foundation (ASF)") > -1 { + return true + } + return false +}