From 72c757b7a44dc5d19d821f7c2fa36bb082e4f2e3 Mon Sep 17 00:00:00 2001 From: Sandro Jäckel Date: Mon, 17 Apr 2023 13:28:47 +0200 Subject: Save rtree with go 1.20 --- internal/rtree/index.go | 18 +++++++++--------- internal/rtree/init.go | 22 +++++++++++----------- internal/rtree/main.go | 10 +++++----- internal/rtree/remote.go | 43 +++++++++++++++++++++---------------------- internal/rtree/remote_test.go | 2 +- internal/rtree/repo.go | 40 ++++++++++++++++++++-------------------- internal/rtree/shared_test.go | 24 ++++++++++++------------ 7 files changed, 79 insertions(+), 80 deletions(-) (limited to 'internal/rtree') diff --git a/internal/rtree/index.go b/internal/rtree/index.go index 226689a..3a351a3 100644 --- a/internal/rtree/index.go +++ b/internal/rtree/index.go @@ -33,12 +33,12 @@ import ( yaml "gopkg.in/yaml.v2" ) -//Index represents the contents of the index file. +// Index represents the contents of the index file. type Index struct { Repos []*Repo `yaml:"repos"` } -//ReadIndex reads the index file. +// ReadIndex reads the index file. func ReadIndex() (*Index, []error) { //read contents of index file buf, err := ioutil.ReadFile(IndexPath) @@ -90,7 +90,7 @@ func (r reposByAbsPath) Len() int { return len(r) } func (r reposByAbsPath) Less(i, j int) bool { return r[i].AbsolutePath() < r[j].AbsolutePath() } func (r reposByAbsPath) Swap(i, j int) { r[i], r[j] = r[j], r[i] } -//Write writes the index file to disk. +// Write writes the index file to disk. func (i *Index) Write() error { sort.Sort(reposByAbsPath(i.Repos)) buf, err := yaml.Marshal(i) @@ -123,7 +123,7 @@ func (i *Index) Write() error { return nil } -//Rebuild implements the `rtree index` subcommand. +// Rebuild implements the `rtree index` subcommand. func (i *Index) Rebuild() error { //check if existing index entries are still checked out var newRepos []*Repo @@ -210,9 +210,9 @@ func (i *Index) Rebuild() error { return nil } -//FindRepo locates the repo with the given remote if it exists on disk or (if -//allowClone is set) clones it and adds it to the index. This is the meat of -//`rtree get`, and is also used by `rtree drop`. +// FindRepo locates the repo with the given remote if it exists on disk or (if +// allowClone is set) clones it and adds it to the index. This is the meat of +// `rtree get`, and is also used by `rtree drop`. func (i *Index) FindRepo(rawRemoteURL string, allowClone bool) (*Repo, error) { //make sure that stdout is not used for prompts cli.Interface.StdoutProtected = true @@ -343,7 +343,7 @@ func (i *Index) FindRepo(rawRemoteURL string, allowClone bool) (*Repo, error) { return target, nil } -//ImportRepo moves the given repo into the rtree and adds it to the index. +// ImportRepo moves the given repo into the rtree and adds it to the index. func (i *Index) ImportRepo(dirPath string) error { //need to make dirPath absolute first dirPath, err := filepath.Abs(dirPath) @@ -405,7 +405,7 @@ func (i *Index) ImportRepo(dirPath string) error { return nil } -//DropRepo deletes the given repo from the rtree and removes it from the index. +// DropRepo deletes the given repo from the rtree and removes it from the index. func (i *Index) DropRepo(repo *Repo) error { err := repo.Exec("git", "status") if err != nil { diff --git a/internal/rtree/init.go b/internal/rtree/init.go index 569f042..7121af9 100644 --- a/internal/rtree/init.go +++ b/internal/rtree/init.go @@ -27,29 +27,29 @@ import ( "github.com/majewsky/gofu/internal/cli" ) -//RemoteAlias describes an alias that can be used in a Git remote URL (as -//defined by the "url..insteadOf" directive in man:git-config(1)). +// RemoteAlias describes an alias that can be used in a Git remote URL (as +// defined by the "url..insteadOf" directive in man:git-config(1)). type RemoteAlias struct { Alias string Replacement string } -//IndexPath is where the index file is stored. +// IndexPath is where the index file is stored. var IndexPath string -//RootPath is the directory below which all repositories are located. Its value -//is $GOPATH/src to match the repository layout created by `go get`. +// RootPath is the directory below which all repositories are located. Its value +// is $GOPATH/src to match the repository layout created by `go get`. var RootPath string -//RemoteAliases is the list of remote aliases that is used by ExpandRemoteURL(). +// RemoteAliases is the list of remote aliases that is used by ExpandRemoteURL(). var RemoteAliases []*RemoteAlias -//Init initializes the global variables of this package to their standard -//values, unless they are already populated. Unit tests shall set IndexPath, -//RootPath etc. before calling Exec(), such that this function becomes a no-op -//when called by Exec(). +// Init initializes the global variables of this package to their standard +// values, unless they are already populated. Unit tests shall set IndexPath, +// RootPath etc. before calling Exec(), such that this function becomes a no-op +// when called by Exec(). // -//Returns false if initialization failed. +// Returns false if initialization failed. func Init() bool { ok := true //until shown otherwise diff --git a/internal/rtree/main.go b/internal/rtree/main.go index f401ced..7e27428 100644 --- a/internal/rtree/main.go +++ b/internal/rtree/main.go @@ -24,11 +24,11 @@ import ( "github.com/majewsky/gofu/internal/cli" ) -//Exec executes the rtree applet and returns an exit code (0 for success, >0 -//for error). The argument is os.Args minus the leading "rtree" or "gofu -//rtree". All side-effects (reading from stdin, writing to stdout/stderr, -//executing other programs) pass through cli.Interface and can be intercepted -//there for the purpose of testing. +// Exec executes the rtree applet and returns an exit code (0 for success, >0 +// for error). The argument is os.Args minus the leading "rtree" or "gofu +// rtree". All side-effects (reading from stdin, writing to stdout/stderr, +// executing other programs) pass through cli.Interface and can be intercepted +// there for the purpose of testing. func Exec(args []string) int { if !Init() { return 1 diff --git a/internal/rtree/remote.go b/internal/rtree/remote.go index 8435979..2973b8c 100644 --- a/internal/rtree/remote.go +++ b/internal/rtree/remote.go @@ -25,18 +25,18 @@ import ( "strings" ) -//RemoteURL is the URL of a remote of a Git repository. +// RemoteURL is the URL of a remote of a Git repository. type RemoteURL string -//ParseRemoteURL parses the given remote URL by substituting aliases defined in -//the system-wide and user-global Git config. For example, with +// ParseRemoteURL parses the given remote URL by substituting aliases defined in +// the system-wide and user-global Git config. For example, with // -// $ cat /etc/gitconfig -// [url "git://github.com/"] -// insteadOf = gh: +// $ cat /etc/gitconfig +// [url "git://github.com/"] +// insteadOf = gh: // -//and the input "gh:foo/bar", the result has a canonical URL of -//"git://github.com/foo/bar". +// and the input "gh:foo/bar", the result has a canonical URL of +// "git://github.com/foo/bar". func ParseRemoteURL(input string) RemoteURL { var best *RemoteAlias for _, current := range RemoteAliases { @@ -52,15 +52,15 @@ func ParseRemoteURL(input string) RemoteURL { return RemoteURL(best.Replacement + strings.TrimPrefix(input, best.Alias)) } -//CanonicalURL returns the URL where the remote will be fetched from. +// CanonicalURL returns the URL where the remote will be fetched from. func (u RemoteURL) CanonicalURL() string { return string(u) } -//CompactURL returns the most compact representation of this remote URL, -//obtained by substituting the longest matching alias defined in the -//system-wide or user-global Git config. This function is mostly the reverse of -//ParseRemoteURL(). +// CompactURL returns the most compact representation of this remote URL, +// obtained by substituting the longest matching alias defined in the +// system-wide or user-global Git config. This function is mostly the reverse of +// ParseRemoteURL(). func (u RemoteURL) CompactURL() string { var best *RemoteAlias for _, current := range RemoteAliases { @@ -76,16 +76,15 @@ func (u RemoteURL) CompactURL() string { return best.Alias + strings.TrimPrefix(string(u), best.Replacement) } -//This regex recognizes the scp-like syntax for git remotes -//(i.e. "[user@]example.org:path/to/repo") as specified by the "GIT URLS" -//section of man:git-clone(1). +// This regex recognizes the scp-like syntax for git remotes +// (i.e. "[user@]example.org:path/to/repo") as specified by the "GIT URLS" +// section of man:git-clone(1). var scpSyntaxRx = regexp.MustCompile(`^(?:[^/@:]+@)?([^/:]+\.[^/:]+):(.+)$`) -//CheckoutPath derives the checkout path for a remote URL. -// -// RemoteURL("https://example.org/foo/bar") -> "example.org/foo/bar" -// RemoteURL("git@example.org:foo/bar.git") -> "example.org/foo/bar" +// CheckoutPath derives the checkout path for a remote URL. // +// RemoteURL("https://example.org/foo/bar") -> "example.org/foo/bar" +// RemoteURL("git@example.org:foo/bar.git") -> "example.org/foo/bar" func (u RemoteURL) CheckoutPath() (string, error) { stripped := strings.TrimSuffix(u.CanonicalURL(), ".git") @@ -102,13 +101,13 @@ func (u RemoteURL) CheckoutPath() (string, error) { return filepath.Join(parsed.Hostname(), parsed.Path), nil } -//MarshalYAML implements the yaml.Marshaler interface. +// MarshalYAML implements the yaml.Marshaler interface. func (u RemoteURL) MarshalYAML() (interface{}, error) { //store URLs in the index in the compact format return u.CompactURL(), nil } -//UnmarshalYAML implements the yaml.Unmarshaler interface. +// UnmarshalYAML implements the yaml.Unmarshaler interface. func (u *RemoteURL) UnmarshalYAML(unmarshal func(interface{}) error) error { var s string err := unmarshal(&s) diff --git a/internal/rtree/remote_test.go b/internal/rtree/remote_test.go index 5910a5c..3a8de82 100644 --- a/internal/rtree/remote_test.go +++ b/internal/rtree/remote_test.go @@ -47,7 +47,7 @@ func TestParseRemoteURL(t *testing.T) { } } -//Most of those are just reversed from `testExpansions`. +// Most of those are just reversed from `testExpansions`. var testContractions = map[RemoteURL]string{ "https://github.com/foo/bar": "gh:f:bar", "https://github.com/bar/foo": "gh:b:foo", diff --git a/internal/rtree/repo.go b/internal/rtree/repo.go index f710666..5cdd39f 100644 --- a/internal/rtree/repo.go +++ b/internal/rtree/repo.go @@ -28,7 +28,7 @@ import ( "github.com/majewsky/gofu/internal/cli" ) -//Repo describes the entry for a repository in the index file. +// Repo describes the entry for a repository in the index file. type Repo struct { //CheckoutPath shall be relative to the RootPath. CheckoutPath string `yaml:"path"` @@ -38,24 +38,24 @@ type Repo struct { Remotes []Remote `yaml:"remotes"` } -//Remote describes a remote that is configured in a Repo. +// Remote describes a remote that is configured in a Repo. type Remote struct { Name string `yaml:"name"` URL RemoteURL `yaml:"url"` } -//AbsolutePath returns the absolute CheckoutPath of this repo. +// AbsolutePath returns the absolute CheckoutPath of this repo. func (r Repo) AbsolutePath() string { return filepath.Join(RootPath, r.CheckoutPath) } -//GitDirPath returns the path of the .git directory of this repo. +// GitDirPath returns the path of the .git directory of this repo. func (r Repo) GitDirPath() string { return filepath.Join(r.AbsolutePath(), ".git") } -//NewRepoFromAbsolutePath initializes a Repo instance by scanning the existing -//checkout at the given path. +// NewRepoFromAbsolutePath initializes a Repo instance by scanning the existing +// checkout at the given path. func NewRepoFromAbsolutePath(path string) (repo Repo, err error) { repo.CheckoutPath, err = filepath.Rel(RootPath, path) if err != nil { @@ -84,8 +84,8 @@ func NewRepoFromAbsolutePath(path string) (repo Repo, err error) { return } -//NewRepoFromRemoteURL initializes a Repo instance for checking out a remote -//for the first time. The checkout does not happen until Checkout() is called. +// NewRepoFromRemoteURL initializes a Repo instance for checking out a remote +// for the first time. The checkout does not happen until Checkout() is called. func NewRepoFromRemoteURL(remoteURL RemoteURL) (Repo, error) { checkoutPath, err := remoteURL.CheckoutPath() return Repo{ @@ -101,9 +101,9 @@ func NewRepoFromRemoteURL(remoteURL RemoteURL) (Repo, error) { var remoteConfigRx = regexp.MustCompile(`remote\.([^=]+)\.url=(.+)`) -//ForeachPhysicalRepo walks over the repository tree, executing the action -//function once for every repo encountered (but *not* for repos contained -//within other repos, e.g. submodules). +// ForeachPhysicalRepo walks over the repository tree, executing the action +// function once for every repo encountered (but *not* for repos contained +// within other repos, e.g. submodules). func ForeachPhysicalRepo(action func(repo Repo) error) error { return filepath.Walk(RootPath, func(path string, info os.FileInfo, err error) error { if err != nil { @@ -131,8 +131,8 @@ func ForeachPhysicalRepo(action func(repo Repo) error) error { }) } -//Checkout creates the repo in the given path with the given remotes. The -//working copy will only be initialized if there is an "origin" remote. +// Checkout creates the repo in the given path with the given remotes. The +// working copy will only be initialized if there is an "origin" remote. func (r Repo) Checkout() error { //check if we have an "origin" remote to clone from var originURL RemoteURL @@ -183,8 +183,8 @@ func (r Repo) Checkout() error { return nil } -//Exec implements the meat of the `rtree exec` command. It returns -//true iff the command exited successfully. +// Exec implements the meat of the `rtree exec` command. It returns +// true iff the command exited successfully. func (r Repo) Exec(cmdline ...string) error { cli.Interface.ShowProgress(r.AbsolutePath()) return cli.Interface.Run(cli.Command{ @@ -193,9 +193,9 @@ func (r Repo) Exec(cmdline ...string) error { }) } -//Move sets the CheckoutPath to the given value and moves the existing repo -//from the old to the new checkoutPath. If makeSymlink is given, a symlink will -//be created from the old to the new location. +// Move sets the CheckoutPath to the given value and moves the existing repo +// from the old to the new checkoutPath. If makeSymlink is given, a symlink will +// be created from the old to the new location. func (r *Repo) Move(checkoutPath string, makeSymlink bool) error { sourcePath := filepath.Join(RootPath, r.CheckoutPath) targetPath := filepath.Join(RootPath, checkoutPath) @@ -229,8 +229,8 @@ func (r *Repo) Move(checkoutPath string, makeSymlink bool) error { return nil } -//ReformatRemoteURLs rewrites the remote URLs in this repo's .git/config into -//their compact forms. +// ReformatRemoteURLs rewrites the remote URLs in this repo's .git/config into +// their compact forms. func (r Repo) ReformatRemoteURLs() error { for _, remote := range r.Remotes { err := cli.Interface.Run(cli.Command{ diff --git a/internal/rtree/shared_test.go b/internal/rtree/shared_test.go index 6720b1c..bd8c238 100644 --- a/internal/rtree/shared_test.go +++ b/internal/rtree/shared_test.go @@ -34,7 +34,7 @@ import ( yaml "gopkg.in/yaml.v2" ) -//Path to a directory where tests can put their index files. +// Path to a directory where tests can put their index files. var indexTmpDir = filepath.Join(os.TempDir(), fmt.Sprintf("rtree-test-%d", os.Getpid())) func TestMain(m *testing.M) { @@ -56,8 +56,8 @@ func TestMain(m *testing.M) { os.Exit(exitCode) } -//Test describes a call to Main(), the environment that's given to it, and the -//assertions that are checked after the call returns. +// Test describes a call to Main(), the environment that's given to it, and the +// assertions that are checked after the call returns. type Test struct { Args []string Input string @@ -137,11 +137,11 @@ type RecordedCommand struct { Fails bool } -//Recorded is a shortcut function for initializing a []RecordedCommand. It -//splits each line on whitespace to obtain the command line of that command, -//and recognizes a leading "@/some/path" to set the workdir. +// Recorded is a shortcut function for initializing a []RecordedCommand. It +// splits each line on whitespace to obtain the command line of that command, +// and recognizes a leading "@/some/path" to set the workdir. // -//This function can only be used for RecordedCommands without output that do not fail. +// This function can only be used for RecordedCommands without output that do not fail. func Recorded(lines ...string) (cs []RecordedCommand) { cs = make([]RecordedCommand, len(lines)) for idx, line := range lines { @@ -155,11 +155,11 @@ func Recorded(lines ...string) (cs []RecordedCommand) { return } -//CommandSimulator implements the cli.CommandRunner interface (via its Next -//method). When a cli.Command is given to Next(), it is matched with the next -//command in the .Cmd list, and the result from that RecordedCommand is -//returned. If the given Command is different from the one expected (or if the -//.Cmd list has been exhausted), an error is returned. +// CommandSimulator implements the cli.CommandRunner interface (via its Next +// method). When a cli.Command is given to Next(), it is matched with the next +// command in the .Cmd list, and the result from that RecordedCommand is +// returned. If the given Command is different from the one expected (or if the +// .Cmd list has been exhausted), an error is returned. type CommandSimulator struct { Cmd []RecordedCommand idx int -- cgit v1.3.1 From d0059fcb87312d296a31d6965d6db84e499fe020 Mon Sep 17 00:00:00 2001 From: Sandro Jäckel Date: Mon, 17 Apr 2023 14:43:15 +0200 Subject: Only use compact URL in UI, not in written files many tools like eg some vscode extensions can parse the git remotes but do not respect git aliases and fail to understand shorthands like gh:majewsky/gofu --- internal/rtree/get_test.go | 8 ++++---- internal/rtree/remote.go | 2 +- internal/rtree/repo.go | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'internal/rtree') diff --git a/internal/rtree/get_test.go b/internal/rtree/get_test.go index a438234..789e903 100644 --- a/internal/rtree/get_test.go +++ b/internal/rtree/get_test.go @@ -35,7 +35,7 @@ var testIndexWithTwoRepos = Index{ { CheckoutPath: "github.com/git/git", Remotes: []Remote{ - {Name: "origin", URL: "gh:git/git"}, + {Name: "origin", URL: "https://github.com/git/git"}, }, }, }, @@ -65,14 +65,14 @@ func TestGetNewRepo(t *testing.T) { Args: []string{"get", remoteURL}, Index: testIndexWithTwoRepos, ExpectOutput: target + "\n", - ExpectExecution: Recorded("git clone gh:another/repo " + target), + ExpectExecution: Recorded("git clone https://github.com/another/repo " + target), ExpectIndex: &Index{ Repos: []*Repo{ { CheckoutPath: "github.com/another/repo", Remotes: []Remote{ //regardless of the remote URL used, we expect the contracted form to be used - {Name: "origin", URL: "gh:another/repo"}, + {Name: "origin", URL: "https://github.com/another/repo"}, }, }, testIndexWithTwoRepos.Repos[0], @@ -106,7 +106,7 @@ func TestGetNewForkAsRemote(t *testing.T) { { CheckoutPath: "github.com/git/git", Remotes: []Remote{ - {Name: "origin", URL: "gh:git/git"}, + {Name: "origin", URL: "https://github.com/git/git"}, {Name: "myfork", URL: "https://example.com/git"}, }, }, diff --git a/internal/rtree/remote.go b/internal/rtree/remote.go index 2973b8c..36e12dd 100644 --- a/internal/rtree/remote.go +++ b/internal/rtree/remote.go @@ -104,7 +104,7 @@ func (u RemoteURL) CheckoutPath() (string, error) { // MarshalYAML implements the yaml.Marshaler interface. func (u RemoteURL) MarshalYAML() (interface{}, error) { //store URLs in the index in the compact format - return u.CompactURL(), nil + return u.CanonicalURL(), nil } // UnmarshalYAML implements the yaml.Unmarshaler interface. diff --git a/internal/rtree/repo.go b/internal/rtree/repo.go index 5cdd39f..2267666 100644 --- a/internal/rtree/repo.go +++ b/internal/rtree/repo.go @@ -153,7 +153,7 @@ func (r Repo) Checkout() error { cli.Interface.ShowWarning(`will not checkout anything since there is no remote named "origin"`) } else { err := cli.Interface.Run(cli.Command{ - Program: []string{"git", "clone", originURL.CompactURL(), r.AbsolutePath()}, + Program: []string{"git", "clone", originURL.CanonicalURL(), r.AbsolutePath()}, }) if err != nil { return err @@ -164,7 +164,7 @@ func (r Repo) Checkout() error { for _, remote := range r.Remotes { if remote.Name != "origin" { err := cli.Interface.Run(cli.Command{ - Program: []string{"git", "remote", "add", remote.Name, remote.URL.CompactURL()}, + Program: []string{"git", "remote", "add", remote.Name, remote.URL.CanonicalURL()}, WorkDir: r.AbsolutePath(), }) if err != nil { @@ -234,7 +234,7 @@ func (r *Repo) Move(checkoutPath string, makeSymlink bool) error { func (r Repo) ReformatRemoteURLs() error { for _, remote := range r.Remotes { err := cli.Interface.Run(cli.Command{ - Program: []string{"git", "remote", "set-url", remote.Name, remote.URL.CompactURL()}, + Program: []string{"git", "remote", "set-url", remote.Name, remote.URL.CanonicalURL()}, WorkDir: r.AbsolutePath(), }) if err != nil { -- cgit v1.3.1