Jordan Liggitt has uploaded this change for review.
zip: fix LICENSE file handling to match modfetch
go modfetch includes the LICENSE file from the repo root when fetching a submodule
if the submodule does not contain a LICENSE. This updates CreateFromVCS to match
that behavior.
Fixes golang/go#60442
Change-Id: I5f9edb775bb330325783e1c30d7d16e436bda74c
---
M zip/zip.go
M zip/zip_test.go
2 files changed, 113 insertions(+), 8 deletions(-)
diff --git a/zip/zip.go b/zip/zip.go
index 7b48a2a..e2f2ff5 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -56,6 +56,7 @@
"path"
"path/filepath"
"strings"
+ "time"
"unicode"
"unicode/utf8"
@@ -653,6 +654,7 @@
return nil, err
}
+ haveLICENSE := false
var fs []File
for _, zf := range zipReader.File {
if !strings.HasPrefix(zf.Name, subdir) || strings.HasSuffix(zf.Name, "/") {
@@ -669,6 +671,25 @@
name: n,
f: zf,
})
+ if n == "LICENSE" {
+ haveLICENSE = true
+ }
+ }
+
+ if !haveLICENSE && subdir != "" {
+ // Note: this method of extracting the license from the root copied from
+ // https://go.googlesource.com/go/+/refs/tags/go1.20.4/src/cmd/go/internal/modfetch/coderepo.go#1118
+ // https://go.googlesource.com/go/+/refs/tags/go1.20.4/src/cmd/go/internal/modfetch/codehost/git.go#657
+ cmd := exec.Command("git", "cat-file", "blob", rev+":LICENSE")
+ cmd.Dir = dir
+ cmd.Env = append(os.Environ(), "PWD="+dir)
+ stderr := bytes.Buffer{}
+ stdout := bytes.Buffer{}
+ cmd.Stdout = &stdout
+ cmd.Stderr = &stderr
+ if err := cmd.Run(); err == nil {
+ fs = append(fs, dataFile{name: "LICENSE", data: stdout.Bytes()})
+ }
}
return fs, nil
@@ -710,6 +731,22 @@
func (f zipFile) Lstat() (os.FileInfo, error) { return f.f.FileInfo(), nil }
func (f zipFile) Open() (io.ReadCloser, error) { return f.f.Open() }
+type dataFile struct {
+ name string
+ info os.FileInfo
+ data []byte
+}
+
+func (f dataFile) Path() string { return f.name }
+func (f dataFile) Lstat() (os.FileInfo, error) { return f, nil }
+func (f dataFile) Open() (io.ReadCloser, error) { return io.NopCloser(bytes.NewReader(f.data)), nil }
+func (f dataFile) Name() string { return path.Base(f.name) }
+func (f dataFile) Size() int64 { return int64(len(f.data)) }
+func (f dataFile) Mode() os.FileMode { return os.FileMode(0) }
+func (f dataFile) ModTime() time.Time { return time.Time{} }
+func (f dataFile) IsDir() bool { return false }
+func (f dataFile) Sys() interface{} { return nil }
+
// isVendoredPackage attempts to report whether the given filename is contained
// in a package whose import path contains (but does not end with) the component
// "vendor".
diff --git a/zip/zip_test.go b/zip/zip_test.go
index 173cc65..8814ff8 100644
--- a/zip/zip_test.go
+++ b/zip/zip_test.go
@@ -1466,6 +1466,8 @@
module example.com/foo/bar
go 1.12
+-- LICENSE --
+root license
-- a.go --
package a
@@ -1482,6 +1484,20 @@
package c
var D = 5
+-- e/LICENSE --
+e license
+-- e/e.go --
+package e
+
+var E = 5
+-- f/go.mod --
+module example.com/foo/bar/f
+
+go 1.12
+-- f/f.go --
+package f
+
+var F = 5
-- .gitignore --
b.go
c/`)))
@@ -1494,31 +1510,60 @@
for _, tc := range []struct {
desc string
+ version module.Version
subdir string
wantFiles []string
+ wantData map[string]string
}{
{
desc: "from root",
+ version: module.Version{Path: "example.com/foo/bar", Version: "v0.0.1"},
subdir: "",
- wantFiles: []string{"go.mod", "a.go", "d/d.go", ".gitignore"},
+ wantFiles: []string{"go.mod", "LICENSE", "a.go", "d/d.go", "e/LICENSE", "e/e.go", ".gitignore"},
+ wantData: map[string]string{"LICENSE": "root license\n"},
},
{
- desc: "from subdir",
- subdir: "d/",
+ desc: "from subdir",
+ version: module.Version{Path: "example.com/foo/bar", Version: "v0.0.1"},
+ subdir: "d/",
// Note: File paths are zipped as if the subdir were the root. ie d.go instead of d/d.go.
- wantFiles: []string{"d.go"},
+ // subdirs without a license hoist the license from the root
+ wantFiles: []string{"d.go", "LICENSE"},
+ wantData: map[string]string{"LICENSE": "root license\n"},
+ },
+ {
+ desc: "from subdir with license",
+ version: module.Version{Path: "example.com/foo/bar", Version: "v0.0.1"},
+ subdir: "e/",
+ // Note: File paths are zipped as if the subdir were the root. ie e.go instead of e/e.go.
+ // subdirs with a license use their own
+ wantFiles: []string{"LICENSE", "e.go"},
+ wantData: map[string]string{"LICENSE": "e license\n"},
+ },
+ {
+ desc: "from submodule subdir",
+ version: module.Version{Path: "example.com/foo/bar/f", Version: "v0.0.1"},
+ subdir: "f/",
+ // Note: File paths are zipped as if the subdir were the root. ie f.go instead of f/f.go.
+ // subdirs without a license hoist the license from the root
+ wantFiles: []string{"go.mod", "f.go", "LICENSE"},
+ wantData: map[string]string{"LICENSE": "root license\n"},
},
} {
t.Run(tc.desc, func(t *testing.T) {
// Create zip from the directory.
tmpZip := &bytes.Buffer{}
- m := module.Version{Path: "example.com/foo/bar", Version: "v0.0.1"}
-
- if err := modzip.CreateFromVCS(tmpZip, m, tmpDir, "HEAD", tc.subdir); err != nil {
+ if err := modzip.CreateFromVCS(tmpZip, tc.version, tmpDir, "HEAD", tc.subdir); err != nil {
t.Fatal(err)
}
+ wantData := map[string]string{}
+ for f, data := range tc.wantData {
+ p := path.Join(tc.version.String(), f)
+ wantData[p] = data
+ }
+
readerAt := bytes.NewReader(tmpZip.Bytes())
r, err := zip.NewReader(readerAt, int64(tmpZip.Len()))
if err != nil {
@@ -1529,10 +1574,28 @@
for _, f := range r.File {
gotMap[f.Name] = true
gotFiles = append(gotFiles, f.Name)
+
+ if want, ok := wantData[f.Name]; ok {
+ r, err := f.Open()
+ if err != nil {
+ t.Errorf("CreatedFromVCS: error opening %s: %v", f.Name, err)
+ continue
+ }
+ defer r.Close()
+ got, err := io.ReadAll(r)
+ if err != nil {
+ t.Errorf("CreatedFromVCS: error reading %s: %v", f.Name, err)
+ continue
+ }
+ if want != string(got) {
+ t.Errorf("CreatedFromVCS: zipped file %s contains %s, expected %s", f.Name, string(got), want)
+ continue
+ }
+ }
}
wantMap := map[string]bool{}
for _, f := range tc.wantFiles {
- p := path.Join("example.com", "foo", "b...@v0.0.1", f)
+ p := path.Join(tc.version.String(), f)
wantMap[p] = true
}
@@ -1549,6 +1612,11 @@
t.Errorf("CreatedFromVCS: zipped file doesn't contain %s, but expected it to. all files: %v", f, gotFiles)
}
}
+ for f := range wantData {
+ if !gotMap[f] {
+ t.Errorf("CreatedFromVCS: zipped file doesn't contain %s, but expected it to. all files: %v", f, gotFiles)
+ }
+ }
})
}
}
To view, visit change 498935. To unsubscribe, or for help writing mail filters, visit settings.
Jordan Liggitt uploaded patch set #2 to this change.
zip: fix LICENSE file handling to match modfetch
go modfetch includes the LICENSE file from the repo root when fetching a submodule
if the submodule does not contain a LICENSE. This updates CreateFromVCS to match
that behavior.
Fixes golang/go#60442
Change-Id: I5f9edb775bb330325783e1c30d7d16e436bda74c
---
M zip/zip.go
M zip/zip_test.go
2 files changed, 112 insertions(+), 8 deletions(-)
To view, visit change 498935. To unsubscribe, or for help writing mail filters, visit settings.
Jordan Liggitt uploaded patch set #3 to this change.
zip: fix LICENSE file handling to match modfetch
go modfetch includes the LICENSE file from the repo root when fetching a submodule
if the submodule does not contain a LICENSE. This updates CreateFromVCS to match
that behavior.
Fixes golang/go#60442
Change-Id: I5f9edb775bb330325783e1c30d7d16e436bda74c
---
M zip/zip.go
M zip/zip_test.go
2 files changed, 117 insertions(+), 8 deletions(-)
To view, visit change 498935. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Bryan Mills.
Jordan Liggitt uploaded patch set #4 to this change.
zip: fix LICENSE file handling to match modfetch
go modfetch includes the LICENSE file from the repo root when fetching
a submodule if the submodule does not contain a LICENSE.
This updates CreateFromVCS to match that behavior.
Fixes golang/go#60442
Change-Id: I5f9edb775bb330325783e1c30d7d16e436bda74c
---
M zip/zip.go
M zip/zip_test.go
2 files changed, 117 insertions(+), 8 deletions(-)
To view, visit change 498935. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Bryan Mills, Jordan Liggitt.
Patch set 4:Run-TryBot +1
1 comment:
File zip/zip.go:
Patch Set #4, Line 689: cmd.Stderr = &stderr
Stderr is set to &stderr, but stderr is never used.
To view, visit change 498935. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Bryan Mills, Dmitri Shuralyov, Jordan Liggitt.
Jordan Liggitt uploaded patch set #5 to this change.
The following approvals got outdated and were removed: Run-TryBot+1 by Dmitri Shuralyov
zip: fix LICENSE file handling to match modfetch
go modfetch includes the LICENSE file from the repo root when fetching
a submodule if the submodule does not contain a LICENSE.
This updates CreateFromVCS to match that behavior.
Fixes golang/go#60442
Change-Id: I5f9edb775bb330325783e1c30d7d16e436bda74c
---
M zip/zip.go
M zip/zip_test.go
2 files changed, 115 insertions(+), 8 deletions(-)
To view, visit change 498935. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Bryan Mills, Dmitri Shuralyov.
1 comment:
File zip/zip.go:
Patch Set #4, Line 689: cmd.Stderr = &stderr
Stderr is set to &stderr, but stderr is never used.
Done
To view, visit change 498935. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Bryan Mills, Jordan Liggitt.
Patch set 5:Run-TryBot +1
Attention is currently required from: Bryan Mills, Jordan Liggitt.
Patch set 5:Commit-Queue +1
Attention is currently required from: Jordan Liggitt.
Patch set 5:Code-Review +2
Attention is currently required from: Jordan Liggitt.
Patch set 5:Run-TryBot +1Auto-Submit +1
Gopher Robot submitted this change.
zip: fix LICENSE file handling to match modfetch
go modfetch includes the LICENSE file from the repo root when fetching
a submodule if the submodule does not contain a LICENSE.
This updates CreateFromVCS to match that behavior.
Fixes golang/go#60442
Change-Id: I5f9edb775bb330325783e1c30d7d16e436bda74c
Reviewed-on: https://go-review.googlesource.com/c/mod/+/498935
TryBot-Result: Gopher Robot <go...@golang.org>
Reviewed-by: Bryan Mills <bcm...@google.com>
Run-TryBot: Dmitri Shuralyov <dmit...@golang.org>
Run-TryBot: Bryan Mills <bcm...@google.com>
Auto-Submit: Bryan Mills <bcm...@google.com>
---
M zip/zip.go
M zip/zip_test.go
2 files changed, 115 insertions(+), 8 deletions(-)
diff --git a/zip/zip.go b/zip/zip.go
index 7b48a2a..27b6f4b 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -56,6 +56,7 @@
"path"
"path/filepath"
"strings"
+ "time"
"unicode"
"unicode/utf8"
@@ -653,6 +654,7 @@
return nil, err
}
+ haveLICENSE := false
var fs []File
for _, zf := range zipReader.File {
if !strings.HasPrefix(zf.Name, subdir) || strings.HasSuffix(zf.Name, "/") {
@@ -669,6 +671,23 @@
name: n,
f: zf,
})
+ if n == "LICENSE" {
+ haveLICENSE = true
+ }
+ }
+
+ if !haveLICENSE && subdir != "" {
+ // Note: this method of extracting the license from the root copied from
+ // https://go.googlesource.com/go/+/refs/tags/go1.20.4/src/cmd/go/internal/modfetch/coderepo.go#1118
+ // https://go.googlesource.com/go/+/refs/tags/go1.20.4/src/cmd/go/internal/modfetch/codehost/git.go#657
+ cmd := exec.Command("git", "cat-file", "blob", rev+":LICENSE")
+ cmd.Dir = dir
+ cmd.Env = append(os.Environ(), "PWD="+dir)
+ stdout := bytes.Buffer{}
+ cmd.Stdout = &stdout
+ if err := cmd.Run(); err == nil {
+ fs = append(fs, dataFile{name: "LICENSE", data: stdout.Bytes()})
+ }
}
return fs, nil
@@ -710,6 +729,26 @@
func (f zipFile) Lstat() (os.FileInfo, error) { return f.f.FileInfo(), nil }
func (f zipFile) Open() (io.ReadCloser, error) { return f.f.Open() }
+type dataFile struct {
+ name string
+ data []byte
+}
+
+func (f dataFile) Path() string { return f.name }
+func (f dataFile) Lstat() (os.FileInfo, error) { return dataFileInfo{f}, nil }
+func (f dataFile) Open() (io.ReadCloser, error) { return io.NopCloser(bytes.NewReader(f.data)), nil }
+
+type dataFileInfo struct {
+ f dataFile
+}
+
+func (fi dataFileInfo) Name() string { return path.Base(fi.f.name) }
+func (fi dataFileInfo) Size() int64 { return int64(len(fi.f.data)) }
+func (fi dataFileInfo) Mode() os.FileMode { return 0644 }
+func (fi dataFileInfo) ModTime() time.Time { return time.Time{} }
+func (fi dataFileInfo) IsDir() bool { return false }
+func (fi dataFileInfo) Sys() interface{} { return nil }
To view, visit change 498935. To unsubscribe, or for help writing mail filters, visit settings.