Add `--dry-run` flag for `zk new` (#96)

pull/103/head
Mickaël Menu 3 years ago committed by GitHub
parent 439c1b1a69
commit 59b8269344
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
# Show the note filename without extension as detail. # Show the note filename without extension as detail.
note-detail = "{{filename-stem}}" note-detail = "{{filename-stem}}"
``` ```
* New `--dry-run` flag for `zk new` which prints out the path and content of the generated note instead of saving it to the file system.
### Fixed ### Fixed

@ -3,13 +3,14 @@ package cmd
import ( import (
"errors" "errors"
"fmt" "fmt"
"os"
"path/filepath" "path/filepath"
"time" "time"
"github.com/mickael-menu/zk/internal/cli" "github.com/mickael-menu/zk/internal/cli"
"github.com/mickael-menu/zk/internal/core" "github.com/mickael-menu/zk/internal/core"
"github.com/mickael-menu/zk/internal/util/opt" "github.com/mickael-menu/zk/internal/util/opt"
"github.com/mickael-menu/zk/internal/util/os" osutil "github.com/mickael-menu/zk/internal/util/os"
) )
// New adds a new note to the notebook. // New adds a new note to the notebook.
@ -20,6 +21,7 @@ type New struct {
Extra map[string]string ` help:"Extra variables passed to the templates." mapsep:","` Extra map[string]string ` help:"Extra variables passed to the templates." mapsep:","`
Template string ` placeholder:PATH help:"Custom template used to render the note."` Template string ` placeholder:PATH help:"Custom template used to render the note."`
PrintPath bool `short:p help:"Print the path of the created note instead of editing it."` PrintPath bool `short:p help:"Print the path of the created note instead of editing it."`
DryRun bool `short:n help:"Don't actually create the note. Instead, prints its content on stdout and the generated path on stderr."`
} }
func (cmd *New) Run(container *cli.Container) error { func (cmd *New) Run(container *cli.Container) error {
@ -28,7 +30,7 @@ func (cmd *New) Run(container *cli.Container) error {
return err return err
} }
content, err := os.ReadStdinPipe() content, err := osutil.ReadStdinPipe()
if err != nil { if err != nil {
return err return err
} }
@ -41,7 +43,19 @@ func (cmd *New) Run(container *cli.Container) error {
Template: opt.NewNotEmptyString(cmd.Template), Template: opt.NewNotEmptyString(cmd.Template),
Extra: cmd.Extra, Extra: cmd.Extra,
Date: time.Now(), Date: time.Now(),
DryRun: cmd.DryRun,
}) })
if cmd.DryRun {
if err != nil {
return err
}
path := filepath.Join(notebook.Path, note.Path)
fmt.Fprintln(os.Stderr, path)
fmt.Print(note.RawContent)
return nil
}
var path string var path string
if err == nil { if err == nil {
path = filepath.Join(notebook.Path, note.Path) path = filepath.Join(notebook.Path, note.Path)

@ -20,19 +20,20 @@ type newNoteTask struct {
bodyTemplatePath opt.String bodyTemplatePath opt.String
templates TemplateLoader templates TemplateLoader
genID IDGenerator genID IDGenerator
dryRun bool
} }
func (t *newNoteTask) execute() (string, error) { func (t *newNoteTask) execute() (string, string, error) {
filenameTemplate, err := t.templates.LoadTemplate(t.filenameTemplate) filenameTemplate, err := t.templates.LoadTemplate(t.filenameTemplate)
if err != nil { if err != nil {
return "", err return "", "", err
} }
var contentTemplate Template = NullTemplate var contentTemplate Template = NullTemplate
if templatePath := t.bodyTemplatePath.Unwrap(); templatePath != "" { if templatePath := t.bodyTemplatePath.Unwrap(); templatePath != "" {
contentTemplate, err = t.templates.LoadTemplateAt(templatePath) contentTemplate, err = t.templates.LoadTemplateAt(templatePath)
if err != nil { if err != nil {
return "", err return "", "", err
} }
} }
@ -47,20 +48,22 @@ func (t *newNoteTask) execute() (string, error) {
path, context, err := t.generatePath(context, filenameTemplate) path, context, err := t.generatePath(context, filenameTemplate)
if err != nil { if err != nil {
return "", err return "", "", err
} }
content, err := contentTemplate.Render(context) content, err := contentTemplate.Render(context)
if err != nil { if err != nil {
return "", err return "", "", err
} }
err = t.fs.Write(path, []byte(content)) if !t.dryRun {
if err != nil { err = t.fs.Write(path, []byte(content))
return "", err if err != nil {
return "", "", err
}
} }
return path, nil return path, content, nil
} }
func (c *newNoteTask) generatePath(context newNoteTemplateContext, filenameTemplate Template) (string, newNoteTemplateContext, error) { func (c *newNoteTask) generatePath(context newNoteTemplateContext, filenameTemplate Template) (string, newNoteTemplateContext, error) {

@ -44,15 +44,22 @@ type NoteContent struct {
func (n *Notebook) ParseNoteAt(absPath string) (*Note, error) { func (n *Notebook) ParseNoteAt(absPath string) (*Note, error) {
wrap := errors.Wrapper(absPath) wrap := errors.Wrapper(absPath)
relPath, err := n.RelPath(absPath) content, err := n.fs.Read(absPath)
if err != nil { if err != nil {
return nil, wrap(err) return nil, wrap(err)
} }
content, err := n.fs.Read(absPath) return n.ParseNoteWithContent(absPath, content)
}
func (n *Notebook) ParseNoteWithContent(absPath string, content []byte) (*Note, error) {
wrap := errors.Wrapper(absPath)
relPath, err := n.RelPath(absPath)
if err != nil { if err != nil {
return nil, wrap(err) return nil, wrap(err)
} }
contentStr := string(content) contentStr := string(content)
contentParts, err := n.parser.ParseNoteContent(contentStr) contentParts, err := n.parser.ParseNoteContent(contentStr)
if err != nil { if err != nil {
@ -86,9 +93,7 @@ func (n *Notebook) ParseNoteAt(absPath string) (*Note, error) {
} }
times, err := times.Stat(absPath) times, err := times.Stat(absPath)
if err != nil { if err == nil {
n.logger.Err(err)
} else {
note.Modified = times.ModTime().UTC() note.Modified = times.ModTime().UTC()
note.Created = creationDateFrom(note.Metadata, times) note.Created = creationDateFrom(note.Metadata, times)
} }

@ -108,6 +108,8 @@ type NewNoteOpts struct {
Extra map[string]string Extra map[string]string
// Creation date provided to the templates. // Creation date provided to the templates.
Date time.Time Date time.Time
// Don't save the generated note on the file system.
DryRun bool
} }
// ErrNoteExists is an error returned when a note already exists with the // ErrNoteExists is an error returned when a note already exists with the
@ -159,23 +161,26 @@ func (n *Notebook) NewNote(opts NewNoteOpts) (*Note, error) {
bodyTemplatePath: opts.Template.Or(config.Note.BodyTemplatePath), bodyTemplatePath: opts.Template.Or(config.Note.BodyTemplatePath),
templates: templates, templates: templates,
genID: n.idGeneratorFactory(config.Note.IDOptions), genID: n.idGeneratorFactory(config.Note.IDOptions),
dryRun: opts.DryRun,
} }
path, err := task.execute() path, content, err := task.execute()
if err != nil { if err != nil {
return nil, wrap(err) return nil, wrap(err)
} }
note, err := n.ParseNoteAt(path) note, err := n.ParseNoteWithContent(path, []byte(content))
if note == nil || err != nil { if note == nil || err != nil {
return nil, wrap(err) return nil, wrap(err)
} }
id, err := n.index.Add(*note) if !opts.DryRun {
if err != nil { id, err := n.index.Add(*note)
return nil, wrap(err) if err != nil {
return nil, wrap(err)
}
note.ID = id
} }
note.ID = id
return note, nil return note, nil
} }

Loading…
Cancel
Save