Skip to content

Commit

Permalink
add githook command, decouple ui survey from comamnd
Browse files Browse the repository at this point in the history
  • Loading branch information
StarpTech committed Jan 25, 2018
1 parent 2749cad commit 0c68329
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 21 deletions.
158 changes: 158 additions & 0 deletions commands/githook/githook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package githook

import (
"os"
"path"

logy "github.com/apex/log"
survey "gopkg.in/AlecAivazis/survey.v1"
)

var (
Hooks = []string{
"applypatch-msg",
"commit-msg",
"post-commit",
"post-receive",
"post-update",
"pre-applypatch",
"pre-commit",
"prepare-commit-msg",
"pre-rebase",
"update",
}
// convention
repoHookDir = "git_hooks"
)

// CommandData contains all command related data
type CommandData struct {
Path string
Hooks []string
}

// Githook command to create git hooks
type Githook struct {
Path string
CommandData *CommandData
}

// Option function.
type Option func(*Githook)

// New with the given options.
func New(options ...Option) *Githook {
v := &Githook{}

for _, o := range options {
o(v)
}

return v
}

// WithCommandData option.
func WithCommandData(cd *CommandData) Option {
return func(g *Githook) {
g.CommandData = cd
}
}

// Install will create hard links from local git_hooks to the corresponding git hooks
func (g *Githook) Install() error {
for _, h := range g.CommandData.Hooks {
hookGitPath := path.Join(g.CommandData.Path, ".git", "hooks", h)
hookRepoPath := path.Join(g.CommandData.Path, repoHookDir, h)
if !exists(hookGitPath) {
dir := path.Dir(hookGitPath)
logy.Debugf("Path '%s' created", dir)
err := createDirIfNotExist(dir)
if err != nil {
logy.WithError(err).Error("Could not create directory")
}
} else {
os.Remove(hookGitPath)
}
if exists(hookRepoPath) {
logy.Debugf("Create symlink old: %s, new: %s", hookGitPath, hookRepoPath)
err := os.Link(hookRepoPath, hookGitPath)
if err != nil {
logy.WithError(err).Errorf("Could not link hook %s", h)
return err
}
logy.Debugf("hook '%s' installed", h)
} else {
logy.Infof("template for hook '%s' could not be found in %s", h, path.Join(g.CommandData.Path, repoHookDir))
}

}
return nil
}

// getQuestions return all required prompts
func (g *Githook) getQuestions() []*survey.Question {
qs := []*survey.Question{
{
Name: "Path",
Validate: survey.Required,
Prompt: &survey.Input{
Message: "What is the destination?",
Default: ".",
},
},
{
Name: "Hooks",
Validate: survey.Required,
Prompt: &survey.MultiSelect{
Message: "Which hooks should be installed?",
Options: Hooks,
},
},
}

return qs
}

func (g *Githook) startCommandSurvey() error {
var cmd = &CommandData{}

// start command prompts
err := survey.Ask(g.getQuestions(), cmd)
if err != nil {
return err
}

g.CommandData = cmd

return nil
}

// Run the command
func (g *Githook) Run() error {
if g.CommandData == nil {
err := g.startCommandSurvey()
if err != nil {
return err
}
}
return g.Install()
}

func exists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}

func createDirIfNotExist(dir string) error {
if _, err := os.Stat(dir); os.IsNotExist(err) {
err = os.MkdirAll(dir, 0755)
if err != nil {
return err
}
}
return nil
}
58 changes: 38 additions & 20 deletions commands/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (

logy "github.com/apex/log"
"github.com/briandowns/spinner"
"github.com/netzkern/butler/commands/githook"
"github.com/netzkern/butler/config"
"github.com/pinzolo/casee"
uuid "github.com/satori/go.uuid"
Expand All @@ -33,8 +34,8 @@ const (
)

type (
// ProjectData contains all project data
ProjectData struct {
// CommandData contains all project data
CommandData struct {
Name string
Path string
Template string
Expand All @@ -50,12 +51,12 @@ type (
ch chan func()
wg sync.WaitGroup
surveyResult map[string]interface{}
project *ProjectData
CommandData *CommandData
surveys *Survey
}
// Data basic template data
// TemplateData basic template data
TemplateData struct {
Project *ProjectData
Project *CommandData
Date string
Year int
Vars map[string]string
Expand Down Expand Up @@ -140,8 +141,8 @@ func (t *Templating) getTemplateOptions() []string {
return tpls
}

// GetQuestions return all required prompts
func (t *Templating) GetQuestions() []*survey.Question {
// getQuestions return all required prompts
func (t *Templating) getQuestions() []*survey.Question {
qs := []*survey.Question{
{
Name: "Template",
Expand Down Expand Up @@ -210,15 +211,15 @@ func (t *Templating) Skip(path string, info os.FileInfo) (bool, error) {
}

func (t *Templating) startCommandSurvey() error {
var project = &ProjectData{}
var cd = &CommandData{}

// start command prompts
err := survey.Ask(t.GetQuestions(), project)
err := survey.Ask(t.getQuestions(), cd)
if err != nil {
return err
}

t.project = project
t.CommandData = cd

return nil
}
Expand Down Expand Up @@ -288,15 +289,17 @@ func (t *Templating) generateTempFuncs() template.FuncMap {

// Run the command
func (t *Templating) Run() error {
err := t.startCommandSurvey()
if err != nil {
return err
if t.CommandData == nil {
err := t.startCommandSurvey()
if err != nil {
return err
}
}

tpl := t.getTemplateByName(t.project.Template)
tpl := t.getTemplateByName(t.CommandData.Template)

if tpl == nil {
return fmt.Errorf("template %s could not be found", t.project.Template)
return fmt.Errorf("template %s could not be found", t.CommandData.Template)
}

// clone repository
Expand All @@ -305,15 +308,15 @@ func (t *Templating) Run() error {
s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
s.Suffix = "Cloning repository..."
s.Start()
err = t.cloneRepo(tpl.Url, t.project.Path)
err := t.cloneRepo(tpl.Url, t.CommandData.Path)
s.Stop()
cloneDuration = time.Since(startTimeClone).Seconds()

if err != nil {
return err
}

surveyFile := path.Join(t.project.Path, t.configName)
surveyFile := path.Join(t.CommandData.Path, t.configName)
ctx := logy.WithFields(logy.Fields{
"path": surveyFile,
})
Expand Down Expand Up @@ -342,7 +345,7 @@ func (t *Templating) Run() error {
}()

templateData := &TemplateData{
t.project,
t.CommandData,
time.Now().Format(time.RFC3339),
time.Now().Year(),
t.Variables,
Expand All @@ -355,7 +358,7 @@ func (t *Templating) Run() error {

// iterate through all directorys
walkDirErr := filepath.Walk(
t.project.Path,
t.CommandData.Path,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
Expand Down Expand Up @@ -432,7 +435,7 @@ func (t *Templating) Run() error {
}

// iterate through all files
walkErr := filepath.Walk(t.project.Path,
walkErr := filepath.Walk(t.CommandData.Path,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
Expand Down Expand Up @@ -546,6 +549,21 @@ func (t *Templating) Run() error {
return walkErr
}

// create hooks
commandGitHook := githook.New(
githook.WithCommandData(
&githook.CommandData{
Path: t.CommandData.Path,
Hooks: githook.Hooks,
},
),
)
err = commandGitHook.Run()
if err != nil {
logy.WithError(err).Error("Could not create git hooks")
return err
}

return nil
}

Expand Down
10 changes: 9 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"runtime"

logy "github.com/apex/log"
"github.com/netzkern/butler/commands/githook"
"github.com/netzkern/butler/commands/template"
"github.com/netzkern/butler/config"
"github.com/netzkern/butler/updater"
Expand All @@ -30,6 +31,7 @@ var (
version = "master"
commands = []string{
"Project Templates",
"Install Git Hooks",
"Auto Update",
"Version",
}
Expand All @@ -46,7 +48,7 @@ var (
)

func init() {
logy.SetLevel(logy.InfoLevel)
logy.SetLevel(logy.ErrorLevel)
cfg = config.ParseConfig(configName)

// Windows comaptible symbols
Expand Down Expand Up @@ -84,6 +86,12 @@ func interactiveCliMode() {
if err != nil {
logy.Errorf(err.Error())
}
case "Install Git Hooks":
command := githook.New()
err := command.Run()
if err != nil {
logy.Errorf(err.Error())
}
case "Auto Update":
updater.ConfirmAndSelfUpdate(repository, version)
case "Version":
Expand Down

0 comments on commit 0c68329

Please sign in to comment.