git-lfs/commands/command_lock.go
risk danger olson a12cdc889f RegisterCommand() can no longer disable commands
the config is available at init(), so isCommandEnabled() checks can be
pulled out of the RegisterCommand() callback, simplifying its signature.
2016-09-01 10:09:38 -06:00

113 lines
2.5 KiB
Go

package commands
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/github/git-lfs/api"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/git"
"github.com/spf13/cobra"
)
var (
lockRemote string
lockRemoteHelp = "specify which remote to use when interacting with locks"
// TODO(taylor): consider making this (and the above flag) a property of
// some parent-command, or another similarly less ugly way of handling
// this
setLockRemoteFor = func(c *config.Configuration) {
c.CurrentRemote = lockRemote
}
)
func lockCommand(cmd *cobra.Command, args []string) {
setLockRemoteFor(cfg)
if len(args) == 0 {
Print("Usage: git lfs lock <path>")
return
}
latest, err := git.CurrentRemoteRef()
if err != nil {
Error(err.Error())
Exit("Unable to determine lastest remote ref for branch.")
}
path, err := lockPath(args[0])
if err != nil {
Exit(err.Error())
}
s, resp := API.Locks.Lock(&api.LockRequest{
Path: path,
Committer: api.CurrentCommitter(),
LatestRemoteCommit: latest.Sha,
})
if _, err := API.Do(s); err != nil {
Error(err.Error())
Exit("Error communicating with LFS API.")
}
if len(resp.Err) > 0 {
Error(resp.Err)
Exit("Server unable to create lock.")
}
Print("\n'%s' was locked (%s)", args[0], resp.Lock.Id)
}
// lockPaths relativizes the given filepath such that it is relative to the root
// path of the repository it is contained within, taking into account the
// working directory of the caller.
//
// If the root directory, working directory, or file cannot be
// determined/opened, an error will be returned. If the file in question is
// actually a directory, an error will be returned. Otherwise, the cleaned path
// will be returned.
//
// For example:
// - Working directory: /code/foo/bar/
// - Repository root: /code/foo/
// - File to lock: ./baz
// - Resolved path bar/baz
func lockPath(file string) (string, error) {
repo, err := git.RootDir()
if err != nil {
return "", err
}
wd, err := os.Getwd()
if err != nil {
return "", err
}
abs := filepath.Join(wd, file)
path := strings.TrimPrefix(abs, repo)
if stat, err := os.Stat(abs); err != nil {
return "", err
} else {
if stat.IsDir() {
return "", fmt.Errorf("lfs: cannot lock directory: %s", file)
}
return path[1:], nil
}
}
func init() {
if !isCommandEnabled(cfg, "locks") {
return
}
RegisterCommand("lock", lockCommand, func(cmd *cobra.Command) {
cmd.Flags().StringVarP(&lockRemote, "remote", "r", cfg.CurrentRemote, lockRemoteHelp)
})
}