Skip to content
This repository was archived by the owner on Apr 28, 2020. It is now read-only.

Commit aa11bec

Browse files
authored
Merge pull request #198 from cdr/specify-folder
Allow repos as filepaths in sail run
2 parents 93844eb + 31d406f commit aa11bec

File tree

2 files changed

+80
-9
lines changed

2 files changed

+80
-9
lines changed

globalflags.go

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@ package main
22

33
import (
44
"flag"
5+
"net/url"
6+
"os"
57
"os/exec"
8+
"os/user"
9+
"path/filepath"
10+
"strings"
611

712
"github.com/fatih/color"
13+
"golang.org/x/xerrors"
814

915
"go.coder.com/flog"
1016
)
@@ -39,18 +45,84 @@ func (gf *globalFlags) ensureDockerDaemon() {
3945
}
4046

4147
func requireRepo(conf config, prefs schemaPrefs, fl *flag.FlagSet) repo {
42-
repoURI := fl.Arg(0)
48+
var (
49+
repoURI = strings.Join(fl.Args(), "/")
50+
r repo
51+
err error
52+
)
53+
4354
if repoURI == "" {
4455
flog.Fatal("Argument <repo> must be provided.")
4556
}
4657

47-
r, err := parseRepo(defaultSchema(conf, prefs), conf.DefaultHost, conf.DefaultOrganization, repoURI)
58+
// if this returns a non-empty string know it's pointing to a valid project on disk
59+
// an error indicates an existing path outside of the project dir
60+
repoName, err := pathIsRunnable(conf, repoURI)
4861
if err != nil {
49-
flog.Fatal("failed to parse repo %q: %v", repoURI, err)
62+
flog.Fatal(err.Error())
63+
}
64+
65+
if repoName != "" {
66+
// we only need the path since the repo exists on disk.
67+
// there's not currently way for us to figure out the host anyways
68+
r = repo{URL: &url.URL{Path: repoName}}
69+
} else {
70+
r, err = parseRepo(defaultSchema(conf, prefs), conf.DefaultHost, conf.DefaultOrganization, repoURI)
71+
if err != nil {
72+
flog.Fatal("failed to parse repo %q: %v", repoURI, err)
73+
}
5074
}
75+
76+
// check if path is pointing to a subdirectory
77+
if sp := strings.Split(r.Path, "/"); len(sp) > 2 {
78+
r.Path = strings.Join(sp[:2], "/")
79+
r.subdir = strings.Join(sp[2:], "/")
80+
}
81+
5182
return r
5283
}
5384

85+
// pathIsRunnable returns the container name if the given path exists and is
86+
// in the projects directory, else an empty string. An error is returned if
87+
// and only if the path exists but it isn't in the user's project directory.
88+
func pathIsRunnable(conf config, path string) (cnt string, _ error) {
89+
fp, err := filepath.Abs(path)
90+
if err != nil {
91+
return
92+
}
93+
94+
s, err := os.Stat(fp)
95+
if err != nil {
96+
return
97+
}
98+
99+
if !s.IsDir() {
100+
return
101+
}
102+
103+
pre := expandRoot(conf.ProjectRoot)
104+
if pre[len(pre)-1] != '/' {
105+
pre = pre + "/"
106+
}
107+
108+
// path exists but doesn't belong to projects directory, return error
109+
if !strings.HasPrefix(fp, pre[:len(pre)-1]) {
110+
return "", xerrors.Errorf("directory %s exists but isn't in projects directory", fp)
111+
}
112+
113+
split := strings.Split(fp, "/")
114+
if len(split) < 2 {
115+
return
116+
}
117+
118+
return strings.TrimPrefix(fp, pre), nil
119+
}
120+
121+
func expandRoot(path string) string {
122+
u, _ := user.Current()
123+
return strings.Replace(path, "~/", u.HomeDir+"/", 1)
124+
}
125+
54126
func defaultSchema(conf config, prefs schemaPrefs) string {
55127
switch {
56128
case prefs.ssh:

repo.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
type repo struct {
1818
*url.URL
19+
subdir string
1920
}
2021

2122
func (r repo) CloneURI() string {
@@ -27,9 +28,7 @@ func (r repo) CloneURI() string {
2728
}
2829

2930
func (r repo) DockerName() string {
30-
return toDockerName(
31-
r.trimPath(),
32-
)
31+
return toDockerName(r.trimPath())
3332
}
3433

3534
func (r repo) trimPath() string {
@@ -50,7 +49,7 @@ func parseRepo(defaultSchema, defaultHost, defaultOrganization, name string) (re
5049
return repo{}, xerrors.Errorf("failed to parse repo path: %w", err)
5150
}
5251

53-
r := repo{u}
52+
r := repo{URL: u}
5453

5554
if r.Scheme == "" {
5655
r.Scheme = defaultSchema
@@ -79,8 +78,8 @@ func parseRepo(defaultSchema, defaultHost, defaultOrganization, name string) (re
7978
// make sure the path doesn't have a trailing .git
8079
r.Path = strings.TrimSuffix(r.Path, ".git")
8180

82-
// non-existent or invalid path
83-
if r.Path == "" || len(strings.Split(r.Path, "/")) != 2 {
81+
// non-existent
82+
if r.Path == "" {
8483
return repo{}, xerrors.Errorf("invalid repo: %s", r.Path)
8584
}
8685

0 commit comments

Comments
 (0)