-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: expose manifest reading and jsonwall as packages #182
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
6c1eee1
chore: move jsonwall to a separate package
letFunny a3a2b5f
chore: move manifest reading to a separate package
letFunny 73afcec
move to pkg subdirectory
letFunny dcecefa
add spdx license
letFunny 99ae181
rename internal package to avoid clashing
letFunny d3f01c5
create new internal package with Apache-2.0 license
letFunny 8939653
omit spdx header from godoc
letFunny 885837d
license ci checker
letFunny b7f5958
Merge branch 'main' into move-jsonwall-manifest
letFunny 6aa9aec
correct CI
letFunny ce5bdcb
test test dependencies
letFunny 06f1427
ci: license now treats empty license as error
letFunny 542a4a1
better message
letFunny 34f1552
rewrote license checker in Go
letFunny d0e3078
isolate Apache-2.0 code
letFunny 3fe73cb
small fixes to script
letFunny 305c014
change package names to apache
letFunny a27d92c
SliceKey moved to setup under type alias
letFunny ff5c993
re-export ParseSetupKey as well
letFunny cc693e0
move SetupKey down in the file
letFunny 44040b3
pkg -> public
letFunny 5abdffa
move manifest.Validate to internal
letFunny b9ebd1d
s/SetupKey/SliceKey/g
letFunny File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"io/fs" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
var licenseRegexp = regexp.MustCompile("// SPDX-License-Identifier: ([^\\s]*)$") | ||
|
||
func fileLicense(path string) (string, error) { | ||
file, err := os.Open(path) | ||
if err != nil { | ||
return "", err | ||
} | ||
defer file.Close() | ||
scanner := bufio.NewScanner(file) | ||
|
||
for scanner.Scan() { | ||
line := scanner.Text() | ||
matches := licenseRegexp.FindStringSubmatch(line) | ||
if len(matches) > 0 { | ||
return matches[1], nil | ||
} | ||
} | ||
|
||
return "", nil | ||
} | ||
|
||
func checkDirLicense(path string, valid string) error { | ||
return filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error { | ||
if !strings.HasSuffix(path, ".go") { | ||
return nil | ||
} | ||
license, err := fileLicense(path) | ||
if err != nil { | ||
return err | ||
} | ||
if license == "" { | ||
return fmt.Errorf("cannot find a valid license in %q", path) | ||
} | ||
if license != valid { | ||
return fmt.Errorf("expected %q to be %q, got %q", path, valid, license) | ||
} | ||
return nil | ||
}) | ||
} | ||
|
||
func run() error { | ||
// Check external packages licenses. | ||
err := checkDirLicense("public", "Apache-2.0") | ||
if err != nil { | ||
return fmt.Errorf("invalid license in exported package: %s", err) | ||
} | ||
|
||
// Check the internal dependencies of the external packages. | ||
output, err := exec.Command("sh", "-c", "go list -deps -test ./public/*").Output() | ||
if err != nil { | ||
return err | ||
} | ||
lines := strings.Split(string(output), "\n") | ||
var internalPkgs []string | ||
for _, line := range lines { | ||
if strings.Contains(line, "github.com/canonical/chisel/internal") { | ||
internalPkgs = append(internalPkgs, strings.TrimPrefix(line, "github.com/canonical/chisel/")) | ||
} | ||
} | ||
for _, pkg := range internalPkgs { | ||
err := checkDirLicense(pkg, "Apache-2.0") | ||
if err != nil { | ||
return fmt.Errorf("invalid license in depedency %q: %s", pkg, err) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func main() { | ||
err := run() | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "%s\n", err) | ||
os.Exit(1) | ||
} | ||
} |
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,22 @@ | ||
name: License check | ||
|
||
on: | ||
workflow_dispatch: | ||
push: | ||
pull_request: | ||
branches: [main] | ||
|
||
jobs: | ||
external-packages: | ||
runs-on: ubuntu-22.04 | ||
name: External packages license check | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- uses: actions/setup-go@v3 | ||
with: | ||
go-version-file: 'go.mod' | ||
|
||
- name: Run license check | ||
run: | | ||
go run .github/scripts/external-packages-license-check.go |
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,54 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package apachetestutil | ||
|
||
import ( | ||
"gopkg.in/check.v1" | ||
|
||
"github.com/canonical/chisel/public/manifest" | ||
) | ||
|
||
type ManifestContents struct { | ||
Paths []*manifest.Path | ||
Packages []*manifest.Package | ||
Slices []*manifest.Slice | ||
Contents []*manifest.Content | ||
} | ||
|
||
func DumpManifestContents(c *check.C, mfest *manifest.Manifest) *ManifestContents { | ||
var slices []*manifest.Slice | ||
err := mfest.IterateSlices("", func(slice *manifest.Slice) error { | ||
slices = append(slices, slice) | ||
return nil | ||
}) | ||
c.Assert(err, check.IsNil) | ||
|
||
var pkgs []*manifest.Package | ||
err = mfest.IteratePackages(func(pkg *manifest.Package) error { | ||
pkgs = append(pkgs, pkg) | ||
return nil | ||
}) | ||
c.Assert(err, check.IsNil) | ||
|
||
var paths []*manifest.Path | ||
err = mfest.IteratePaths("", func(path *manifest.Path) error { | ||
paths = append(paths, path) | ||
return nil | ||
}) | ||
c.Assert(err, check.IsNil) | ||
|
||
var contents []*manifest.Content | ||
err = mfest.IterateContents("", func(content *manifest.Content) error { | ||
contents = append(contents, content) | ||
return nil | ||
}) | ||
c.Assert(err, check.IsNil) | ||
|
||
mc := ManifestContents{ | ||
Paths: paths, | ||
Packages: pkgs, | ||
Slices: slices, | ||
Contents: contents, | ||
} | ||
return &mc | ||
} |
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,55 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package apacheutil | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
) | ||
|
||
// Avoid importing the log type information unnecessarily. There's a small cost | ||
// associated with using an interface rather than the type. Depending on how | ||
// often the logger is plugged in, it would be worth using the type instead. | ||
type log_Logger interface { | ||
Output(calldepth int, s string) error | ||
} | ||
|
||
var globalLoggerLock sync.Mutex | ||
var globalLogger log_Logger | ||
var globalDebug bool | ||
|
||
// Specify the *log.Logger object where log messages should be sent to. | ||
func SetLogger(logger log_Logger) { | ||
globalLoggerLock.Lock() | ||
globalLogger = logger | ||
globalLoggerLock.Unlock() | ||
} | ||
|
||
// Enable the delivery of debug messages to the logger. Only meaningful | ||
// if a logger is also set. | ||
func SetDebug(debug bool) { | ||
globalLoggerLock.Lock() | ||
globalDebug = debug | ||
globalLoggerLock.Unlock() | ||
} | ||
|
||
// logf sends to the logger registered via SetLogger the string resulting | ||
// from running format and args through Sprintf. | ||
func logf(format string, args ...interface{}) { | ||
globalLoggerLock.Lock() | ||
defer globalLoggerLock.Unlock() | ||
if globalLogger != nil { | ||
globalLogger.Output(2, fmt.Sprintf(format, args...)) | ||
} | ||
} | ||
|
||
// debugf sends to the logger registered via SetLogger the string resulting | ||
// from running format and args through Sprintf, but only if debugging was | ||
// enabled via SetDebug. | ||
func debugf(format string, args ...interface{}) { | ||
globalLoggerLock.Lock() | ||
defer globalLoggerLock.Unlock() | ||
if globalDebug && globalLogger != nil { | ||
globalLogger.Output(2, fmt.Sprintf(format, args...)) | ||
} | ||
} |
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,27 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package apacheutil_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "gopkg.in/check.v1" | ||
|
||
"github.com/canonical/chisel/internal/apacheutil" | ||
) | ||
|
||
func Test(t *testing.T) { TestingT(t) } | ||
|
||
type S struct{} | ||
|
||
var _ = Suite(&S{}) | ||
|
||
func (s *S) SetUpTest(c *C) { | ||
apacheutil.SetDebug(true) | ||
apacheutil.SetLogger(c) | ||
} | ||
|
||
func (s *S) TearDownTest(c *C) { | ||
apacheutil.SetDebug(false) | ||
apacheutil.SetLogger(nil) | ||
} |
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,32 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package apacheutil | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
) | ||
|
||
type SliceKey struct { | ||
Package string | ||
Slice string | ||
} | ||
|
||
func (s SliceKey) String() string { return s.Package + "_" + s.Slice } | ||
|
||
// FnameExp matches the slice definition file basename. | ||
var FnameExp = regexp.MustCompile(`^([a-z0-9](?:-?[.a-z0-9+]){1,})\.yaml$`) | ||
|
||
// SnameExp matches only the slice name, without the leading package name. | ||
var SnameExp = regexp.MustCompile(`^([a-z](?:-?[a-z0-9]){2,})$`) | ||
|
||
// knameExp matches the slice full name in pkg_slice format. | ||
var knameExp = regexp.MustCompile(`^([a-z0-9](?:-?[.a-z0-9+]){1,})_([a-z](?:-?[a-z0-9]){2,})$`) | ||
|
||
func ParseSliceKey(sliceKey string) (SliceKey, error) { | ||
match := knameExp.FindStringSubmatch(sliceKey) | ||
if match == nil { | ||
return SliceKey{}, fmt.Errorf("invalid slice reference: %q", sliceKey) | ||
} | ||
return SliceKey{match[1], match[2]}, nil | ||
} |
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,96 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package apacheutil_test | ||
|
||
import ( | ||
. "gopkg.in/check.v1" | ||
|
||
"github.com/canonical/chisel/internal/apacheutil" | ||
) | ||
|
||
var sliceKeyTests = []struct { | ||
input string | ||
expected apacheutil.SliceKey | ||
err string | ||
}{{ | ||
input: "foo_bar", | ||
expected: apacheutil.SliceKey{Package: "foo", Slice: "bar"}, | ||
}, { | ||
input: "fo_bar", | ||
expected: apacheutil.SliceKey{Package: "fo", Slice: "bar"}, | ||
}, { | ||
input: "1234_bar", | ||
expected: apacheutil.SliceKey{Package: "1234", Slice: "bar"}, | ||
}, { | ||
input: "foo1.1-2-3_bar", | ||
expected: apacheutil.SliceKey{Package: "foo1.1-2-3", Slice: "bar"}, | ||
}, { | ||
input: "foo-pkg_dashed-slice-name", | ||
expected: apacheutil.SliceKey{Package: "foo-pkg", Slice: "dashed-slice-name"}, | ||
}, { | ||
input: "foo+_bar", | ||
expected: apacheutil.SliceKey{Package: "foo+", Slice: "bar"}, | ||
}, { | ||
input: "foo_slice123", | ||
expected: apacheutil.SliceKey{Package: "foo", Slice: "slice123"}, | ||
}, { | ||
input: "g++_bins", | ||
expected: apacheutil.SliceKey{Package: "g++", Slice: "bins"}, | ||
}, { | ||
input: "a+_bar", | ||
expected: apacheutil.SliceKey{Package: "a+", Slice: "bar"}, | ||
}, { | ||
input: "a._bar", | ||
expected: apacheutil.SliceKey{Package: "a.", Slice: "bar"}, | ||
}, { | ||
input: "foo_ba", | ||
err: `invalid slice reference: "foo_ba"`, | ||
}, { | ||
input: "f_bar", | ||
err: `invalid slice reference: "f_bar"`, | ||
}, { | ||
input: "1234_789", | ||
err: `invalid slice reference: "1234_789"`, | ||
}, { | ||
input: "foo_bar.x.y", | ||
err: `invalid slice reference: "foo_bar.x.y"`, | ||
}, { | ||
input: "foo-_-bar", | ||
err: `invalid slice reference: "foo-_-bar"`, | ||
}, { | ||
input: "foo_bar-", | ||
err: `invalid slice reference: "foo_bar-"`, | ||
}, { | ||
input: "foo-_bar", | ||
err: `invalid slice reference: "foo-_bar"`, | ||
}, { | ||
input: "-foo_bar", | ||
err: `invalid slice reference: "-foo_bar"`, | ||
}, { | ||
input: "foo_bar_baz", | ||
err: `invalid slice reference: "foo_bar_baz"`, | ||
}, { | ||
input: "a-_bar", | ||
err: `invalid slice reference: "a-_bar"`, | ||
}, { | ||
input: "+++_bar", | ||
err: `invalid slice reference: "\+\+\+_bar"`, | ||
}, { | ||
input: "..._bar", | ||
err: `invalid slice reference: "\.\.\._bar"`, | ||
}, { | ||
input: "white space_no-whitespace", | ||
err: `invalid slice reference: "white space_no-whitespace"`, | ||
}} | ||
|
||
func (s *S) TestParseSliceKey(c *C) { | ||
for _, test := range sliceKeyTests { | ||
key, err := apacheutil.ParseSliceKey(test.input) | ||
if test.err != "" { | ||
c.Assert(err, ErrorMatches, test.err) | ||
continue | ||
} | ||
c.Assert(err, IsNil) | ||
c.Assert(key, DeepEquals, test.expected) | ||
} | ||
} |
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,4 +1,4 @@ | ||
package jsonwall | ||
package manifestutil | ||
|
||
import ( | ||
"fmt" | ||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Comment for reviewer]: This script for the CI is the only new code, the rest is all moved.