mirror of
https://github.com/dnote/dnote
synced 2026-03-15 06:55:49 +01:00
Compare commits
3 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff7e3a4cee | ||
|
|
37b137cbe7 | ||
|
|
e98403428e |
16 changed files with 354 additions and 113 deletions
49
.github/workflows/ci.yml
vendored
49
.github/workflows/ci.yml
vendored
|
|
@ -1,49 +0,0 @@
|
||||||
name: CI
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:14
|
|
||||||
env:
|
|
||||||
POSTGRES_USER: postgres
|
|
||||||
POSTGRES_PASSWORD: postgres
|
|
||||||
POSTGRES_DB: dnote_test
|
|
||||||
POSTGRES_PORT: 5432
|
|
||||||
# Wait until postgres has started
|
|
||||||
options: >-
|
|
||||||
--health-cmd pg_isready
|
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
|
|
||||||
# Expose port to the host
|
|
||||||
ports:
|
|
||||||
- 5432:5432
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: '1.20.0'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
make install
|
|
||||||
|
|
||||||
- name: Test cli
|
|
||||||
run: |
|
|
||||||
make test-cli
|
|
||||||
|
|
||||||
- name: Test app
|
|
||||||
run: |
|
|
||||||
make test-api
|
|
||||||
|
|
@ -20,9 +20,10 @@ package add
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"time"
|
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/database"
|
"github.com/dnote/dnote/pkg/cli/database"
|
||||||
"github.com/dnote/dnote/pkg/cli/infra"
|
"github.com/dnote/dnote/pkg/cli/infra"
|
||||||
|
|
@ -33,7 +34,6 @@ import (
|
||||||
"github.com/dnote/dnote/pkg/cli/utils"
|
"github.com/dnote/dnote/pkg/cli/utils"
|
||||||
"github.com/dnote/dnote/pkg/cli/validate"
|
"github.com/dnote/dnote/pkg/cli/validate"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var contentFlag string
|
var contentFlag string
|
||||||
|
|
@ -52,7 +52,7 @@ var example = `
|
||||||
pull is fetch with a merge
|
pull is fetch with a merge
|
||||||
EOF`
|
EOF`
|
||||||
|
|
||||||
func preRun(cmd *cobra.Command, args []string) error {
|
func preRun(cmd *command.Command, args []string) error {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return errors.New("Incorrect number of argument")
|
return errors.New("Incorrect number of argument")
|
||||||
}
|
}
|
||||||
|
|
@ -61,8 +61,9 @@ func preRun(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmd returns a new add command
|
// NewCmd returns a new add command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
|
Name: "add",
|
||||||
Use: "add <book>",
|
Use: "add <book>",
|
||||||
Short: "Add a new note",
|
Short: "Add a new note",
|
||||||
Aliases: []string{"a", "n", "new"},
|
Aliases: []string{"a", "n", "new"},
|
||||||
|
|
@ -84,7 +85,7 @@ func getContent(ctx context.DnoteCtx) (string, error) {
|
||||||
|
|
||||||
// check for piped content
|
// check for piped content
|
||||||
fInfo, _ := os.Stdin.Stat()
|
fInfo, _ := os.Stdin.Stat()
|
||||||
if fInfo.Mode() & os.ModeCharDevice == 0 {
|
if fInfo.Mode()&os.ModeCharDevice == 0 {
|
||||||
c, err := ui.ReadStdInput()
|
c, err := ui.ReadStdInput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "Failed to get piped input")
|
return "", errors.Wrap(err, "Failed to get piped input")
|
||||||
|
|
@ -106,7 +107,7 @@ func getContent(ctx context.DnoteCtx) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
bookName := args[0]
|
bookName := args[0]
|
||||||
if err := validate.BookName(bookName); err != nil {
|
if err := validate.BookName(bookName); err != nil {
|
||||||
return errors.Wrap(err, "invalid book name")
|
return errors.Wrap(err, "invalid book name")
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@ package cat
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/database"
|
"github.com/dnote/dnote/pkg/cli/database"
|
||||||
"github.com/dnote/dnote/pkg/cli/infra"
|
"github.com/dnote/dnote/pkg/cli/infra"
|
||||||
"github.com/dnote/dnote/pkg/cli/log"
|
"github.com/dnote/dnote/pkg/cli/log"
|
||||||
"github.com/dnote/dnote/pkg/cli/output"
|
"github.com/dnote/dnote/pkg/cli/output"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var example = `
|
var example = `
|
||||||
|
|
@ -40,7 +40,7 @@ var deprecationWarning = `and "view" will replace it in the future version.
|
||||||
Run "dnote view --help" for more information.
|
Run "dnote view --help" for more information.
|
||||||
`
|
`
|
||||||
|
|
||||||
func preRun(cmd *cobra.Command, args []string) error {
|
func preRun(cmd *command.Command, args []string) error {
|
||||||
if len(args) != 2 {
|
if len(args) != 2 {
|
||||||
return errors.New("Incorrect number of arguments")
|
return errors.New("Incorrect number of arguments")
|
||||||
}
|
}
|
||||||
|
|
@ -49,8 +49,8 @@ func preRun(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmd returns a new cat command
|
// NewCmd returns a new cat command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
Use: "cat <book name> <note index>",
|
Use: "cat <book name> <note index>",
|
||||||
Aliases: []string{"c"},
|
Aliases: []string{"c"},
|
||||||
Short: "See a note",
|
Short: "See a note",
|
||||||
|
|
@ -65,7 +65,7 @@ func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
||||||
|
|
||||||
// NewRun returns a new run function
|
// NewRun returns a new run function
|
||||||
func NewRun(ctx context.DnoteCtx, contentOnly bool) infra.RunEFunc {
|
func NewRun(ctx context.DnoteCtx, contentOnly bool) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
var noteRowIDArg string
|
var noteRowIDArg string
|
||||||
|
|
||||||
if len(args) == 2 {
|
if len(args) == 2 {
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,12 @@
|
||||||
package edit
|
package edit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/infra"
|
"github.com/dnote/dnote/pkg/cli/infra"
|
||||||
"github.com/dnote/dnote/pkg/cli/log"
|
"github.com/dnote/dnote/pkg/cli/log"
|
||||||
"github.com/dnote/dnote/pkg/cli/utils"
|
"github.com/dnote/dnote/pkg/cli/utils"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var contentFlag string
|
var contentFlag string
|
||||||
|
|
@ -49,8 +49,8 @@ var example = `
|
||||||
`
|
`
|
||||||
|
|
||||||
// NewCmd returns a new edit command
|
// NewCmd returns a new edit command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
Use: "edit <note id|book name>",
|
Use: "edit <note id|book name>",
|
||||||
Short: "Edit a note or a book",
|
Short: "Edit a note or a book",
|
||||||
Aliases: []string{"e"},
|
Aliases: []string{"e"},
|
||||||
|
|
@ -67,7 +67,7 @@ func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func preRun(cmd *cobra.Command, args []string) error {
|
func preRun(cmd *command.Command, args []string) error {
|
||||||
if len(args) != 1 && len(args) != 2 {
|
if len(args) != 1 && len(args) != 2 {
|
||||||
return errors.New("Incorrect number of argument")
|
return errors.New("Incorrect number of argument")
|
||||||
}
|
}
|
||||||
|
|
@ -76,7 +76,7 @@ func preRun(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
// DEPRECATED: Remove in 1.0.0
|
// DEPRECATED: Remove in 1.0.0
|
||||||
if len(args) == 2 {
|
if len(args) == 2 {
|
||||||
log.Plain(log.ColorYellow.Sprintf("DEPRECATED: you no longer need to pass book name to the view command. e.g. `dnote view 123`.\n\n"))
|
log.Plain(log.ColorYellow.Sprintf("DEPRECATED: you no longer need to pass book name to the view command. e.g. `dnote view 123`.\n\n"))
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/infra"
|
"github.com/dnote/dnote/pkg/cli/infra"
|
||||||
"github.com/dnote/dnote/pkg/cli/log"
|
"github.com/dnote/dnote/pkg/cli/log"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var example = `
|
var example = `
|
||||||
|
|
@ -43,7 +43,7 @@ var example = `
|
||||||
|
|
||||||
var bookName string
|
var bookName string
|
||||||
|
|
||||||
func preRun(cmd *cobra.Command, args []string) error {
|
func preRun(cmd *command.Command, args []string) error {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return errors.New("Incorrect number of argument")
|
return errors.New("Incorrect number of argument")
|
||||||
}
|
}
|
||||||
|
|
@ -52,8 +52,8 @@ func preRun(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmd returns a new remove command
|
// NewCmd returns a new remove command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
Use: "find",
|
Use: "find",
|
||||||
Short: "Find notes by keywords",
|
Short: "Find notes by keywords",
|
||||||
Aliases: []string{"f"},
|
Aliases: []string{"f"},
|
||||||
|
|
@ -154,7 +154,7 @@ func doQuery(ctx context.DnoteCtx, query, bookName string) (*sql.Rows, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
phrase, err := escapePhrase(args[0])
|
phrase, err := escapePhrase(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "escaping phrase")
|
return errors.Wrap(err, "escaping phrase")
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/dnote/dnote/pkg/cli/client"
|
"github.com/dnote/dnote/pkg/cli/client"
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/consts"
|
"github.com/dnote/dnote/pkg/cli/consts"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/database"
|
"github.com/dnote/dnote/pkg/cli/database"
|
||||||
|
|
@ -31,7 +32,6 @@ import (
|
||||||
"github.com/dnote/dnote/pkg/cli/log"
|
"github.com/dnote/dnote/pkg/cli/log"
|
||||||
"github.com/dnote/dnote/pkg/cli/ui"
|
"github.com/dnote/dnote/pkg/cli/ui"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var example = `
|
var example = `
|
||||||
|
|
@ -40,8 +40,8 @@ var example = `
|
||||||
var usernameFlag, passwordFlag string
|
var usernameFlag, passwordFlag string
|
||||||
|
|
||||||
// NewCmd returns a new login command
|
// NewCmd returns a new login command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
Use: "login",
|
Use: "login",
|
||||||
Short: "Login to dnote server",
|
Short: "Login to dnote server",
|
||||||
Example: example,
|
Example: example,
|
||||||
|
|
@ -49,8 +49,11 @@ func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
f := cmd.Flags()
|
f := cmd.Flags()
|
||||||
f.StringVarP(&usernameFlag, "username", "u", "", "email address for authentication")
|
f.String("username", "", "email address for authentication")
|
||||||
f.StringVarP(&passwordFlag, "password", "p", "", "password for authentication")
|
f.StringVar(&usernameFlag, "u", "", "email address for authentication")
|
||||||
|
|
||||||
|
f.String("password", "", "password for authentication")
|
||||||
|
f.StringVar(&passwordFlag, "p", "", "password for authentication")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
@ -150,7 +153,7 @@ func getGreeting(ctx context.DnoteCtx) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
greeting := getGreeting(ctx)
|
greeting := getGreeting(ctx)
|
||||||
log.Plain(greeting)
|
log.Plain(greeting)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,13 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
"github.com/dnote/dnote/pkg/cli/client"
|
"github.com/dnote/dnote/pkg/cli/client"
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/consts"
|
"github.com/dnote/dnote/pkg/cli/consts"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/database"
|
"github.com/dnote/dnote/pkg/cli/database"
|
||||||
"github.com/dnote/dnote/pkg/cli/infra"
|
"github.com/dnote/dnote/pkg/cli/infra"
|
||||||
"github.com/dnote/dnote/pkg/cli/log"
|
"github.com/dnote/dnote/pkg/cli/log"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNotLoggedIn is an error for logging out when not logged in
|
// ErrNotLoggedIn is an error for logging out when not logged in
|
||||||
|
|
@ -38,8 +38,8 @@ var example = `
|
||||||
dnote logout`
|
dnote logout`
|
||||||
|
|
||||||
// NewCmd returns a new logout command
|
// NewCmd returns a new logout command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
Use: "logout",
|
Use: "logout",
|
||||||
Short: "Logout from the server",
|
Short: "Logout from the server",
|
||||||
Example: example,
|
Example: example,
|
||||||
|
|
@ -83,7 +83,7 @@ func Do(ctx context.DnoteCtx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
err := Do(ctx)
|
err := Do(ctx)
|
||||||
if err == ErrNotLoggedIn {
|
if err == ErrNotLoggedIn {
|
||||||
log.Error("not logged in\n")
|
log.Error("not logged in\n")
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/infra"
|
"github.com/dnote/dnote/pkg/cli/infra"
|
||||||
"github.com/dnote/dnote/pkg/cli/log"
|
"github.com/dnote/dnote/pkg/cli/log"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var example = `
|
var example = `
|
||||||
|
|
@ -43,7 +43,7 @@ var deprecationWarning = `and "view" will replace it in the future version.
|
||||||
Run "dnote view --help" for more information.
|
Run "dnote view --help" for more information.
|
||||||
`
|
`
|
||||||
|
|
||||||
func preRun(cmd *cobra.Command, args []string) error {
|
func preRun(cmd *command.Command, args []string) error {
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
return errors.New("Incorrect number of argument")
|
return errors.New("Incorrect number of argument")
|
||||||
}
|
}
|
||||||
|
|
@ -52,8 +52,8 @@ func preRun(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmd returns a new ls command
|
// NewCmd returns a new ls command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
Use: "ls <book name?>",
|
Use: "ls <book name?>",
|
||||||
Aliases: []string{"l", "notes"},
|
Aliases: []string{"l", "notes"},
|
||||||
Short: "List all notes",
|
Short: "List all notes",
|
||||||
|
|
@ -68,7 +68,7 @@ func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
||||||
|
|
||||||
// NewRun returns a new run function for ls
|
// NewRun returns a new run function for ls
|
||||||
func NewRun(ctx context.DnoteCtx, nameOnly bool) infra.RunEFunc {
|
func NewRun(ctx context.DnoteCtx, nameOnly bool) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
if err := printBooks(ctx, nameOnly); err != nil {
|
if err := printBooks(ctx, nameOnly); err != nil {
|
||||||
return errors.Wrap(err, "viewing books")
|
return errors.Wrap(err, "viewing books")
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/database"
|
"github.com/dnote/dnote/pkg/cli/database"
|
||||||
"github.com/dnote/dnote/pkg/cli/infra"
|
"github.com/dnote/dnote/pkg/cli/infra"
|
||||||
|
|
@ -30,7 +31,6 @@ import (
|
||||||
"github.com/dnote/dnote/pkg/cli/ui"
|
"github.com/dnote/dnote/pkg/cli/ui"
|
||||||
"github.com/dnote/dnote/pkg/cli/utils"
|
"github.com/dnote/dnote/pkg/cli/utils"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var bookFlag string
|
var bookFlag string
|
||||||
|
|
@ -45,8 +45,8 @@ var example = `
|
||||||
`
|
`
|
||||||
|
|
||||||
// NewCmd returns a new remove command
|
// NewCmd returns a new remove command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
Use: "remove <note id|book name>",
|
Use: "remove <note id|book name>",
|
||||||
Short: "Remove a note or a book",
|
Short: "Remove a note or a book",
|
||||||
Aliases: []string{"rm", "d", "delete"},
|
Aliases: []string{"rm", "d", "delete"},
|
||||||
|
|
@ -59,12 +59,12 @@ func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
||||||
f.StringVarP(&bookFlag, "book", "b", "", "The book name to delete")
|
f.StringVarP(&bookFlag, "book", "b", "", "The book name to delete")
|
||||||
f.BoolVarP(&yesFlag, "yes", "y", false, "Assume yes to the prompts and run in non-interactive mode")
|
f.BoolVarP(&yesFlag, "yes", "y", false, "Assume yes to the prompts and run in non-interactive mode")
|
||||||
|
|
||||||
f.MarkDeprecated("book", "Pass the book name as an argument. e.g. `dnote rm book_name`")
|
// f.MarkDeprecated("book", "Pass the book name as an argument. e.g. `dnote rm book_name`")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func preRun(cmd *cobra.Command, args []string) error {
|
func preRun(cmd *command.Command, args []string) error {
|
||||||
if len(args) != 1 && len(args) != 2 {
|
if len(args) != 1 && len(args) != 2 {
|
||||||
return errors.New("Incorrect number of argument")
|
return errors.New("Incorrect number of argument")
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +81,7 @@ func maybeConfirm(message string, defaultValue bool) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
// DEPRECATED: Remove in 1.0.0
|
// DEPRECATED: Remove in 1.0.0
|
||||||
if bookFlag != "" {
|
if bookFlag != "" {
|
||||||
if err := runBook(ctx, bookFlag); err != nil {
|
if err := runBook(ctx, bookFlag); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -19,21 +19,18 @@
|
||||||
package root
|
package root
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
var root = &cobra.Command{
|
var root = &command.Command{
|
||||||
Use: "dnote",
|
Use: "dnote",
|
||||||
Short: "Dnote - a simple command line notebook",
|
Short: "Dnote - a simple command line notebook",
|
||||||
SilenceErrors: true,
|
SilenceErrors: true,
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
CompletionOptions: cobra.CompletionOptions{
|
|
||||||
DisableDefaultCmd: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register adds a new command
|
// Register adds a new command
|
||||||
func Register(cmd *cobra.Command) {
|
func Register(cmd *command.Command) {
|
||||||
root.AddCommand(cmd)
|
root.AddCommand(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/dnote/dnote/pkg/cli/client"
|
"github.com/dnote/dnote/pkg/cli/client"
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/consts"
|
"github.com/dnote/dnote/pkg/cli/consts"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/database"
|
"github.com/dnote/dnote/pkg/cli/database"
|
||||||
|
|
@ -31,7 +32,6 @@ import (
|
||||||
"github.com/dnote/dnote/pkg/cli/migrate"
|
"github.com/dnote/dnote/pkg/cli/migrate"
|
||||||
"github.com/dnote/dnote/pkg/cli/upgrade"
|
"github.com/dnote/dnote/pkg/cli/upgrade"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -45,8 +45,8 @@ var example = `
|
||||||
var isFullSync bool
|
var isFullSync bool
|
||||||
|
|
||||||
// NewCmd returns a new sync command
|
// NewCmd returns a new sync command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
Use: "sync",
|
Use: "sync",
|
||||||
Aliases: []string{"s"},
|
Aliases: []string{"s"},
|
||||||
Short: "Sync data with the server",
|
Short: "Sync data with the server",
|
||||||
|
|
@ -886,7 +886,7 @@ func saveSyncState(tx *database.DB, serverTime int64, serverMaxUSN int) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
if ctx.SessionKey == "" {
|
if ctx.SessionKey == "" {
|
||||||
return errors.New("not logged in")
|
return errors.New("not logged in")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,17 @@ package version
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmd returns a new version command
|
// NewCmd returns a new version command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
Use: "version",
|
Use: "version",
|
||||||
Short: "Print the version number of Dnote",
|
Short: "Print the version number of Dnote",
|
||||||
Long: "Print the version number of Dnote",
|
Long: "Print the version number of Dnote",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *command.Command, args []string) {
|
||||||
fmt.Printf("dnote %s\n", ctx.Version)
|
fmt.Printf("dnote %s\n", ctx.Version)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,10 @@
|
||||||
package view
|
package view
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
"github.com/dnote/dnote/pkg/cli/infra"
|
"github.com/dnote/dnote/pkg/cli/infra"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/dnote/dnote/pkg/cli/cmd/cat"
|
"github.com/dnote/dnote/pkg/cli/cmd/cat"
|
||||||
"github.com/dnote/dnote/pkg/cli/cmd/ls"
|
"github.com/dnote/dnote/pkg/cli/cmd/ls"
|
||||||
|
|
@ -43,7 +43,7 @@ var example = `
|
||||||
var nameOnly bool
|
var nameOnly bool
|
||||||
var contentOnly bool
|
var contentOnly bool
|
||||||
|
|
||||||
func preRun(cmd *cobra.Command, args []string) error {
|
func preRun(cmd *command.Command, args []string) error {
|
||||||
if len(args) > 2 {
|
if len(args) > 2 {
|
||||||
return errors.New("Incorrect number of argument")
|
return errors.New("Incorrect number of argument")
|
||||||
}
|
}
|
||||||
|
|
@ -52,8 +52,9 @@ func preRun(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmd returns a new view command
|
// NewCmd returns a new view command
|
||||||
func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
func NewCmd(ctx context.DnoteCtx) *command.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &command.Command{
|
||||||
|
Name: "view",
|
||||||
Use: "view <book name?> <note index?>",
|
Use: "view <book name?> <note index?>",
|
||||||
Aliases: []string{"v"},
|
Aliases: []string{"v"},
|
||||||
Short: "List books, notes or view a content",
|
Short: "List books, notes or view a content",
|
||||||
|
|
@ -70,7 +71,7 @@ func NewCmd(ctx context.DnoteCtx) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
func newRun(ctx context.DnoteCtx) infra.RunEFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *command.Command, args []string) error {
|
||||||
var run infra.RunEFunc
|
var run infra.RunEFunc
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
|
|
|
||||||
183
pkg/cli/command/command.go
Normal file
183
pkg/cli/command/command.go
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/dnote/dnote/pkg/cli/log"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Command struct {
|
||||||
|
// Name is the name of the command. This is used to find the subcommand
|
||||||
|
// and is case sensitive.
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// flags is a FlagSet which can parse and hold flags and their values.
|
||||||
|
flags *flag.FlagSet
|
||||||
|
|
||||||
|
// args is a list of arments
|
||||||
|
args []string
|
||||||
|
|
||||||
|
// RunE is a function that contains the logic for the command
|
||||||
|
RunE func(cmd *Command, args []string) error
|
||||||
|
|
||||||
|
// commands is the list of subcommands that this command has.
|
||||||
|
commands []*Command
|
||||||
|
|
||||||
|
// Parent is a pointer to the parent command, if any, of which the command
|
||||||
|
// is a subcommand.
|
||||||
|
Parent *Command
|
||||||
|
|
||||||
|
Use string
|
||||||
|
Short string
|
||||||
|
SilenceErrors bool
|
||||||
|
SilenceUsage bool
|
||||||
|
Example string
|
||||||
|
Aliases []string
|
||||||
|
PreRunE func(cmd *Command, args []string) error
|
||||||
|
Deprecated string
|
||||||
|
Long string
|
||||||
|
Run func(cmd *Command, args []string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) HelpFunc() {
|
||||||
|
err := tmpl(os.Stdout, c.HelpTemplate(), c)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flags returns a flag set for the command. If not initialized yet, it initializes
|
||||||
|
// one and returns the result.
|
||||||
|
func (c *Command) Flags() *flag.FlagSet {
|
||||||
|
if c.flags == nil {
|
||||||
|
c.flags = flag.NewFlagSet(c.Name, flag.ContinueOnError)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.flags
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseFlags parses the given slice of arguments using the flag set of the command.
|
||||||
|
func (c *Command) ParseFlags(args []string) error {
|
||||||
|
err := c.Flags().Parse(args)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Error parsing flags")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root returns the root command of the given command.
|
||||||
|
func (c *Command) Root() *Command {
|
||||||
|
if c.Parent != nil {
|
||||||
|
return c.Parent.Root()
|
||||||
|
}
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// setArgs sets the arguments for the command. It is useful while writing tests.
|
||||||
|
func (c *Command) setArgs(args []string) {
|
||||||
|
c.args = args
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args returns the argument for the command. By default, os.Args[1:] is used.
|
||||||
|
func (c *Command) Args() []string {
|
||||||
|
args := c.args
|
||||||
|
if c.args == nil {
|
||||||
|
args = os.Args[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return args
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute runs the root command. It is meant to be called on the root command.
|
||||||
|
func (c *Command) Execute() error {
|
||||||
|
// Call Execute on the root command
|
||||||
|
if c.Parent != nil {
|
||||||
|
return c.Root().Execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
args := c.Args()
|
||||||
|
log.Debug("root command received arguments: %s\n", args)
|
||||||
|
|
||||||
|
cmd, args := c.findCommand(args)
|
||||||
|
if cmd == nil {
|
||||||
|
// not found. show suggestion
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmd.execute(args); err != nil {
|
||||||
|
if errors.Cause(err) == errNotRunnable {
|
||||||
|
cmd.Help()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var errNotRunnable = errors.New("Command is not runnable.")
|
||||||
|
|
||||||
|
// execute runs the command.
|
||||||
|
func (c *Command) execute(args []string) error {
|
||||||
|
log.Debug("command '%s' called with arguments: %s\n", c.Name, args)
|
||||||
|
|
||||||
|
if err := c.ParseFlags(args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nonFlagArgs := c.Flags().Args()
|
||||||
|
log.Debug("command '%s' called with non-flag arguments: %s\n", c.Name, nonFlagArgs)
|
||||||
|
|
||||||
|
if c.RunE == nil {
|
||||||
|
return errNotRunnable
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.RunE(c, nonFlagArgs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasAlias checks whether the command has the given alias.
|
||||||
|
func (c *Command) hasAlias(targetAlias string) bool {
|
||||||
|
for _, alias := range c.Aliases {
|
||||||
|
if alias == targetAlias {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// findCommand finds and returns an appropriate subcommand to be called, based
|
||||||
|
// on the given slice of arguments. It also returns a slice of arguments with which
|
||||||
|
// the subcommand should be called.
|
||||||
|
func (c *Command) findCommand(args []string) (*Command, []string) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return c, args
|
||||||
|
}
|
||||||
|
|
||||||
|
name := args[0]
|
||||||
|
log.Debug("sub-command: '%s'\n", name)
|
||||||
|
|
||||||
|
for _, cmd := range c.commands {
|
||||||
|
if cmd.Name == name || cmd.hasAlias(name) {
|
||||||
|
return cmd, args[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, args
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddCommand adds the given command as a subcommand.
|
||||||
|
func (c *Command) AddCommand(cmd *Command) {
|
||||||
|
cmd.Parent = c
|
||||||
|
|
||||||
|
c.commands = append(c.commands, cmd)
|
||||||
|
}
|
||||||
105
pkg/cli/command/command_test.go
Normal file
105
pkg/cli/command/command_test.go
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/dnote/dnote/pkg/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAddCommand(t *testing.T) {
|
||||||
|
cmd := Command{Name: "root command"}
|
||||||
|
assert.Equal(t, len(cmd.commands), 0, "Commands length mismatch")
|
||||||
|
|
||||||
|
subCommand1 := Command{Name: "foo"}
|
||||||
|
cmd.AddCommand(&subCommand1)
|
||||||
|
assert.Equal(t, subCommand1.Parent, &cmd, "subCommand1 Parent mismatch")
|
||||||
|
assert.Equal(t, len(cmd.commands), 1, "Commands length mismatch")
|
||||||
|
assert.Equal(t, cmd.commands[0], &subCommand1, "commands[0] mismatch")
|
||||||
|
|
||||||
|
subCommand2 := Command{Name: "bar"}
|
||||||
|
cmd.AddCommand(&subCommand2)
|
||||||
|
assert.Equal(t, len(cmd.commands), 2, "Commands length mismatch")
|
||||||
|
assert.Equal(t, subCommand2.Parent, &cmd, "subCommand2 Parent mismatch")
|
||||||
|
assert.Equal(t, cmd.commands[0], &subCommand1, "commands[0] mismatch")
|
||||||
|
assert.Equal(t, cmd.commands[1], &subCommand2, "commands[1] mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasAlias(t *testing.T) {
|
||||||
|
cmd := Command{
|
||||||
|
Name: "foo",
|
||||||
|
Aliases: []string{"f", "bar"},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, cmd.hasAlias("f"), true, "Command should have 'f' alias")
|
||||||
|
assert.Equal(t, cmd.hasAlias("F"), false, "Command should not have 'F' alias")
|
||||||
|
assert.Equal(t, cmd.hasAlias("bar"), true, "Command should have 'bar' alias")
|
||||||
|
assert.Equal(t, cmd.hasAlias("BAR"), false, "Command should have 'BAR' alias")
|
||||||
|
assert.Equal(t, cmd.hasAlias("baz"), false, "Command should not have 'baz' alias")
|
||||||
|
assert.Equal(t, cmd.hasAlias(""), false, "Command should not have an empty alias")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasAlias_withoutAlias(t *testing.T) {
|
||||||
|
cmd := Command{
|
||||||
|
Name: "foo",
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, cmd.hasAlias("f"), false, "Command should not have any alias")
|
||||||
|
assert.Equal(t, cmd.hasAlias(""), false, "Command should not have any alias")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommandRoot(t *testing.T) {
|
||||||
|
subCommand2 := Command{
|
||||||
|
Name: "baz",
|
||||||
|
}
|
||||||
|
subCommand1 := Command{
|
||||||
|
Name: "bar",
|
||||||
|
commands: []*Command{
|
||||||
|
&subCommand2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd := Command{
|
||||||
|
Name: "foo",
|
||||||
|
commands: []*Command{
|
||||||
|
&subCommand1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
subCommand1.Parent = &cmd
|
||||||
|
subCommand2.Parent = &subCommand1
|
||||||
|
|
||||||
|
assert.Equal(t, cmd.Root(), &cmd, "Command should already be a root")
|
||||||
|
assert.Equal(t, subCommand1.Root(), &cmd, "subCommand1 root mismatch")
|
||||||
|
assert.Equal(t, subCommand2.Root(), &cmd, "subCommand2 root mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFindSubcommand(t *testing.T) {
|
||||||
|
subCommand1 := Command{
|
||||||
|
Name: "bar",
|
||||||
|
Aliases: []string{"quz"},
|
||||||
|
}
|
||||||
|
subCommand2 := Command{
|
||||||
|
Name: "baz",
|
||||||
|
}
|
||||||
|
cmd := Command{
|
||||||
|
Name: "foo",
|
||||||
|
commands: []*Command{
|
||||||
|
&subCommand1,
|
||||||
|
&subCommand2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, cmd.findSubCommand("bar"), &subCommand1, "Subcommand 'bar' mismatch")
|
||||||
|
assert.Equal(t, cmd.findSubCommand("baz"), &subCommand2, "Subcommand 'baz' mismatch")
|
||||||
|
|
||||||
|
// Should match an alias
|
||||||
|
assert.Equal(t, cmd.findSubCommand("quz"), &subCommand1, "Subcommand 'quz' mismatch")
|
||||||
|
// Should not match if not exists
|
||||||
|
assert.Equal(t, cmd.findSubCommand("qux"), (*Command)(nil), "Subcommand 'qux' mismatch")
|
||||||
|
// Should not match itself
|
||||||
|
assert.Equal(t, subCommand1.findSubCommand("bar"), (*Command)(nil), "Subcommand 'bar' mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeCommand(cmd *Command, args ...string) error {
|
||||||
|
cmd.setArgs(args)
|
||||||
|
return cmd.Execute()
|
||||||
|
}
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/dnote/dnote/pkg/cli/command"
|
||||||
"github.com/dnote/dnote/pkg/cli/config"
|
"github.com/dnote/dnote/pkg/cli/config"
|
||||||
"github.com/dnote/dnote/pkg/cli/consts"
|
"github.com/dnote/dnote/pkg/cli/consts"
|
||||||
"github.com/dnote/dnote/pkg/cli/context"
|
"github.com/dnote/dnote/pkg/cli/context"
|
||||||
|
|
@ -38,11 +39,10 @@ import (
|
||||||
"github.com/dnote/dnote/pkg/cli/utils"
|
"github.com/dnote/dnote/pkg/cli/utils"
|
||||||
"github.com/dnote/dnote/pkg/clock"
|
"github.com/dnote/dnote/pkg/clock"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunEFunc is a function type of dnote commands
|
// RunEFunc is a function type of dnote commands
|
||||||
type RunEFunc func(*cobra.Command, []string) error
|
type RunEFunc func(*command.Command, []string) error
|
||||||
|
|
||||||
func checkLegacyDBPath() (string, bool) {
|
func checkLegacyDBPath() (string, bool) {
|
||||||
legacyDnoteDir := getLegacyDnotePath(dirs.Home)
|
legacyDnoteDir := getLegacyDnotePath(dirs.Home)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue