aboutsummaryrefslogtreecommitdiff
path: root/repo.go
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2017-05-02 21:22:20 +0200
committerStefan Majewsky <majewsky@gmx.net>2017-05-02 21:22:20 +0200
commit72733e8203654cd26464c8c5a6c955b025102cca (patch)
tree4a8c312fb25dcf79f2cd61b88b7f2ff6baf8d996 /repo.go
parent6b382c55ed7885857a6232a0c8b086ab1f64985e (diff)
downloadgofu-72733e8203654cd26464c8c5a6c955b025102cca.tar.gz
restructure rtree into gofu (with rtree as the first applet)
Diffstat (limited to 'repo.go')
-rw-r--r--repo.go196
1 files changed, 0 insertions, 196 deletions
diff --git a/repo.go b/repo.go
deleted file mode 100644
index 532b5d1..0000000
--- a/repo.go
+++ /dev/null
@@ -1,196 +0,0 @@
-/*******************************************************************************
-*
-* Copyright 2017 Stefan Majewsky <majewsky@gmx.net>
-*
-* This program is free software: you can redistribute it and/or modify it under
-* the terms of the GNU General Public License as published by the Free Software
-* Foundation, either version 3 of the License, or (at your option) any later
-* version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT ANY
-* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along with
-* this program. If not, see <http://www.gnu.org/licenses/>.
-*
-*******************************************************************************/
-
-package main
-
-import (
- "bytes"
- "errors"
- "fmt"
- "os"
- "os/exec"
- "path/filepath"
- "regexp"
- "strings"
-)
-
-//RootPath is the directory below which all repositories are located. Its value
-//is $GOPATH/src to match the repository layout created by `go get`.
-var RootPath string
-
-func init() {
- gopath := os.Getenv("GOPATH")
- if gopath == "" {
- FatalIfError(errors.New("$GOPATH is not set (rtree needs the GOPATH variable to know where to look for and place repos)"))
- }
- RootPath = filepath.Join(gopath, "src")
-}
-
-//Repo describes the entry for a repository in the index file.
-type Repo struct {
- //CheckoutPath shall be relative to the RootPath.
- CheckoutPath string `yaml:"path"`
- //Remotes maps remote names (as noted in the .git/config of the repo) to
- //remote URLs (as they appear in the .git/config of the repo, i.e. possibly
- //abbreviated).
- Remotes []Remote `yaml:"remotes"`
-}
-
-//Remote describes a remote that is configured in a Repo.
-type Remote struct {
- Name string `yaml:"name"`
- URL string `yaml:"url"`
-}
-
-//AbsolutePath returns the absolute CheckoutPath of this repo.
-func (r Repo) AbsolutePath() string {
- return filepath.Join(RootPath, r.CheckoutPath)
-}
-
-//NewRepoFromAbsolutePath initializes a Repo instance by scanning the existing
-//checkout at the given path.
-func NewRepoFromAbsolutePath(path string) (repo Repo, err error) {
- repo.CheckoutPath, err = filepath.Rel(RootPath, path)
- if err != nil {
- return
- }
-
- //list remotes
- cmd := exec.Command("git", "-C", path, "config", "-l")
- var buf bytes.Buffer
- cmd.Stdout = &buf
- cmd.Stderr = os.Stderr
- err = cmd.Run()
- if err != nil {
- return repo, fmt.Errorf("exec `git config -l` in %s: %s", path, err.Error())
- }
-
- for _, line := range strings.Split(string(buf.Bytes()), "\n") {
- match := remoteConfigRx.FindStringSubmatch(line)
- if match == nil {
- continue
- }
- repo.Remotes = append(repo.Remotes, Remote{
- Name: match[1],
- URL: match[2],
- })
- }
- return
-}
-
-var remoteConfigRx = regexp.MustCompile(`remote\.([^=]+)\.url=(.+)`)
-
-//ForeachPhysicalRepo walks over the repository tree, executing the action
-//function once for every repo encountered (but *not* for repos contained
-//within other repos, e.g. submodules).
-func ForeachPhysicalRepo(action func(repo Repo) error) error {
- return filepath.Walk(RootPath, func(path string, info os.FileInfo, err error) error {
- if err != nil {
- return err
- }
- //look for repos, i.e. directories containing a .git directory
- if !info.IsDir() {
- return nil
- }
- _, err = os.Stat(filepath.Join(path, ".git"))
- if err != nil {
- return nil
- }
-
- //appears to be a repo
- repo, err := NewRepoFromAbsolutePath(path)
- if err == nil {
- err = action(repo)
- }
- if err != nil {
- return err
- }
- //do not traverse further down into submodules etc.
- return filepath.SkipDir
- })
-}
-
-//Checkout creates the repo in the given path with the given remotes. The
-//working copy will only be initialized if there is an "origin" remote.
-func (r Repo) Checkout() error {
- //check if we have an "origin" remote to clone from
- var originURL string
- for _, remote := range r.Remotes {
- if remote.Name == "origin" {
- originURL = remote.URL
- break
- }
- }
-
- if originURL == "" {
- cmd := exec.Command("git", "init", r.AbsolutePath())
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- err := cmd.Run()
- if err != nil {
- return err
- }
- fmt.Fprintln(os.Stderr, "warning: will not checkout anything since there is no remote named \"origin\"")
- } else {
- cmd := exec.Command("git", "clone", originURL, r.AbsolutePath())
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- err := cmd.Run()
- if err != nil {
- return err
- }
- }
-
- remotesAdded := false
- for _, remote := range r.Remotes {
- if remote.Name != "origin" {
- cmd := exec.Command("git", "-C", r.AbsolutePath(), "remote", "add", remote.Name, remote.URL)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- err := cmd.Run()
- if err != nil {
- return err
- }
- remotesAdded = true
- }
- }
- if remotesAdded {
- cmd := exec.Command("git", "-C", r.AbsolutePath(), "remote", "update")
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- return cmd.Run()
- }
-
- return nil
-}
-
-//InteractiveExec implements the meat of the `rtree exec` command. It returns
-//true iff the command exited successfully.
-func (r Repo) InteractiveExec(command string, args ...string) (ok bool) {
- fmt.Fprintf(os.Stdout, "\x1B[1;36m>> \x1B[0;36m%s\x1B[0m\n", r.AbsolutePath())
- cmd := exec.Command(command, args...)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.Dir = r.AbsolutePath()
- err := cmd.Run()
- if err != nil {
- fmt.Fprintf(os.Stderr, "\x1B[1;31m!! \x1B[0;31m%s\x1B[0m\n", err.Error())
- return false
- }
- return true
-}