diff --git a/config.go b/config.go index 4a1f653..3aaea3c 100644 --- a/config.go +++ b/config.go @@ -31,13 +31,15 @@ func resolvePath(homedir string, path string) string { // config describes the config.toml. // Changes to this should be accompanied by changes to DefaultConfig. type config struct { - DefaultImage string `toml:"default_image"` - ProjectRoot string `toml:"project_root"` - DefaultHat string `toml:"default_hat"` - DefaultSchema string `toml:"default_schema"` - DefaultHost string `toml:"default_host"` + DefaultImage string `toml:"default_image"` + ProjectRoot string `toml:"project_root"` + DefaultHat string `toml:"default_hat"` + DefaultSchema string `toml:"default_schema"` + DefaultHost string `toml:"default_host"` + DefaultOrganization string `toml:"default_organization"` } +// DefaultConfig is the default configuration file string. const DefaultConfig = `# sail configuration. # default_image is the default Docker image to use if the repository provides none. default_image = "codercom/ubuntu-dev" @@ -54,6 +56,10 @@ default_schema = "ssh" # default host used to clone repo in sail run if none given default_host = "github.com" + +# default_oranization lets you configure which username to use on default_host +# when cloning a repo. +# default_organization = "" ` // metaRoot returns the root path of all metadata stored on the host. diff --git a/globalflags.go b/globalflags.go index 1f01d1a..d97e5ab 100644 --- a/globalflags.go +++ b/globalflags.go @@ -43,7 +43,7 @@ func requireRepo(conf config, prefs schemaPrefs, fl *flag.FlagSet) repo { flog.Fatal("Argument must be provided.") } - r, err := parseRepo(defaultSchema(conf, prefs), conf.DefaultHost, repoURI) + r, err := parseRepo(defaultSchema(conf, prefs), conf.DefaultHost, conf.DefaultOrganization, repoURI) if err != nil { flog.Fatal("failed to parse repo %q: %v", repoURI, err) } diff --git a/project_test.go b/project_test.go index 6b0e4e9..3f2cf62 100644 --- a/project_test.go +++ b/project_test.go @@ -51,7 +51,7 @@ func Test_project(t *testing.T) { rb := newRollback() defer rb.run() - repo, err := parseRepo(test.schema, "github.com", test.repo) + repo, err := parseRepo(test.schema, "github.com", "", test.repo) require.NoError(t, err) p := &project{ diff --git a/repo.go b/repo.go index ef45d43..eac3633 100644 --- a/repo.go +++ b/repo.go @@ -44,7 +44,7 @@ func (r repo) BaseName() string { // It can be a full url like https://github.com/cdr/sail or ssh://git@github.com/cdr/sail, // or just the path like cdr/sail and the host + schema will be inferred. // By default the host and the schema will be the provided defaultSchema. -func parseRepo(defaultSchema, defaultHost, name string) (repo, error) { +func parseRepo(defaultSchema, defaultHost, defaultOrganization, name string) (repo, error) { u, err := url.Parse(name) if err != nil { return repo{}, xerrors.Errorf("failed to parse repo path: %w", err) @@ -68,6 +68,11 @@ func parseRepo(defaultSchema, defaultHost, name string) (repo, error) { } } + // add the defaultOrganization if the path has no slashes + if defaultOrganization != "" && !strings.Contains(r.trimPath(), "/") { + r.Path = fmt.Sprintf("%v/%v", defaultOrganization, r.trimPath()) + } + // make sure path doesn't have a leading forward slash r.Path = strings.TrimPrefix(r.Path, "/") diff --git a/repo_test.go b/repo_test.go index 46a6271..73ed245 100644 --- a/repo_test.go +++ b/repo_test.go @@ -9,9 +9,10 @@ import ( func TestParseRepo(t *testing.T) { var tests = []struct { - defSchema string - defHost string - fullPath string + defSchema string + defHost string + defOrganization string + fullPath string expPath string expHost string @@ -23,6 +24,7 @@ func TestParseRepo(t *testing.T) { { "ssh", "github.com", + "", "cdr/sail", "cdr/sail", "github.com", @@ -34,6 +36,7 @@ func TestParseRepo(t *testing.T) { { "http", "github.com", + "", "cdr/sail", "cdr/sail", "github.com", @@ -45,6 +48,7 @@ func TestParseRepo(t *testing.T) { { "https", "github.com", + "", "cdr/sail", "cdr/sail", "github.com", @@ -56,6 +60,7 @@ func TestParseRepo(t *testing.T) { { "https", "github.com", + "", "https://github.com/cdr/sail", "cdr/sail", "github.com", @@ -67,6 +72,7 @@ func TestParseRepo(t *testing.T) { { "ssh", "github.com", + "", "git@github.com/cdr/sail.git", "cdr/sail", "github.com", @@ -78,6 +84,7 @@ func TestParseRepo(t *testing.T) { { "http", "github.com", + "", "ssh://git@github.com/cdr/sail", "cdr/sail", "github.com", @@ -89,6 +96,7 @@ func TestParseRepo(t *testing.T) { { "https", "my.private-git.com", + "", "private/repo", "private/repo", "my.private-git.com", @@ -96,10 +104,22 @@ func TestParseRepo(t *testing.T) { "https", "https://my.private-git.com/private/repo.git", }, + // ensure default organization works as expected + { + "ssh", + "github.com", + "cdr", + "sail", + "cdr/sail", + "github.com", + "git", + "ssh", + "ssh://git@github.com/cdr/sail.git", + }, } for _, test := range tests { - repo, err := parseRepo(test.defSchema, test.defHost, test.fullPath) + repo, err := parseRepo(test.defSchema, test.defHost, test.defOrganization, test.fullPath) require.NoError(t, err) assert.Equal(t, test.expPath, repo.Path, "expected path to be the same") diff --git a/sail_helpers_test.go b/sail_helpers_test.go index 1d60287..b1acea0 100644 --- a/sail_helpers_test.go +++ b/sail_helpers_test.go @@ -43,7 +43,7 @@ func run(t *testing.T, name, repo, hatPath string, fns ...func(t *testing.T, p * conf := mustReadConfig(filepath.Join(metaRoot(), ".sail.toml")) - repo, err := parseRepo("ssh", "github.com", repo) + repo, err := parseRepo("ssh", "github.com", "", repo) require.NoError(t, err) p.proj = &project{ diff --git a/versionmd.go b/versionmd.go index bcc71a2..402788d 100644 --- a/versionmd.go +++ b/versionmd.go @@ -9,7 +9,7 @@ import ( var version string -type versioncmd struct {} +type versioncmd struct{} func (v *versioncmd) Spec() cli.CommandSpec { return cli.CommandSpec{