Example #1
0
// Returns local cloned repositories' root.
// Uses the value of `git config ghq.root` or defaults to ~/.ghq.
func localRepositoryRoots() []string {
	if len(_localRepositoryRoots) != 0 {
		return _localRepositoryRoots
	}

	var err error
	_localRepositoryRoots, err = GitConfigAll("ghq.root")
	utils.PanicIf(err)

	if len(_localRepositoryRoots) == 0 {
		homeDir, err := homedir.Dir()
		utils.PanicIf(err)

		_localRepositoryRoots = []string{filepath.Join(homeDir, ".ghq")}
	}

	for i, v := range _localRepositoryRoots {
		path := filepath.Clean(v)
		if _, err := os.Stat(path); err == nil {
			_localRepositoryRoots[i], err = filepath.EvalSymlinks(path)
			utils.PanicIf(err)
		} else {
			_localRepositoryRoots[i] = path
		}
	}

	return _localRepositoryRoots
}
Example #2
0
func doImportPocket(c *cli.Context) {
	if pocket.ConsumerKey == "" {
		utils.Log("error", "Built without consumer key set")
		return
	}

	accessToken, err := GitConfig("ghq.pocket.token")
	utils.PanicIf(err)

	if accessToken == "" {
		receiverURL, ch, err := pocket.StartAccessTokenReceiver()
		utils.PanicIf(err)

		utils.Log("pocket", "Waiting for Pocket authentication callback at "+receiverURL)

		utils.Log("pocket", "Obtaining request token")
		authRequest, err := pocket.ObtainRequestToken(receiverURL)
		utils.DieIf(err)

		url := pocket.GenerateAuthorizationURL(authRequest.Code, receiverURL)
		utils.Log("open", url)

		<-ch

		utils.Log("pocket", "Obtaining access token")
		authorized, err := pocket.ObtainAccessToken(authRequest.Code)
		utils.DieIf(err)

		utils.Log("authorized", authorized.Username)

		accessToken = authorized.AccessToken
		utils.Run("git", "config", "ghq.pocket.token", authorized.AccessToken)
	}

	utils.Log("pocket", "Retrieving github.com entries")
	res, err := pocket.RetrieveGitHubEntries(accessToken)
	utils.DieIf(err)

	for _, item := range res.List {
		url, err := url.Parse(item.ResolvedURL)
		if err != nil {
			utils.Log("error", fmt.Sprintf("Could not parse URL <%s>: %s", item.ResolvedURL, err))
			continue
		}

		remote, err := NewRemoteRepository(url)
		if utils.ErrorIf(err) {
			continue
		}

		if remote.IsValid() == false {
			utils.Log("skip", fmt.Sprintf("Not a valid repository: %s", url))
			continue
		}

		getRemoteRepository(remote, c.Bool("update"))
	}
}
Example #3
0
func getRemoteRepository(remote RemoteRepository, doUpdate bool) {
	remoteURL := remote.URL()
	local := LocalRepositoryFromURL(remoteURL)

	path := local.FullPath
	newPath := false

	_, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			newPath = true
			err = nil
		}
		utils.PanicIf(err)
	}

	if newPath {
		utils.Log("clone", fmt.Sprintf("%s -> %s", remoteURL, path))
		remote.VCS().Clone(remoteURL, path)
	} else {
		if doUpdate {
			utils.Log("update", path)
			local.VCS().Update(path)
		} else {
			utils.Log("exists", path)
		}
	}
}
Example #4
0
// getRemoteRepository clones or updates a remote repository remote.
// If doUpdate is true, updates the locally cloned repository. Otherwise does nothing.
// If isShallow is true, does shallow cloning. (no effect if already cloned or the VCS is Mercurial)
func getRemoteRepository(remote RemoteRepository, doUpdate bool, isShallow bool) {
	remoteURL := remote.URL()
	local := LocalRepositoryFromURL(remoteURL)

	path := local.FullPath
	newPath := false

	_, err := os.Stat(path)
	if err != nil {
		if os.IsNotExist(err) {
			newPath = true
			err = nil
		}
		utils.PanicIf(err)
	}

	if newPath {
		utils.Log("clone", fmt.Sprintf("%s -> %s", remoteURL, path))

		vcs := remote.VCS()
		if vcs == nil {
			utils.Log("error", fmt.Sprintf("Could not find version control system: %s", remoteURL))
			os.Exit(1)
		}

		vcs.Clone(remoteURL, path, isShallow)
	} else {
		if doUpdate {
			utils.Log("update", path)
			local.VCS().Update(path)
		} else {
			utils.Log("exists", path)
		}
	}
}
Example #5
0
// Returns local cloned repositories' root.
// Uses the value of `git config ghq.root` or defaults to ~/.ghq.
func localRepositoryRoots() []string {
	if len(_localRepositoryRoots) != 0 {
		return _localRepositoryRoots
	}

	var err error
	_localRepositoryRoots, err = GitConfigAll("ghq.root")
	utils.PanicIf(err)

	if len(_localRepositoryRoots) == 0 {
		usr, err := user.Current()
		utils.PanicIf(err)

		_localRepositoryRoots = []string{path.Join(usr.HomeDir, ".ghq")}
	}

	return _localRepositoryRoots
}
Example #6
0
func doLook(c *cli.Context) {
	name := c.Args().First()

	if name == "" {
		cli.ShowCommandHelp(c, "look")
		os.Exit(1)
	}

	reposFound := []*LocalRepository{}
	walkLocalRepositories(func(repo *LocalRepository) {
		if repo.Matches(name) {
			reposFound = append(reposFound, repo)
		}
	})

	switch len(reposFound) {
	case 0:
		utils.Log("error", "No repository found")
		os.Exit(1)

	case 1:
		if runtime.GOOS == "windows" {
			cmd := exec.Command(os.Getenv("COMSPEC"))
			cmd.Stdin = os.Stdin
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			cmd.Dir = reposFound[0].FullPath
			err := cmd.Start()
			if err == nil {
				cmd.Wait()
				os.Exit(0)
			}
		} else {
			shell := os.Getenv("SHELL")
			if shell == "" {
				shell = "/bin/sh"
			}

			utils.Log("cd", reposFound[0].FullPath)
			err := os.Chdir(reposFound[0].FullPath)
			utils.PanicIf(err)

			syscall.Exec(shell, []string{shell}, syscall.Environ())
		}

	default:
		utils.Log("error", "More than one repositories are found; Try more precise name")
		for _, repo := range reposFound {
			utils.Log("error", "- "+strings.Join(repo.PathParts, "/"))
		}
	}
}
Example #7
0
func doGet(c *cli.Context) {
	argURL := c.Args().Get(0)
	category := c.Args().Get(1)
	doUpdate := c.Bool("update")
	isShallow := c.Bool("shallow")

	if argURL == "" {
		cli.ShowCommandHelp(c, "get")
		os.Exit(1)
	}

	url, err := NewURL(argURL)
	utils.DieIf(err)

	isSSH := c.Bool("p")
	if isSSH {
		// Assume Git repository if `-p` is given.
		url, err = ConvertGitURLHTTPToSSH(url)
		utils.DieIf(err)
	}

	remote, err := NewRemoteRepository(url)
	utils.DieIf(err)

	if remote.IsValid() == false {
		utils.Log("error", fmt.Sprintf("Not a valid repository: %s", url))
		os.Exit(1)
	}

	getRemoteRepository(remote, doUpdate, isShallow)

	if category != "" {
		localPath := LocalRepositoryFromURL(remote.URL()).FullPath
		categoryFile := path.Dir(localPath) + "/." + path.Base(localPath)

		if doUpdate {
			utils.Log("overwrite category", fmt.Sprintf("%s as %s", localPath, category))
			ioutil.WriteFile(categoryFile, []byte(category+"\n"), 0644)
		} else {
			_, err := os.Stat(localPath)
			if err != nil {
				utils.PanicIf(err)
			} else {
				utils.Log("new category", fmt.Sprintf("%s as %s", localPath, category))
				ioutil.WriteFile(categoryFile, []byte(category+"\n"), 0644)
			}
		}
	}
}
Example #8
0
func doLook(c *cli.Context) {
	name := c.Args().First()

	if name == "" {
		cli.ShowCommandHelp(c, "look")
		os.Exit(1)
	}

	reposFound := []*LocalRepository{}
	walkLocalRepositories(func(repo *LocalRepository) {
		if repo.Matches(name) {
			reposFound = append(reposFound, repo)
		}
	})

	switch len(reposFound) {
	case 0:
		utils.Log("error", "No repository found")

	case 1:
		shell := os.Getenv("SHELL")
		if shell == "" {
			shell = "/bin/sh"
		}

		utils.Log("cd", reposFound[0].FullPath)
		err := os.Chdir(reposFound[0].FullPath)
		utils.PanicIf(err)

		syscall.Exec(shell, []string{shell}, syscall.Environ())

	default:
		utils.Log("error", "More than one repositories are found; Try more precise name")
		for _, repo := range reposFound {
			utils.Log("error", "- "+strings.Join(repo.PathParts, "/"))
		}
	}
}
Example #9
0
File: git.go Project: iwaim/ghq
func gitVersionOutputSatisfies(gitVersionOutput string, baseVersionParts []uint) bool {
	versionStrings := versionRx.FindStringSubmatch(gitVersionOutput)
	if versionStrings == nil {
		return false
	}

	for i, v := range baseVersionParts {
		thisV64, err := strconv.ParseUint(versionStrings[i+1], 10, 0)
		utils.PanicIf(err)

		thisV := uint(thisV64)

		if thisV > v {
			return true
		} else if v == thisV {
			continue
		} else {
			return false
		}
	}

	return true
}
Example #10
0
func doList(c *cli.Context) {
	query := c.Args().First()
	category := c.Args().First()
	isCategory := c.Bool("category")
	exact := c.Bool("exact")
	printFullPaths := c.Bool("full-path")
	printUniquePaths := c.Bool("unique")

	if isCategory {
		query = ""
	}

	var categoryFn = func(repo *LocalRepository) bool {
		if isCategory && category != "" {
			localPath := repo.FullPath
			categoryFile := path.Dir(localPath) + "/." + path.Base(localPath)
			fp, err := os.Open(categoryFile)

			if err != nil {
				return false
			}
			defer fp.Close()

			scanner := bufio.NewScanner(fp)

			var flg bool
			if scanner.Scan() {
				flg = category == scanner.Text()
			} else {
				flg = false
			}

			if err := scanner.Err(); err != nil {
				utils.PanicIf(err)
			}

			return flg
		}

		return true
	}

	var filterFn func(*LocalRepository) bool
	if query == "" {
		filterFn = func(repo *LocalRepository) bool {
			return true
		}
	} else if exact {
		filterFn = func(repo *LocalRepository) bool {
			return repo.Matches(query)
		}
	} else {
		filterFn = func(repo *LocalRepository) bool {
			return strings.Contains(repo.NonHostPath(), query)
		}
	}

	repos := []*LocalRepository{}

	walkLocalRepositories(func(repo *LocalRepository) {
		if (categoryFn(repo) && filterFn(repo)) == false {
			return
		}

		repos = append(repos, repo)
	})

	if printUniquePaths {
		subpathCount := map[string]int{} // Count duplicated subpaths (ex. foo/dotfiles and bar/dotfiles)
		reposCount := map[string]int{}   // Check duplicated repositories among roots

		// Primary first
		for _, repo := range repos {
			if reposCount[repo.RelPath] == 0 {
				for _, p := range repo.Subpaths() {
					subpathCount[p] = subpathCount[p] + 1
				}
			}

			reposCount[repo.RelPath] = reposCount[repo.RelPath] + 1
		}

		for _, repo := range repos {
			if reposCount[repo.RelPath] > 1 && repo.IsUnderPrimaryRoot() == false {
				continue
			}

			for _, p := range repo.Subpaths() {
				if subpathCount[p] == 1 {
					fmt.Println(p)
					break
				}
			}
		}
	} else {
		for _, repo := range repos {
			if printFullPaths {
				fmt.Println(repo.FullPath)
			} else {
				fmt.Println(repo.RelPath)
			}
		}
	}
}
Example #11
0
func doImportStarred(c *cli.Context) {
	user := c.Args().First()
	doUpdate := c.Bool("update")
	isSSH := c.Bool("p")
	isShallow := c.Bool("shallow")

	if user == "" {
		cli.ShowCommandHelp(c, "starred")
		os.Exit(1)
	}

	githubToken := os.Getenv("GHQ_GITHUB_TOKEN")

	if githubToken == "" {
		var err error
		githubToken, err = GitConfigSingle("ghq.github.token")
		utils.PanicIf(err)
	}

	var client *github.Client

	if githubToken != "" {
		oauthTransport := &oauth.Transport{
			Token: &oauth.Token{AccessToken: githubToken},
		}
		client = github.NewClient(oauthTransport.Client())
	} else {
		client = github.NewClient(nil)
	}

	options := &github.ActivityListStarredOptions{Sort: "created"}

	for page := 1; ; page++ {
		options.Page = page

		repositories, res, err := client.Activity.ListStarred(user, options)
		utils.DieIf(err)

		utils.Log("page", fmt.Sprintf("%d/%d", page, res.LastPage))
		for _, repo := range repositories {
			url, err := url.Parse(*repo.HTMLURL)
			if err != nil {
				utils.Log("error", fmt.Sprintf("Could not parse URL <%s>: %s", repo.HTMLURL, err))
				continue
			}
			if isSSH {
				url, err = ConvertGitURLHTTPToSSH(url)
				if err != nil {
					utils.Log("error", fmt.Sprintf("Could not convert URL <%s>: %s", repo.HTMLURL, err))
					continue
				}
			}

			remote, err := NewRemoteRepository(url)
			if utils.ErrorIf(err) {
				continue
			}

			if remote.IsValid() == false {
				utils.Log("skip", fmt.Sprintf("Not a valid repository: %s", url))
				continue
			}

			getRemoteRepository(remote, doUpdate, isShallow)
		}

		if page >= res.LastPage {
			break
		}
	}
}