Skip to content

Commit

Permalink
Merge pull request #8 from yskopets/feature/support-licenserignore-files
Browse files Browse the repository at this point in the history
  • Loading branch information
liamawhite committed Apr 28, 2020
2 parents f3723da + f825fda commit d2d5934
Show file tree
Hide file tree
Showing 17 changed files with 169 additions and 12 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ Licenser will also automatically ignore the following files:

- *.md, *.golden
- .gitignore
- Anything matched by the top level .gitignore (experimental)
- Files that should be ignored according to .gitignore (experimental)
- .licenserignore
- Files that should be ignored according to .licenserignore (experimental)

## Install

Expand Down
5 changes: 4 additions & 1 deletion ci/lint
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#!/bin/bash

BASEDIR=$(dirname "$0")
LICENSER="go run ${BASEDIR}/../main.go"

SUCCESS=true

# Ensure Licenses are present
if licenser verify -r .; then
if ${LICENSER} verify -r .; then
echo "Licenses are present on all recognised files."
else
echo "Licenses are missing."
Expand Down
4 changes: 3 additions & 1 deletion pkg/command/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ var verifyCmd = &cobra.Command{
Verify will ignore the following files:
- *.md, *.golden
- .gitignore
- Anything matched by the top level .gitignore (experimental)
- Files that should be ignored according to .gitignore (experimental)
- .licenserignore
- Files that should be ignored according to .licenserignore (experimental)
`,
Run: func(cmd *cobra.Command, args []string) {
license := license.NewApache20(time.Now().Year(), "")
Expand Down
47 changes: 38 additions & 9 deletions pkg/processor/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ import (
"github.com/liamawhite/licenser/pkg/license"
)

// licenserignoreFile is a name for *ignore files specific to licenser.
const licenserignoreFile = ".licenserignore"

// Processor finds all valid files and passes them to a file mutator to be handled
type Processor struct {
startDirectory string
Expand All @@ -38,18 +41,20 @@ type Processor struct {
dryRun bool
success bool

skipListGitIgnore gitignore.GitIgnore
skipListExtension map[string]bool
skipListGitIgnore gitignore.GitIgnore
skipListLicenserIgnore gitignore.GitIgnore
skipListExtension map[string]bool
}

// New creates a new file processor starting the the passed startDirectory
// and using the passed license to apply and verify files
func New(startDirectory string, license license.Handler) *Processor {
return &Processor{
startDirectory: startDirectory,
mutator: mutator.New(license),
skipListGitIgnore: buildGitIgnoreSkip(startDirectory),
skipListExtension: buildExtensionSkip(),
startDirectory: startDirectory,
mutator: mutator.New(license),
skipListGitIgnore: buildGitIgnoreSkip(startDirectory),
skipListLicenserIgnore: buildLicenserIgnoreSkip(startDirectory),
skipListExtension: buildExtensionSkip(),
}
}

Expand Down Expand Up @@ -111,17 +116,32 @@ func (p *Processor) visit(path string, f os.FileInfo, err error) error {
}

func (p *Processor) shouldSkip(path string) bool {
// skip predefined file types
if _, ok := p.skipListExtension[filepath.Ext(path)]; ok {
return true
}
// skip .git/**, .gitignore, .gitattributes, etc
if strings.Contains(path, ".git") {
return true
}
f, err := os.Stat(path)
if err != nil {
// don't skip start dir (it cannot be ignored by *ignore files anyway,
// and `go-gitignore` library crashes on this use case)
if path == p.startDirectory {
return false
}
return p.skipListGitIgnore.Relative(path, f.IsDir()) != nil
// skip according to .gitignore
if match := p.skipListGitIgnore.Match(path); match != nil && match.Ignore() {
return true
}
// skip .licenserignore
if filepath.Base(path) == licenserignoreFile {
return true
}
// skip according to .licenserignore
if match := p.skipListLicenserIgnore.Match(path); match != nil && match.Ignore() {
return true
}
return false
}

func buildGitIgnoreSkip(startDirectory string) gitignore.GitIgnore {
Expand All @@ -131,6 +151,15 @@ func buildGitIgnoreSkip(startDirectory string) gitignore.GitIgnore {
}
return gitignore
}

func buildLicenserIgnoreSkip(startDirectory string) gitignore.GitIgnore {
ignore, err := gitignore.NewRepositoryWithFile(startDirectory, licenserignoreFile)
if err != nil {
fmt.Fprintf(os.Stderr, "error reading contents of %s:%v\n", licenserignoreFile, err)
}
return ignore
}

func buildExtensionSkip() map[string]bool {
return map[string]bool{
".md": true,
Expand Down
61 changes: 61 additions & 0 deletions pkg/processor/processor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2020 Tetrate
//
// 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 processor

import (
"fmt"
"path/filepath"
"testing"

"github.com/liamawhite/licenser/pkg/license"

"github.com/stretchr/testify/assert"
)

func Test_shouldSkip(t *testing.T) {
tests := []struct {
path string
want bool
}{
// never ignore root dir
{".", false},

// ignore *ignore files themselves
{".gitignore", true},
{".gitattributes", true},
{".licenserignore", true},

// ignore according to .licenserignore files
{"licenserignore/ignore.yaml", true},
{"licenserignore/include.yaml", false},
{"licenserignore/nested/ignore.yaml", true},
{"licenserignore/nested/include.yaml", false},

// ignore according to .gitignore files
{"gitignore/ignore.yaml", true},
{"gitignore/include.yaml", false},
{"gitignore/nested/ignore.yaml", true},
{"gitignore/nested/include.yaml", false},
}
processor := New("testdata", license.NewApache20(2020, "ASF"))
for _, tt := range tests {
tc := tt
name := fmt.Sprintf("shouldSkip %s is %t", tc.path, tc.want)
t.Run(name, func(t *testing.T) {
path := filepath.Clean(filepath.Join("testdata", tc.path))
assert.Equal(t, tc.want, processor.shouldSkip(path))
})
}
}
2 changes: 2 additions & 0 deletions pkg/processor/testdata/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/gitignore/*.yaml
!/gitignore/include.yaml
2 changes: 2 additions & 0 deletions pkg/processor/testdata/.licenserignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/licenserignore/*.yaml
!/licenserignore/include.yaml
2 changes: 2 additions & 0 deletions pkg/processor/testdata/gitignore/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/nested/*.yaml
!/nested/include.yaml
Empty file.
13 changes: 13 additions & 0 deletions pkg/processor/testdata/gitignore/include.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2020 Tetrate
#
# 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.
Empty file.
13 changes: 13 additions & 0 deletions pkg/processor/testdata/gitignore/nested/include.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2020 Tetrate
#
# 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.
2 changes: 2 additions & 0 deletions pkg/processor/testdata/licenserignore/.licenserignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/nested/*.yaml
!/nested/include.yaml
Empty file.
13 changes: 13 additions & 0 deletions pkg/processor/testdata/licenserignore/include.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2020 Tetrate
#
# 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.
Empty file.
13 changes: 13 additions & 0 deletions pkg/processor/testdata/licenserignore/nested/include.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2020 Tetrate
#
# 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.

0 comments on commit d2d5934

Please sign in to comment.