diff --git a/README.md b/README.md
index 9a775c5..b3e5351 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
Corgi is a command-line tool that helps with your repetitive command usages by organizing them into reusable snippet. See usage by simply running `corgi` or `corgi --help`
-Current version: **v0.2.1**
+Current version: **v0.2.2**
## Examples
Create a new snippet to automate the commands you run repetitively
@@ -145,9 +145,9 @@ corgi remove [
]
```
### Configure `corgi`
-Currently the only editable option is your text editor choice (default is `vim`), to configure the corgi CLI, run
+You can configure your text editor choice (default is `vim`) for snippet editing, and filter tool for interactive snippet selection. To configure the corgi CLI, run
```
-corgi config --editor
+corgi config [--editor ] [--filter-cmd ]
```
## Roadmap
diff --git a/cmd/config.go b/cmd/config.go
index a292e4b..a22dded 100644
--- a/cmd/config.go
+++ b/cmd/config.go
@@ -1,6 +1,8 @@
package cmd
-import "github.com/spf13/cobra"
+import (
+ "github.com/spf13/cobra"
+)
var configCmd = &cobra.Command{
Use: "config",
@@ -9,6 +11,7 @@ var configCmd = &cobra.Command{
}
var editor string
+var filterCmd string
func configure(cmd *cobra.Command, args []string) error {
conf, _, err := loadConfigAndSnippetsMeta()
@@ -21,10 +24,17 @@ func configure(cmd *cobra.Command, args []string) error {
return err
}
}
+ if filterCmd != "" {
+ conf.FilterCmd = filterCmd
+ if err := conf.Save(); err != nil {
+ return err
+ }
+ }
return nil
}
func init() {
+ configCmd.Flags().StringVar(&filterCmd, "filter-cmd", "", "Select the text editor you would like to use to edit snippet")
configCmd.Flags().StringVar(&editor, "editor", "", "Select the text editor you would like to use to edit snippet")
rootCmd.AddCommand(configCmd)
}
diff --git a/cmd/describe.go b/cmd/describe.go
index c4ff305..56fc193 100644
--- a/cmd/describe.go
+++ b/cmd/describe.go
@@ -3,7 +3,7 @@ package cmd
import "github.com/spf13/cobra"
var describeCmd = &cobra.Command{
- Use: "describe",
+ Use: "describe [title]",
Short: "Describe a snippet",
Args: cobra.MaximumNArgs(1),
RunE: describe,
diff --git a/cmd/edit.go b/cmd/edit.go
index 3dba72d..7fa5ce4 100644
--- a/cmd/edit.go
+++ b/cmd/edit.go
@@ -8,7 +8,7 @@ import (
)
var editCmd = &cobra.Command{
- Use: "edit",
+ Use: "edit [title]",
Short: "Edit a snippet",
Args: cobra.MaximumNArgs(1),
RunE: edit,
@@ -16,14 +16,14 @@ var editCmd = &cobra.Command{
func edit(cmd *cobra.Command, args []string) error {
// load config & snippets
- conf, snippets, err := loadConfigAndSnippetsMeta()
+ conf, snippetsMeta, err := loadConfigAndSnippetsMeta()
if err != nil {
return err
}
// find snippet title
var title string
if len(args) == 0 {
- title, err = filterSnippetTitle(conf.FilterCmd, snippets.GetSnippetTitles())
+ title, err = filterSnippetTitle(conf.FilterCmd, snippetsMeta.GetSnippetTitles())
if err != nil {
return err
}
@@ -31,7 +31,7 @@ func edit(cmd *cobra.Command, args []string) error {
title = args[0]
}
// find snippet
- s, err := snippets.FindSnippet(title)
+ s, err := snippetsMeta.FindSnippet(title)
if err != nil {
return err
}
@@ -39,6 +39,11 @@ func edit(cmd *cobra.Command, args []string) error {
if err := util.Execute(command, os.Stdin, os.Stdout); err != nil {
return err
}
+ // mark snippetsMeta dirty
+ snippetsMeta.IsMetaDirty = true
+ if err = snippetsMeta.Save(); err != nil {
+ return err
+ }
return nil
}
diff --git a/cmd/exec.go b/cmd/exec.go
index f8ae0c9..e4dc370 100644
--- a/cmd/exec.go
+++ b/cmd/exec.go
@@ -6,7 +6,7 @@ import (
)
var execCmd = &cobra.Command{
- Use: "exec",
+ Use: "exec [title]",
Short: "Execute a snippet",
Args: cobra.MaximumNArgs(1),
RunE: execute,
diff --git a/cmd/export.go b/cmd/export.go
index de71f60..adc5e1b 100644
--- a/cmd/export.go
+++ b/cmd/export.go
@@ -7,7 +7,7 @@ import (
)
var exportCmd = &cobra.Command{
- Use: "export",
+ Use: "export [title]",
Short: "Export a snippet to json file",
Args: cobra.MaximumNArgs(1),
RunE: export,
diff --git a/cmd/import.go b/cmd/import.go
index 7fdfe72..9bac257 100644
--- a/cmd/import.go
+++ b/cmd/import.go
@@ -6,8 +6,8 @@ import (
)
var importCmd = &cobra.Command{
- Use: "import",
- Short: "Import a snippet from json file",
+ Use: "import [file1] [file2...]",
+ Short: "Import a snippet from one or multiple json files",
Args: cobra.MinimumNArgs(1),
RunE: importSnippet,
}
diff --git a/cmd/list.go b/cmd/list.go
index 0ee1067..1db8f1d 100644
--- a/cmd/list.go
+++ b/cmd/list.go
@@ -14,13 +14,13 @@ var listCmd = &cobra.Command{
func list(cmd *cobra.Command, args []string) error {
// load config & snippets
- _, snippets, err := loadConfigAndSnippetsMeta()
+ _, snippetsMeta, err := loadConfigAndSnippetsMeta()
if err != nil {
return err
}
// display
fmt.Println("Here is the list of corgi snippets saved on your system:")
- for _, s := range snippets.Snippets {
+ for _, s := range snippetsMeta.Snippets {
color.Yellow("- %s", s.Title)
}
return nil
diff --git a/cmd/new.go b/cmd/new.go
index 79f2ad0..7eb0146 100644
--- a/cmd/new.go
+++ b/cmd/new.go
@@ -29,7 +29,7 @@ func create(cmd *cobra.Command, args []string) error {
}
defer snippet.RemoveHistFile()
// load config and snippets
- conf, snippets, err := loadConfigAndSnippetsMeta()
+ conf, snippetsMeta, err := loadConfigAndSnippetsMeta()
if err != nil {
return err
}
@@ -40,7 +40,7 @@ func create(cmd *cobra.Command, args []string) error {
return err
}
// add new sninppet to snippets meta and save
- if err = snippets.SaveNewSnippet(newSnippet, conf.SnippetsDir); err != nil {
+ if err = snippetsMeta.SaveNewSnippet(newSnippet, conf.SnippetsDir); err != nil {
return err
}
return nil
diff --git a/cmd/remove.go b/cmd/remove.go
index c708538..6d63458 100644
--- a/cmd/remove.go
+++ b/cmd/remove.go
@@ -3,7 +3,7 @@ package cmd
import "github.com/spf13/cobra"
var removeCmd = &cobra.Command{
- Use: "remove",
+ Use: "remove [title]",
Short: "Remove a snippet",
Args: cobra.MaximumNArgs(1),
RunE: remove,
diff --git a/cmd/root.go b/cmd/root.go
index 59ff02f..084428f 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -5,11 +5,11 @@ import (
"os"
)
-var appVersion = "v0.2.1"
+var appVersion = "v0.2.2"
var rootCmd = &cobra.Command{
Use: "corgi",
- Short: "Corgi is a smart dog that helps you organize your command flow for future usage",
+ Short: "Corgi is a smart dog that helps you manage your CLI workflow",
Version: appVersion,
SilenceUsage: true,
Run: func(cmd *cobra.Command, args []string) {
diff --git a/snippet/snippet.go b/snippet/snippet.go
index 67b4265..a2cdf9c 100644
--- a/snippet/snippet.go
+++ b/snippet/snippet.go
@@ -98,9 +98,13 @@ func (snippet *Snippet) AskQuestion(options ...interface{}) error {
return nil
}
+func getSnippetFileName(title string) string {
+ return fmt.Sprintf("%s.json", strings.Replace(title, " ", "_", -1))
+}
+
func (snippet *Snippet) Save(snippetsDir string) error {
- fmt.Printf("Saving snippet %s... ", snippet.Title)
- filePath := fmt.Sprintf("%s/%s.json", snippetsDir, strings.Replace(snippet.Title, " ", "_", -1))
+ fmt.Printf("Saving snippet \"%s\"... ", snippet.Title)
+ filePath := fmt.Sprintf("%s/%s", snippetsDir, getSnippetFileName(snippet.Title))
snippet.fileLoc = filePath
if err := snippet.writeToFile(filePath); err != nil {
color.Red("Failure")
diff --git a/snippet/snippets.go b/snippet/snippets.go
index c4e19d7..deac32c 100644
--- a/snippet/snippets.go
+++ b/snippet/snippets.go
@@ -7,11 +7,15 @@ import (
"github.com/fatih/color"
"io/ioutil"
"os"
+ "path"
+ "strconv"
+ "time"
)
type SnippetsMeta struct {
- Snippets []*jsonSnippet `json:"snippets"`
- fileLoc string
+ Snippets []*jsonSnippet `json:"snippets"`
+ IsMetaDirty bool `json:"is_meta_dirty"`
+ fileLoc string
}
type jsonSnippet struct {
@@ -19,18 +23,46 @@ type jsonSnippet struct {
Title string `json:"title"`
}
+func (sm *SnippetsMeta) syncWithSnippets() error {
+ for _, s := range sm.Snippets {
+ snippet, err := sm.FindSnippet(s.Title)
+ if err != nil {
+ return err
+ }
+ if s.Title != snippet.Title {
+ s.Title = snippet.Title
+ newFileName := getSnippetFileName(s.Title)
+ newFilePath := fmt.Sprintf("%s/%s", path.Dir(s.FileLoc), newFileName)
+ if err = os.Rename(s.FileLoc, newFilePath); err != nil {
+ return err
+ }
+ s.FileLoc = newFilePath
+ }
+ }
+ sm.IsMetaDirty = false
+ if err := sm.Save(); err != nil {
+ return err
+ }
+ return nil
+}
+
func LoadSnippetsMeta(filePath string) (*SnippetsMeta, error) {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return nil, err
}
- snippets := &SnippetsMeta{}
- if err := util.LoadJsonDataFromFile(filePath, snippets); err != nil {
+ snippetsMeta := &SnippetsMeta{}
+ if err := util.LoadJsonDataFromFile(filePath, snippetsMeta); err != nil {
return nil, err
}
- if snippets.fileLoc == "" {
- snippets.fileLoc = filePath
+ if snippetsMeta.fileLoc == "" {
+ snippetsMeta.fileLoc = filePath
+ }
+ if snippetsMeta.IsMetaDirty {
+ if err := snippetsMeta.syncWithSnippets(); err != nil {
+ return nil, err
+ }
}
- return snippets, nil
+ return snippetsMeta, nil
}
func (sm *SnippetsMeta) Save() error {
@@ -49,9 +81,18 @@ func (sm *SnippetsMeta) Save() error {
// Save new snippet into snippetsDir and update snippets meta file
func (sm *SnippetsMeta) SaveNewSnippet(snippet *Snippet, snippetsDir string) error {
+ // check for duplicate
+ if sm.isDuplicate(snippet.Title) {
+ t := strconv.FormatInt(time.Now().Unix(), 10)
+ newTitle := fmt.Sprintf("%s-%s", snippet.Title, t)
+ color.Red("Snippet with title \"%s\" already existed - saving as \"%s\"", snippet.Title, newTitle)
+ snippet.Title = newTitle
+ }
+ // save snippet file
if err := snippet.Save(snippetsDir); err != nil {
return err
}
+ // save to snippets meta file
jsonSnippet := &jsonSnippet{
Title: snippet.Title,
FileLoc: snippet.fileLoc,
@@ -63,6 +104,15 @@ func (sm *SnippetsMeta) SaveNewSnippet(snippet *Snippet, snippetsDir string) err
return nil
}
+func (sm *SnippetsMeta) isDuplicate(title string) bool {
+ for _, s := range sm.Snippets {
+ if s.Title == title {
+ return true
+ }
+ }
+ return false
+}
+
func (sm *SnippetsMeta) DeleteSnippet(title string) error {
idx, err := sm.findJsonSnippetIndex(title)
if err != nil {
diff --git a/snippet/step.go b/snippet/step.go
index e391b62..c09d341 100644
--- a/snippet/step.go
+++ b/snippet/step.go
@@ -13,7 +13,6 @@ import (
type StepInfo struct {
Command string `json:"command"`
Description string `json:"description,omitempty"`
- ExecuteConcurrent bool `json:"execute_concurrent"`
}
var TemplateParamsRegex = `<([^(<>|\s)]+)>`