add the ability to specify repository ref #80
| @@ -11,7 +11,7 @@ | |||||||
|     <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> |     <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> | ||||||
|         <text x="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text> |         <text x="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text> | ||||||
|         <text x="33.5" y="14">coverage</text> |         <text x="33.5" y="14">coverage</text> | ||||||
|         <text x="86" y="15" fill="#010101" fill-opacity=".3">16.4%</text> |         <text x="86" y="15" fill="#010101" fill-opacity=".3">17.0%</text> | ||||||
|         <text x="86" y="14">16.4%</text> |         <text x="86" y="14">17.0%</text> | ||||||
|     </g> |     </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 926 B After Width: | Height: | Size: 926 B | 
| @@ -413,19 +413,19 @@ msgstr "" | |||||||
| msgid "Executing %s()" | msgid "Executing %s()" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: pkg/repos/pull.go:79 | #: pkg/repos/pull.go:80 | ||||||
| msgid "Pulling repository" | msgid "Pulling repository" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: pkg/repos/pull.go:103 | #: pkg/repos/pull.go:116 | ||||||
| msgid "Repository up to date" | msgid "Repository up to date" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: pkg/repos/pull.go:160 | #: pkg/repos/pull.go:207 | ||||||
| msgid "Git repository does not appear to be a valid ALR repo" | msgid "Git repository does not appear to be a valid ALR repo" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: pkg/repos/pull.go:176 | #: pkg/repos/pull.go:223 | ||||||
| msgid "" | msgid "" | ||||||
| "ALR repo's minimum ALR version is greater than the current version. Try " | "ALR repo's minimum ALR version is greater than the current version. Try " | ||||||
| "updating ALR if something doesn't work." | "updating ALR if something doesn't work." | ||||||
|   | |||||||
| @@ -425,19 +425,19 @@ msgstr "Выполнение build()" | |||||||
| msgid "Executing %s()" | msgid "Executing %s()" | ||||||
| msgstr "Выполнение %s()" | msgstr "Выполнение %s()" | ||||||
|  |  | ||||||
| #: pkg/repos/pull.go:79 | #: pkg/repos/pull.go:80 | ||||||
| msgid "Pulling repository" | msgid "Pulling repository" | ||||||
| msgstr "Скачивание репозитория" | msgstr "Скачивание репозитория" | ||||||
|  |  | ||||||
| #: pkg/repos/pull.go:103 | #: pkg/repos/pull.go:116 | ||||||
| msgid "Repository up to date" | msgid "Repository up to date" | ||||||
| msgstr "Репозиторий уже обновлён" | msgstr "Репозиторий уже обновлён" | ||||||
|  |  | ||||||
| #: pkg/repos/pull.go:160 | #: pkg/repos/pull.go:207 | ||||||
| msgid "Git repository does not appear to be a valid ALR repo" | msgid "Git repository does not appear to be a valid ALR repo" | ||||||
| msgstr "Репозиторий Git не поддерживается репозиторием ALR" | msgstr "Репозиторий Git не поддерживается репозиторием ALR" | ||||||
|  |  | ||||||
| #: pkg/repos/pull.go:176 | #: pkg/repos/pull.go:223 | ||||||
| msgid "" | msgid "" | ||||||
| "ALR repo's minimum ALR version is greater than the current version. Try " | "ALR repo's minimum ALR version is greater than the current version. Try " | ||||||
| "updating ALR if something doesn't work." | "updating ALR if something doesn't work." | ||||||
|   | |||||||
| @@ -34,4 +34,5 @@ type Config struct { | |||||||
| type Repo struct { | type Repo struct { | ||||||
| 	Name string `toml:"name"` | 	Name string `toml:"name"` | ||||||
| 	URL  string `toml:"url"` | 	URL  string `toml:"url"` | ||||||
|  | 	Ref  string `toml:"ref"` | ||||||
| } | } | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ import ( | |||||||
| 	"github.com/go-git/go-billy/v5" | 	"github.com/go-git/go-billy/v5" | ||||||
| 	"github.com/go-git/go-billy/v5/osfs" | 	"github.com/go-git/go-billy/v5/osfs" | ||||||
| 	"github.com/go-git/go-git/v5" | 	"github.com/go-git/go-git/v5" | ||||||
|  | 	gitConfig "github.com/go-git/go-git/v5/config" | ||||||
| 	"github.com/go-git/go-git/v5/plumbing" | 	"github.com/go-git/go-git/v5/plumbing" | ||||||
| 	"github.com/leonelquinteros/gotext" | 	"github.com/leonelquinteros/gotext" | ||||||
| 	"github.com/pelletier/go-toml/v2" | 	"github.com/pelletier/go-toml/v2" | ||||||
| @@ -88,6 +89,14 @@ func (rs *Repos) Pull(ctx context.Context, repos []types.Repo) error { | |||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			err = r.FetchContext(ctx, &git.FetchOptions{ | ||||||
|  | 				Progress: os.Stderr, | ||||||
|  | 				Force:    true, | ||||||
|  | 			}) | ||||||
|  | 			if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			w, err := r.Worktree() | 			w, err := r.Worktree() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| @@ -98,16 +107,24 @@ func (rs *Repos) Pull(ctx context.Context, repos []types.Repo) error { | |||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			err = w.PullContext(ctx, &git.PullOptions{Progress: os.Stderr}) | 			revHash, err := resolveHash(r, repo.Ref) | ||||||
| 			if errors.Is(err, git.NoErrAlreadyUpToDate) { | 			if err != nil { | ||||||
|  | 				return fmt.Errorf("error resolving hash: %w", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if old.Hash() == *revHash { | ||||||
| 				slog.Info(gotext.Get("Repository up to date"), "name", repo.Name) | 				slog.Info(gotext.Get("Repository up to date"), "name", repo.Name) | ||||||
| 			} else if err != nil { | 			} | ||||||
|  |  | ||||||
|  | 			err = w.Checkout(&git.CheckoutOptions{ | ||||||
|  | 				Hash:  plumbing.NewHash(revHash.String()), | ||||||
|  | 				Force: true, | ||||||
|  | 			}) | ||||||
|  | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 			repoFS = w.Filesystem | 			repoFS = w.Filesystem | ||||||
|  |  | ||||||
| 			// Make sure the DB is created even if the repo is up to date |  | ||||||
| 			if !errors.Is(err, git.NoErrAlreadyUpToDate) || rs.db.IsEmpty(ctx) { |  | ||||||
| 			new, err := r.Head() | 			new, err := r.Head() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| @@ -127,7 +144,6 @@ func (rs *Repos) Pull(ctx context.Context, repos []types.Repo) error { | |||||||
| 					return err | 					return err | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			} |  | ||||||
| 		} else { | 		} else { | ||||||
| 			err = os.RemoveAll(repoDir) | 			err = os.RemoveAll(repoDir) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| @@ -139,9 +155,40 @@ func (rs *Repos) Pull(ctx context.Context, repos []types.Repo) error { | |||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			_, err = git.PlainCloneContext(ctx, repoDir, false, &git.CloneOptions{ | 			r, err := git.PlainInit(repoDir, false) | ||||||
| 				URL:      repoURL.String(), | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			_, err = r.CreateRemote(&gitConfig.RemoteConfig{ | ||||||
|  | 				Name: git.DefaultRemoteName, | ||||||
|  | 				URLs: []string{repoURL.String()}, | ||||||
|  | 			}) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			err = r.FetchContext(ctx, &git.FetchOptions{ | ||||||
| 				Progress: os.Stderr, | 				Progress: os.Stderr, | ||||||
|  | 				Force:    true, | ||||||
|  | 			}) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			w, err := r.Worktree() | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			revHash, err := resolveHash(r, repo.Ref) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return fmt.Errorf("error resolving hash: %w", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			err = w.Checkout(&git.CheckoutOptions{ | ||||||
|  | 				Hash:  plumbing.NewHash(revHash.String()), | ||||||
|  | 				Force: true, | ||||||
| 			}) | 			}) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| @@ -268,7 +315,8 @@ func (rs *Repos) processRepoChangesRunner(repoDir, scriptDir string) (*interp.Ru | |||||||
| 		interp.StatHandler(handlers.RestrictedStat(repoDir)), | 		interp.StatHandler(handlers.RestrictedStat(repoDir)), | ||||||
| 		interp.OpenHandler(handlers.RestrictedOpen(repoDir)), | 		interp.OpenHandler(handlers.RestrictedOpen(repoDir)), | ||||||
| 		interp.StdIO(handlers.NopRWC{}, handlers.NopRWC{}, handlers.NopRWC{}), | 		interp.StdIO(handlers.NopRWC{}, handlers.NopRWC{}, handlers.NopRWC{}), | ||||||
| 		interp.Dir(scriptDir), | 		// Use temp dir instead script dir because runner may be for deleted file | ||||||
|  | 		interp.Dir(os.TempDir()), | ||||||
| 	) | 	) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -285,7 +333,7 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git | |||||||
|  |  | ||||||
| 	patch, err := oldCommit.Patch(newCommit) | 	patch, err := oldCommit.Patch(newCommit) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return fmt.Errorf("error to create patch: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var actions []action | 	var actions []action | ||||||
| @@ -319,6 +367,7 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git | |||||||
| 				}, | 				}, | ||||||
| 			) | 			) | ||||||
| 		default: | 		default: | ||||||
|  | 			slog.Debug("unexpected, but I'll try to do") | ||||||
| 			actions = append(actions, action{ | 			actions = append(actions, action{ | ||||||
| 				Type: actionUpdate, | 				Type: actionUpdate, | ||||||
| 				File: to.Path(), | 				File: to.Path(), | ||||||
| @@ -332,7 +381,7 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git | |||||||
| 	for _, action := range actions { | 	for _, action := range actions { | ||||||
| 		runner, err := rs.processRepoChangesRunner(repoDir, filepath.Dir(filepath.Join(repoDir, action.File))) | 		runner, err := rs.processRepoChangesRunner(repoDir, filepath.Dir(filepath.Join(repoDir, action.File))) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return fmt.Errorf("error creating process repo changes runner: %w", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch action.Type { | 		switch action.Type { | ||||||
| @@ -340,15 +389,19 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git | |||||||
| 			if filepath.Base(action.File) != "alr.sh" { | 			if filepath.Base(action.File) != "alr.sh" { | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			scriptFl, err := oldCommit.File(action.File) | 			scriptFl, err := oldCommit.File(action.File) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil | 				return fmt.Errorf("error getting file: %w", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			r, err := scriptFl.Reader() | 			r, err := scriptFl.Reader() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil | 				return fmt.Errorf("error creating reader: %w", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			runner, err := rs.processRepoChangesRunner(repoDir, filepath.Dir(filepath.Join(repoDir, action.File))) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return fmt.Errorf("error creating process repo changes runner: %w", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			var pkg db.Package | 			var pkg db.Package | ||||||
| @@ -378,7 +431,7 @@ func (rs *Repos) processRepoChanges(ctx context.Context, repo types.Repo, r *git | |||||||
|  |  | ||||||
| 			err = rs.updatePkg(ctx, repo, runner, r) | 			err = rs.updatePkg(ctx, repo, runner, r) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return fmt.Errorf("error updatePkg: %w", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -18,12 +18,18 @@ package repos | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/go-git/go-git/v5" | ||||||
|  | 	"github.com/go-git/go-git/v5/plumbing" | ||||||
| 	"github.com/go-git/go-git/v5/plumbing/format/diff" | 	"github.com/go-git/go-git/v5/plumbing/format/diff" | ||||||
|  | 	"github.com/go-git/go-git/v5/plumbing/transport" | ||||||
|  | 	"github.com/go-git/go-git/v5/plumbing/transport/client" | ||||||
|  |  | ||||||
| 	"mvdan.cc/sh/v3/interp" | 	"mvdan.cc/sh/v3/interp" | ||||||
| 	"mvdan.cc/sh/v3/syntax" | 	"mvdan.cc/sh/v3/syntax" | ||||||
|  |  | ||||||
| @@ -137,3 +143,59 @@ func resolveOverrides(runner *interp.Runner, pkg *db.Package) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func getHeadReference(r *git.Repository) (plumbing.ReferenceName, error) { | ||||||
|  | 	remote, err := r.Remote(git.DefaultRemoteName) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	endpoint, err := transport.NewEndpoint(remote.Config().URLs[0]) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gitClient, err := client.NewClient(endpoint) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	session, err := gitClient.NewUploadPackSession(endpoint, nil) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	info, err := session.AdvertisedReferences() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	refs, err := info.AllReferences() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return refs["HEAD"].Target(), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func resolveHash(r *git.Repository, ref string) (*plumbing.Hash, error) { | ||||||
|  | 	var err error | ||||||
|  |  | ||||||
|  | 	if ref == "" { | ||||||
|  | 		reference, err := getHeadReference(r) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("failed to get head reference %w", err) | ||||||
|  | 		} | ||||||
|  | 		ref = reference.Short() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	hsh, err := r.ResolveRevision(git.DefaultRemoteName + "/" + plumbing.Revision(ref)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		hsh, err = r.ResolveRevision(plumbing.Revision(ref)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return hsh, nil | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user