Skip to content

Commit 7a32bb7

Browse files
authored
feat: add clone command (#19)
1 parent a63df21 commit 7a32bb7

File tree

5 files changed

+126
-0
lines changed

5 files changed

+126
-0
lines changed

cmds/clone.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package cmds
2+
3+
import (
4+
"github.com/joshmedeski/sesh/connect"
5+
"github.com/joshmedeski/sesh/git"
6+
7+
"github.com/urfave/cli/v2"
8+
)
9+
10+
func Clone() *cli.Command {
11+
return &cli.Command{
12+
Name: "clone",
13+
Aliases: []string{"cl"},
14+
Usage: "Clone a git repo and connect to it as a session",
15+
UseShortOptionHandling: true,
16+
Flags: []cli.Flag{
17+
&cli.StringFlag{
18+
Name: "cmdDir",
19+
Aliases: []string{"d"},
20+
Usage: "The directory to run the git command in",
21+
},
22+
},
23+
Action: func(cCtx *cli.Context) error {
24+
repo := cCtx.Args().First()
25+
dir := cCtx.Args().Get(1)
26+
cmdDir := cCtx.String("cmdDir")
27+
c, err := git.Clone(git.CloneOptions{
28+
Dir: &dir,
29+
CmdDir: &cmdDir,
30+
Repo: repo,
31+
})
32+
if err != nil {
33+
return cli.Exit(err, 1)
34+
}
35+
connect.Connect(c.Path, false, "")
36+
return nil
37+
},
38+
}
39+
}

git/clone.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package git
2+
3+
import (
4+
"os/exec"
5+
"regexp"
6+
"strings"
7+
)
8+
9+
type CloneOptions struct {
10+
Dir *string
11+
CmdDir *string
12+
Repo string
13+
}
14+
15+
type ClonedRepo struct {
16+
Name string
17+
Path string
18+
}
19+
20+
func Clone(o CloneOptions) (ClonedRepo, error) {
21+
cmdArgs := []string{"clone", o.Repo}
22+
if o.Dir != nil && strings.TrimSpace(*o.Dir) != "" {
23+
cmdArgs = append(cmdArgs, *o.Dir)
24+
}
25+
cmd := exec.Command("git", cmdArgs...)
26+
if o.CmdDir != nil && strings.TrimSpace(*o.CmdDir) != "" {
27+
cmd.Dir = *o.CmdDir
28+
}
29+
_, err := cmd.Output()
30+
cmd.Wait()
31+
if err != nil {
32+
return ClonedRepo{}, err
33+
}
34+
name := findRepo(o.Repo)
35+
if o.Dir != nil && strings.TrimSpace(*o.Dir) != "" {
36+
name = *o.Dir
37+
}
38+
path := cmd.Dir + "/" + name
39+
return ClonedRepo{
40+
Name: name,
41+
Path: path,
42+
}, nil
43+
}
44+
45+
func findRepo(repo string) string {
46+
repo = strings.TrimSuffix(repo, ".git")
47+
re := regexp.MustCompile(`([^\/]*)$`)
48+
match := re.FindString(repo)
49+
return match
50+
}

git/clone_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package git
2+
3+
import (
4+
"strings"
5+
"testing"
6+
)
7+
8+
func TestFindRepo(t *testing.T) {
9+
repos := []string{
10+
"https://github.com/username/repository.git",
11+
"[email protected]:username/repository.git",
12+
"https://github.com/username/repository",
13+
"[email protected]:username/repository",
14+
"username/repository",
15+
}
16+
17+
for _, repo := range repos {
18+
result := strings.TrimSpace(findRepo(repo))
19+
if result != "repository" {
20+
t.Errorf("Expected repository for URL %s, got %s instead", repo, result)
21+
}
22+
}
23+
}

git/git.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ import (
66
"strings"
77
)
88

9+
func gitCmd(args []string) ([]byte, error) {
10+
tmux, err := exec.LookPath("git")
11+
if err != nil {
12+
return nil, err
13+
}
14+
cmd := exec.Command(tmux, args...)
15+
output, err := cmd.Output()
16+
if err != nil {
17+
return nil, err
18+
}
19+
return output, nil
20+
}
21+
922
func RootPath(path string) string {
1023
gitRootPathCmd := exec.Command("git", "-C", path, "rev-parse", "--show-toplevel")
1124
gitRootPathByteOutput, err := gitRootPathCmd.CombinedOutput()

seshcli/seshcli.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func App() cli.App {
1717
cmds.List(),
1818
cmds.Choose(),
1919
cmds.Connect(),
20+
cmds.Clone(),
2021
},
2122
}
2223
}

0 commit comments

Comments
 (0)