From c9faf272bdb3eee3653e9f26831d01928f8c35a9 Mon Sep 17 00:00:00 2001 From: dadada Date: Sat, 18 Nov 2023 15:02:17 +0100 Subject: [PATCH] Split up main package into multiple files --- args.go | 44 +++++++++++++++ commit.go | 54 ++++++++++++++++++ download.go | 38 +++++++++++++ main.go | 156 +--------------------------------------------------- remote.go | 54 ++++++++++++++++++ 5 files changed, 192 insertions(+), 154 deletions(-) create mode 100644 args.go create mode 100644 commit.go create mode 100644 download.go create mode 100644 remote.go diff --git a/args.go b/args.go new file mode 100644 index 0000000..83a84fe --- /dev/null +++ b/args.go @@ -0,0 +1,44 @@ +package main + +import ( + "flag" + "log" + "os" +) + +func getArgs() (*string, *bool, *string, *string, *string) { + cwd, err := os.Getwd() + if err != nil { + log.Fatalf("Failed to get working directory %s", err) + } + + gitdir := flag.String( + "C", + cwd, + "The directory containing the git repository in which to archive the pads.", + ) + doPush := flag.Bool( + "push", + false, + "Push the changes to the remote specified by remoteUrl.", + ) + username := flag.String( + "username", + "", + "The username for authenticating to the remote.", + ) + password := flag.String( + "password", + os.Getenv("GIT_PASSWORD"), + "The password for authenticating to the remote. Can also be specified via the environment variable GIT_PASSWORD.", + ) + remoteUrl := flag.String( + "url", + "", + "URL to push changes to.", + ) + + flag.Parse() + + return gitdir, doPush, username, password, remoteUrl +} diff --git a/commit.go b/commit.go new file mode 100644 index 0000000..7e65c60 --- /dev/null +++ b/commit.go @@ -0,0 +1,54 @@ +package main + +import ( + "fmt" + "sync" + "time" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/object" +) + +var cm sync.Mutex + +func commit( + tree *git.Worktree, + padfile string, + url string, +) (plumbing.Hash, error) { + cm.Lock() + defer cm.Unlock() + + if _, err := tree.Add(padfile); err != nil { + return plumbing.ZeroHash, fmt.Errorf("Failed to stage %s: %w", padfile, err) + } + + status, err := tree.Status() + if err != nil { + return plumbing.ZeroHash, fmt.Errorf("Failed to get status of %s", padfile) + } + + fileStatus := status.File(padfile) + if fileStatus.Staging != git.Added && fileStatus.Staging != git.Modified { + return plumbing.ZeroHash, nothingToDo + } + + commit, err := tree.Commit( + fmt.Sprintf("Updated %s from %s", padfile, url), + &git.CommitOptions{ + All: false, + Author: &object.Signature{ + Name: "Pad Archiver[bot]", + Email: "dadada+pad-archiver@dadada.li@", + When: time.Now(), + }, + }, + ) + + if err != nil { + return plumbing.ZeroHash, fmt.Errorf("Failed to commit %s: %w", padfile, err) + } + + return commit, nil +} diff --git a/download.go b/download.go new file mode 100644 index 0000000..6b9709b --- /dev/null +++ b/download.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "io" + "net/http" + "os" + "path" + "path/filepath" +) + +func download( + gitdir string, + url string, +) (string, error) { + res, err := http.Get(url + "/export/txt") + if err != nil { + return "", fmt.Errorf("Failed to get pad at %s: %w", url, err) + } + + defer res.Body.Close() + + padfile := path.Base(url) + ".txt" + + padpath := filepath.Join(gitdir, padfile) + out, err := os.Create(padpath) + + written, err := io.Copy(out, res.Body) + if err != nil { + return "", fmt.Errorf("Failed to write pad to file at %s: %w", padfile, err) + } + + if written < 100 { + return "", fmt.Errorf("Skipping update of %s, because pad has likely been removed from %s", padfile, url) + } + + return padfile, nil +} diff --git a/main.go b/main.go index 74c4efd..6bf36ce 100644 --- a/main.go +++ b/main.go @@ -4,21 +4,12 @@ import ( "bufio" "crypto/tls" "errors" - "flag" - "fmt" - "io" "log" "net/http" "os" - "path" - "path/filepath" "sync" - "time" "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/object" githttp "github.com/go-git/go-git/v5/plumbing/transport/http" ) @@ -30,142 +21,10 @@ var ( nothingToDo = errors.New("Nothing to do for unmodified file") ) -var cm sync.Mutex - -func commit( - tree *git.Worktree, - padfile string, - url string, -) (plumbing.Hash, error) { - cm.Lock() - defer cm.Unlock() - - if _, err := tree.Add(padfile); err != nil { - return plumbing.ZeroHash, fmt.Errorf("Failed to stage %s: %w", padfile, err) - } - - status, err := tree.Status() - if err != nil { - return plumbing.ZeroHash, fmt.Errorf("Failed to get status of %s", padfile) - } - - fileStatus := status.File(padfile) - if fileStatus.Staging != git.Added && fileStatus.Staging != git.Modified { - return plumbing.ZeroHash, nothingToDo - } - - commit, err := tree.Commit( - fmt.Sprintf("Updated %s from %s", padfile, url), - &git.CommitOptions{ - All: false, - Author: &object.Signature{ - Name: "Pad Archiver[bot]", - Email: "dadada+pad-archiver@dadada.li@", - When: time.Now(), - }, - }, - ) - - if err != nil { - return plumbing.ZeroHash, fmt.Errorf("Failed to commit %s: %w", padfile, err) - } - - return commit, nil -} - -func download( - gitdir string, - url string, -) (string, error) { - res, err := http.Get(url + "/export/txt") - if err != nil { - return "", fmt.Errorf("Failed to get pad at %s: %w", url, err) - } - - defer res.Body.Close() - - padfile := path.Base(url) + ".txt" - - padpath := filepath.Join(gitdir, padfile) - out, err := os.Create(padpath) - - written, err := io.Copy(out, res.Body) - if err != nil { - return "", fmt.Errorf("Failed to write pad to file at %s: %w", padfile, err) - } - - if written < 100 { - return "", fmt.Errorf("Skipping update of %s, because pad has likely been removed from %s", padfile, url) - } - - return padfile, nil -} - -func createRemote( - repo *git.Repository, - remote string, - url string, -) (*git.Remote, error) { - newRemote, err := repo.Remote(remote) - if err != nil { - log.Printf("Creating new git remote %s with URL %s", remote, url) - return repo.CreateRemote(&config.RemoteConfig{ - Name: remote, - URLs: []string{url}, - }) - } else { - log.Printf("Using remote %s with URL %s", remote, url) - } - - return newRemote, nil -} - -func push( - auth *githttp.BasicAuth, - r *git.Repository, - remote string, -) error { - return r.Push(&git.PushOptions{ - RemoteName: remote, - Auth: auth, - }) -} - func main() { http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - cwd, err := os.Getwd() - if err != nil { - log.Fatalf("Failed to get working directory %s", err) - } - - gitdir := flag.String( - "C", - cwd, - "The directory containing the git repository in which to archive the pads.", - ) - doPush := flag.Bool( - "push", - false, - "Push the changes to the remote specified by remoteUrl.", - ) - username := flag.String( - "username", - "", - "The username for authenticating to the remote.", - ) - password := flag.String( - "password", - os.Getenv("GIT_PASSWORD"), - "The password for authenticating to the remote. Can also be specified via the environment variable GIT_PASSWORD.", - ) - remoteUrl := flag.String( - "url", - "", - "URL to push changes to.", - ) - - flag.Parse() + gitdir, doPush, username, password, remoteUrl := getArgs() repo, err := git.PlainOpen(*gitdir) if err != nil { @@ -215,17 +74,6 @@ func main() { } if *doPush == true { - if _, err := createRemote(repo, defaultRemoteName, *remoteUrl); err != nil { - log.Fatalf("%s", err) - } - if err := push(auth, repo, defaultRemoteName); err != nil { - if err == git.NoErrAlreadyUpToDate { - log.Println("Already up-to-date") - } else { - log.Fatalf("%s", err) - } - } else { - log.Println("Pushed changes to remote") - } + pushRepo(repo, remoteUrl, auth) } } diff --git a/remote.go b/remote.go new file mode 100644 index 0000000..6f39e25 --- /dev/null +++ b/remote.go @@ -0,0 +1,54 @@ +package main + +import ( + "log" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/config" + githttp "github.com/go-git/go-git/v5/plumbing/transport/http" +) + +func pushRepo(repo *git.Repository, remoteUrl *string, auth *githttp.BasicAuth) { + if _, err := createRemote(repo, defaultRemoteName, *remoteUrl); err != nil { + log.Fatalf("%s", err) + } + if err := push(auth, repo, defaultRemoteName); err != nil { + if err == git.NoErrAlreadyUpToDate { + log.Println("Already up-to-date") + } else { + log.Fatalf("%s", err) + } + } else { + log.Println("Pushed changes to remote") + } +} + +func createRemote( + repo *git.Repository, + remote string, + url string, +) (*git.Remote, error) { + newRemote, err := repo.Remote(remote) + if err != nil { + log.Printf("Creating new git remote %s with URL %s", remote, url) + return repo.CreateRemote(&config.RemoteConfig{ + Name: remote, + URLs: []string{url}, + }) + } else { + log.Printf("Using remote %s with URL %s", remote, url) + } + + return newRemote, nil +} + +func push( + auth *githttp.BasicAuth, + r *git.Repository, + remote string, +) error { + return r.Push(&git.PushOptions{ + RemoteName: remote, + Auth: auth, + }) +}