Skip to content

Commit b96d4c2

Browse files
committed
Initial go implementation of 'init'
1 parent 81810a0 commit b96d4c2

File tree

10 files changed

+183
-15
lines changed

10 files changed

+183
-15
lines changed

.gitignore

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1 @@
1-
# Binaries for programs and plugins
2-
*.exe
3-
*.exe~
4-
*.dll
5-
*.so
6-
*.dylib
7-
8-
# Test binary, built with `go test -c`
9-
*.test
10-
11-
# Output of the go coverage tool, specifically when used with LiteIDE
12-
*.out
13-
14-
# Dependency directories (remove the comment below to include it)
15-
# vendor/
1+
/git-bundle-server

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ By running this software, you can self-host a bundle server to work with Git's
55

66
[bundle-uris]: https://github.com/git/git/blob/next/Documentation/technical/bundle-uri.txt
77

8+
## Cloning and Building
9+
10+
Be sure to clone inside the `src` directory of your `GOROOT`.
11+
12+
Once there, you can build the `git-bundle-server` executable with
13+
14+
```ShellSession
15+
$ go build git-bundle-server/cmd/git-bundle-server
16+
```
17+
818
## Bundle Management through CLI
919

1020
The following command-line interface allows you to manage which repositories are

cmd/git-bundle-server/init.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"git-bundle-server/internal/git"
7+
"log"
8+
"os"
9+
"time"
10+
)
11+
12+
type Init struct{}
13+
14+
func (Init) subcommand() string {
15+
return "init"
16+
}
17+
18+
func (Init) run(args []string) error {
19+
if len(args) < 2 {
20+
// TODO: allow parsing <route> out of <url>
21+
return errors.New("usage: git-bundle-server init <url> <route>")
22+
}
23+
24+
url := args[0]
25+
route := args[1]
26+
27+
repo := reporoot() + route
28+
web := webroot() + route
29+
30+
mkdirErr := os.MkdirAll(web, os.ModePerm)
31+
if mkdirErr != nil {
32+
log.Fatal("Failed to create web directory: ", mkdirErr)
33+
}
34+
35+
fmt.Printf("Cloning repository from %s\n", url)
36+
gitErr := git.GitCommand("clone", "--mirror", url, repo)
37+
38+
if gitErr != nil {
39+
return gitErr
40+
}
41+
42+
timestamp := time.Now().UTC().Unix()
43+
bundleFile := web + "/bundle-" + fmt.Sprint(timestamp) + ".bundle"
44+
fmt.Printf("Constructing base bundle file at %s\n", bundleFile)
45+
46+
gitErr = git.GitCommand("-C", repo, "bundle", "create", bundleFile, "--all")
47+
if gitErr != nil {
48+
return gitErr
49+
}
50+
51+
return nil
52+
}

cmd/git-bundle-server/main.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"os"
6+
)
7+
8+
func main() {
9+
cmds := all()
10+
11+
if len(os.Args) < 2 {
12+
log.Fatal("usage: git-bundle-server <command> [<options>]\n")
13+
return
14+
}
15+
16+
for i := 0; i < len(cmds); i++ {
17+
if cmds[i].subcommand() == os.Args[1] {
18+
err := cmds[i].run(os.Args[2:])
19+
if err != nil {
20+
log.Fatal("Failed with error: ", err)
21+
}
22+
}
23+
}
24+
}

cmd/git-bundle-server/subcommand.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package main
2+
3+
import (
4+
"os"
5+
)
6+
7+
type Subcommand interface {
8+
subcommand() string
9+
run(args []string) error
10+
}
11+
12+
func all() []Subcommand {
13+
return []Subcommand{
14+
Init{},
15+
}
16+
}
17+
18+
func bundleroot() string {
19+
dirname, err := os.UserHomeDir()
20+
if err != nil {
21+
// TODO: respond better. For now, try creating in "/var"
22+
dirname = "/var"
23+
}
24+
25+
return dirname + "/git-bundle-server/"
26+
}
27+
28+
func webroot() string {
29+
return bundleroot() + "www/"
30+
}
31+
32+
func reporoot() string {
33+
return bundleroot() + "git/"
34+
}

cmd/git-bundle-server/update.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
type Update struct{}
8+
9+
func (Update) subcommand() string {
10+
return "update"
11+
}
12+
13+
func (Update) run(args []string) error {
14+
fmt.Printf("Found Update method!\n")
15+
16+
for _, arg := range args {
17+
fmt.Printf("%s\n", arg)
18+
}
19+
20+
return nil
21+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module git-bundle-server
2+
3+
go 1.18

internal/bundles/bundles.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package bundles
2+
3+
import "fmt"
4+
5+
func BundleList() {
6+
fmt.Printf("called bundleList\n")
7+
fmt.Printf("\n");
8+
}

internal/bundles/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/github/git-bundle-server/internal/bundles
2+
3+
go 1.18

internal/git/git.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package git
2+
3+
import (
4+
"log"
5+
"os/exec"
6+
)
7+
8+
func GitCommand(args ...string) error {
9+
git, lookErr := exec.LookPath("git")
10+
11+
if lookErr != nil {
12+
return lookErr
13+
}
14+
15+
cmd := exec.Command(git, args...)
16+
err := cmd.Start()
17+
if err != nil {
18+
log.Fatal("Git command failed to start: ", err)
19+
}
20+
21+
err = cmd.Wait()
22+
if err != nil {
23+
log.Fatal("Git command returned a failure: ", err)
24+
}
25+
26+
return err
27+
}

0 commit comments

Comments
 (0)