3 Commits

3 changed files with 136 additions and 13 deletions
+52 -10
View File
@@ -126,7 +126,7 @@ func downloadFile(filename, url string) error {
// get downloads the source module into the provided GOPATH,
// checking out the specified revision if non-empty.
func (u *upstream) get(gopath, sourceRepo, requestedPath, rev string) error {
func (u *upstream) get(gopath, sourceRepo, requestedPath, rev string, forcePrerelease bool) error {
done := make(chan struct{})
defer close(done)
go progressSize("git clone", filepath.Join(gopath, "src"), done)
@@ -147,16 +147,29 @@ func (u *upstream) get(gopath, sourceRepo, requestedPath, rev string) error {
return fmt.Errorf("mkdir clone parent: %w", err)
}
cmd := exec.Command("git", "clone", u.repoURL, dir)
cmd.Env = passthroughEnv()
cmd.Stderr = os.Stderr
log.Println("get: Running", cmd)
if err := cmd.Run(); err != nil {
return fmt.Errorf("git clone: %w", err)
cloneRef := shallowCloneRef(info, rev, forcePrerelease)
shallowCloneSucceeded := false
if cloneRef != "" {
if err := runGitClone(u.repoURL, dir, cloneRef, true); err == nil {
shallowCloneSucceeded = true
log.Printf("Shallow cloned %q at %q", u.repoURL, cloneRef)
} else {
log.Printf("WARNING: shallow git clone at %q failed, falling back to full clone: %v", cloneRef, err)
if removeErr := os.RemoveAll(dir); removeErr != nil {
return fmt.Errorf("remove failed shallow clone dir: %w", removeErr)
}
if err := runGitClone(u.repoURL, dir, "", false); err != nil {
return fmt.Errorf("git clone: %w", err)
}
}
} else {
if err := runGitClone(u.repoURL, dir, "", false); err != nil {
return fmt.Errorf("git clone: %w", err)
}
}
if rev != "" {
cmd = exec.Command("git", "-c", "advice.detachedHead=false", "checkout", rev)
if rev != "" && !(shallowCloneSucceeded && rev == cloneRef) {
cmd := exec.Command("git", "-c", "advice.detachedHead=false", "checkout", rev)
cmd.Dir = dir
cmd.Env = passthroughEnv()
cmd.Stderr = os.Stderr
@@ -168,6 +181,35 @@ func (u *upstream) get(gopath, sourceRepo, requestedPath, rev string) error {
return nil
}
func shallowCloneRef(info *pkgsiteInfo, rev string, forcePrerelease bool) string {
if forcePrerelease || rev != "" {
return ""
}
if info != nil {
return strings.TrimSpace(info.Package.Version)
}
return ""
}
func gitCloneArgs(repoURL, dir, ref string, shallow bool) []string {
args := []string{"-c", "advice.detachedHead=false", "clone"}
if shallow {
args = append(args, "--depth=1", "--single-branch")
if ref != "" {
args = append(args, "--branch", ref)
}
}
return append(args, repoURL, dir)
}
func runGitClone(repoURL, dir, ref string, shallow bool) error {
cmd := exec.Command("git", gitCloneArgs(repoURL, dir, ref, shallow)...)
cmd.Env = passthroughEnv()
cmd.Stderr = os.Stderr
log.Println("get: Running", cmd)
return cmd.Run()
}
func guessedPackageType(u *upstream) packageType {
if u.packageName == "main" || (u.packageName == "" && u.firstMain != "") {
return typeProgram
@@ -604,7 +646,7 @@ func makeUpstreamSourceTarball(requestedPath, sourceRepo, revision string, force
var u upstream
log.Printf("Downloading %q\n", sourceRepo+"/...")
if err := u.get(gopath, sourceRepo, requestedPath, revision); err != nil {
if err := u.get(gopath, sourceRepo, requestedPath, revision, forcePrerelease); err != nil {
return nil, fmt.Errorf("get source: %w", err)
}
+79
View File
@@ -91,6 +91,30 @@ func TestCleanSpecAssetPath(t *testing.T) {
}
}
func TestWriteLicenseAndDocFilesOrdersDocBeforeSortedLicenses(t *testing.T) {
path := filepath.Join(t.TempDir(), "files")
f, err := os.Create(path)
if err != nil {
t.Fatalf("create temp file: %v", err)
}
writeLicenseAndDocFiles(f, specAssetFiles{
licenseFiles: []string{"zLICENSE", "COPYING", "LICENSE"},
readmeFile: "README.md",
}, true)
if err := f.Close(); err != nil {
t.Fatalf("close temp file: %v", err)
}
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read temp file: %v", err)
}
want := "%doc README.md\n%license COPYING\n%license LICENSE\n%license zLICENSE\n"
if got := string(content); got != want {
t.Fatalf("writeLicenseAndDocFiles() = %q, want %q", got, want)
}
}
func TestSummaryFromReadme(t *testing.T) {
readme := `
# Project
@@ -281,6 +305,61 @@ func TestGoImportPathFromArgument(t *testing.T) {
}
}
func TestShallowCloneRef(t *testing.T) {
info := &pkgsiteInfo{Package: pkgsitePackage{Version: "v1.2.3"}}
tests := []struct {
name string
info *pkgsiteInfo
rev string
forcePrerelease bool
want string
}{
{
name: "skips shallow clone for explicit revision",
info: info,
rev: "v1.2.4",
want: "",
},
{
name: "uses pkgsite latest version",
info: info,
want: "v1.2.3",
},
{
name: "skips shallow clone for prerelease packaging",
info: info,
forcePrerelease: true,
want: "",
},
{
name: "handles missing pkgsite info",
want: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := shallowCloneRef(tt.info, tt.rev, tt.forcePrerelease); got != tt.want {
t.Fatalf("shallowCloneRef() = %q, want %q", got, tt.want)
}
})
}
}
func TestGitCloneArgs(t *testing.T) {
got := strings.Join(gitCloneArgs("https://example.com/repo", "/tmp/repo", "v1.2.3", true), " ")
want := "-c advice.detachedHead=false clone --depth=1 --single-branch --branch v1.2.3 https://example.com/repo /tmp/repo"
if got != want {
t.Fatalf("gitCloneArgs(shallow) = %q, want %q", got, want)
}
got = strings.Join(gitCloneArgs("https://example.com/repo", "/tmp/repo", "", false), " ")
want = "-c advice.detachedHead=false clone https://example.com/repo /tmp/repo"
if got != want {
t.Fatalf("gitCloneArgs(full) = %q, want %q", got, want)
}
}
func TestSetRepoDependenciesSeparatesRuntimeAndTestOnly(t *testing.T) {
u := upstream{}
u.setRepoDependencies(
+5 -3
View File
@@ -269,12 +269,14 @@ func writeRPMProgramSubpackage(f *os.File, gopkg, openRuyiProgram, openRuyiSrc,
}
func writeLicenseAndDocFiles(f *os.File, assetFiles specAssetFiles, includeDoc bool) {
for _, licenseFile := range assetFiles.licenseFiles {
fmt.Fprintf(f, "%%license %s\n", licenseFile)
}
if includeDoc && assetFiles.readmeFile != "" {
fmt.Fprintf(f, "%%doc %s\n", assetFiles.readmeFile)
}
licenseFiles := append([]string(nil), assetFiles.licenseFiles...)
sort.Strings(licenseFiles)
for _, licenseFile := range licenseFiles {
fmt.Fprintf(f, "%%license %s\n", licenseFile)
}
}
func writeRPMFilesSection(f *os.File, openRuyiSrc, openRuyiLib, openRuyiProgram string, pkgType packageType, assetFiles specAssetFiles) {