Skip to content

Commit

Permalink
Implement add command and refactor some other files and tests
Browse files Browse the repository at this point in the history
Signed-off-by: Valentin Kiselev <[email protected]>
  • Loading branch information
mrexox committed Jun 9, 2022
1 parent 9ec226c commit 5878866
Show file tree
Hide file tree
Showing 16 changed files with 391 additions and 177 deletions.
2 changes: 2 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ linters:
- unused
- varcheck
- whitespace
- godot
- godox
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ build:
test:
go test -count=1 -timeout=30s -race ./...

bench:
go test -run=Bench -bench=. ./...

bin/golangci-lint:
@test -x $$(go env GOPATH)/bin/golangci-lint || \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.44.0
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin v1.43.0

lint: bin/golangci-lint
$$(go env GOPATH)/bin/golangci-lint run
56 changes: 25 additions & 31 deletions pkg/cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,39 @@ import (
"github.com/evilmartians/lefthook/pkg/lefthook"
)

var createDirs bool

var longAddCmd = heredoc.Doc(`
This command will try to build the following structure in repository:
├───.git
│ └───hooks
│ └───pre-commit // this executable will be added. Existed file with
│ // same name will be renamed to pre-commit.old
(lefthook add this dirs if you run command with -d option)
├───.lefthook // directory for project level hooks
│ └───pre-commit // directory with hooks executables
├───.lefthook-local // directory for personal hooks add it in .gitignore
│ └───pre-commit
`)

func NewAddCmd(opts *lefthook.Options) *cobra.Command {
args := lefthook.AddArgs{}

addCmd := cobra.Command{
Use: "add",
Use: "add hook-name",
Short: "This command add a hook directory to a repository",
Long: longAddCmd,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return addExecutor(args, opts)
Long: heredoc.Doc(`
This command will try to build the following structure in repository:
├───.git
│ └───hooks
│ └───pre-commit // this executable will be added. Existed file with
│ // same name will be renamed to pre-commit.old
(lefthook add this dirs if you run command with -d option)
├───.lefthook // directory for project level hooks
│ └───pre-commit // directory with hooks executables
├───.lefthook-local // directory for personal hooks add it in .gitignore
│ └───pre-commit
`),
Example: "lefthook add pre-commit",
Args: cobra.MinimumNArgs(1),
RunE: func(_cmd *cobra.Command, hooks []string) error {
args.Hook = hooks[0]
return lefthook.Add(opts, &args)
},
}

addCmd.Flags().BoolVarP(
&createDirs, "dirs", "d", false, "create directory for scripts",
&args.CreateDirs, "dirs", "d", false, "create directory for scripts",
)
addCmd.Flags().BoolVarP(
&args.Force, "force", "f", false, "overwrite .old hooks",
)

return &addCmd
}

func addExecutor(args []string, opts *lefthook.Options) error {
// addHook
// if createDirs
// addProjectHookDir
// addLocalHookDir

return nil
}
1 change: 0 additions & 1 deletion pkg/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ func NewRootCmd() *cobra.Command {
&options.NoColors, "no-colors", false, "disable colored output",
)

// TODO: Drop deprecated options
rootCmd.Flags().BoolVarP(
&options.Force, "force", "f", false,
"DEPRECATED: reinstall hooks without checking config version",
Expand Down
11 changes: 9 additions & 2 deletions pkg/config/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import (
"github.com/spf13/viper"
)

// Loads configs from the given directory with extensions
const (
DefaultSourceDir = ".lefthook"
DefaultSourceDirLocal = ".lefthook-local"
)

// Loads configs from the given directory with extensions.
func Load(fs afero.Fs, path string) (*Config, error) {
global, err := read(fs, path, "lefthook")
if err != nil {
Expand All @@ -23,6 +28,8 @@ func Load(fs afero.Fs, path string) (*Config, error) {
var config Config

config.Colors = true // by default colors are enabled
config.SourceDir = DefaultSourceDir
config.SourceDirLocal = DefaultSourceDirLocal

err = unmarshalConfigs(global, extends, &config)
if err != nil {
Expand Down Expand Up @@ -50,7 +57,7 @@ func read(fs afero.Fs, path string, name string) (*viper.Viper, error) {
return v, nil
}

// Merges extends from .lefthook and .lefthook-local
// Merges extends from .lefthook and .lefthook-local.
func mergeAllExtends(fs afero.Fs, path string) (*viper.Viper, error) {
extends, err := read(fs, path, "lefthook")
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion pkg/config/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ post-commit:
run: curl -x POST status.com/done
`),
result: &Config{
Colors: true, // defaults to true
SourceDir: DefaultSourceDir,
SourceDirLocal: DefaultSourceDirLocal,
Colors: true, // defaults to true
Hooks: map[string]*Hook{
"pre-commit": {
Glob: "",
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/script.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func unmarshalScripts(s map[string]interface{}) (map[string]*Script, error) {
// runner: bash
//
// This is not an expected behavior and cannot be controlled yet
// Working with GetStringMap is the only way to get the structure "as is"
// Working with GetStringMap is the only way to get the structure "as is".
func unmarshal(input, output interface{}) error {
if err := mapstructure.WeakDecode(input, &output); err != nil {
return err
Expand Down
1 change: 0 additions & 1 deletion pkg/git/git2go.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
git2go "github.com/libgit2/git2go/v33"
)

// Git2GoRepository is a realization of Repository interface with bindings to libgit2
type Git2GoRepository struct {
repo *git2go.Repository
}
Expand Down
29 changes: 20 additions & 9 deletions pkg/git/repository.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
package git

// Repository is an interface to work with git repo.
// It's realization might change
type Repository interface {
HooksPath() (string, error)
RootPath() string
GitPath() string
OperationInProgress() bool
type Repository struct {
HooksPath string
RootPath string
GitPath string
}

func NewRepository() (Repository, error) {
return NewGit2GoRepository()
func NewRepository() (*Repository, error) {
repo, err := NewGit2GoRepository()
if err != nil {
return nil, err
}

hooksPath, err := repo.HooksPath()
if err != nil {
return nil, err
}

return &Repository{
HooksPath: hooksPath,
RootPath: repo.RootPath(),
GitPath: repo.GitPath(),
}, nil
}
73 changes: 73 additions & 0 deletions pkg/lefthook/add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package lefthook

import (
"fmt"
"path/filepath"

"github.com/evilmartians/lefthook/pkg/config"
)

type AddArgs struct {
Hook string

CreateDirs, Force bool
}

func Add(opts *Options, args *AddArgs) error {
lefthook, err := initialize(opts)
if err != nil {
return err
}

return lefthook.Add(args)
}

// Creates a hook, given in args. The hook is a Lefthook hook.
func (l *Lefthook) Add(args *AddArgs) error {
if !config.HookAvailable(args.Hook) {
return fmt.Errorf("Skip adding, hook is unavailable: %s", args.Hook)
}

err := l.cleanHook(args.Hook, args.Force || l.Options.Force)
if err != nil {
return err
}

err = l.addHook(args.Hook, "")
if err != nil {
return err
}

if args.CreateDirs {
global, local := l.getSourceDirs()

sourceDir := filepath.Join(l.repo.RootPath, global, args.Hook)
sourceDirLocal := filepath.Join(l.repo.RootPath, local, args.Hook)
println("HI", sourceDir, sourceDirLocal)
if err = l.Fs.MkdirAll(sourceDir, 0755); err != nil {
return err
}
if err = l.Fs.MkdirAll(sourceDirLocal, 0755); err != nil {
return err
}
}

return nil
}

func (l *Lefthook) getSourceDirs() (global, local string) {
global = config.DefaultSourceDir
local = config.DefaultSourceDirLocal

cfg, err := config.Load(l.Fs, l.repo.RootPath)
if err == nil {
if len(cfg.SourceDir) > 0 {
global = cfg.SourceDir
}
if len(cfg.SourceDirLocal) > 0 {
local = cfg.SourceDirLocal
}
}

return
}
Loading

0 comments on commit 5878866

Please sign in to comment.