mirror of
https://github.com/mickael-menu/zk
synced 2024-11-07 15:20:21 +00:00
Specify the notebook directory explicitly (#14)
This commit is contained in:
parent
be8b2d6289
commit
e653c71356
@ -11,6 +11,10 @@ All notable changes to this project will be documented in this file.
|
||||
* This is the same format as a notebook [configuration file](docs/config.md).
|
||||
* Shared templates can be stored in `~/.config/zk/templates/`.
|
||||
* `XDG_CONFIG_HOME` is taken into account.
|
||||
* Use `--notebook-dir` or set `ZK_NOTEBOOK_DIR` to run `zk` as if it was started from this path instead of the current working directory.
|
||||
* This allows running `zk` without being in a notebook.
|
||||
* By setting `ZK_NOTEBOOK_DIR` in your shell configuration file (e.g. `~/.profile`), you are declaring a default global notebook which will be used when `zk` is not in a notebook.
|
||||
* When the notebook directory is set explicitly, any path given as argument will be relative to it instead of the actual working directory.
|
||||
|
||||
|
||||
## 0.2.1
|
||||
|
@ -26,6 +26,7 @@ type Container struct {
|
||||
Date date.Provider
|
||||
Logger util.Logger
|
||||
Terminal *term.Terminal
|
||||
WorkingDir string
|
||||
templateLoader *handlebars.Loader
|
||||
zk *zk.Zk
|
||||
zkErr error
|
||||
@ -48,24 +49,15 @@ func NewContainer() (*Container, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Open current notebook
|
||||
zk, zkErr := zk.Open(".", config)
|
||||
if zkErr == nil {
|
||||
config = zk.Config
|
||||
os.Setenv("ZK_PATH", zk.Path)
|
||||
}
|
||||
|
||||
date := date.NewFrozenNow()
|
||||
|
||||
return &Container{
|
||||
Config: config,
|
||||
Logger: util.NewStdLogger("zk: ", 0),
|
||||
// zk is short-lived, so we freeze the current date to use the same
|
||||
// date for any rendering during the execution.
|
||||
// date for any template rendering during the execution.
|
||||
Date: &date,
|
||||
Logger: util.NewStdLogger("zk: ", 0),
|
||||
Terminal: term.New(),
|
||||
zk: zk,
|
||||
zkErr: zkErr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -94,6 +86,24 @@ func locateGlobalConfig() (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// OpenNotebook resolves and loads the first notebook found in the given
|
||||
// searchPaths.
|
||||
func (c *Container) OpenNotebook(searchPaths []string) {
|
||||
if len(searchPaths) == 0 {
|
||||
panic("no notebook search paths provided")
|
||||
}
|
||||
|
||||
for _, path := range searchPaths {
|
||||
c.zk, c.zkErr = zk.Open(path, c.Config)
|
||||
if c.zkErr == nil {
|
||||
c.WorkingDir = path
|
||||
c.Config = c.zk.Config
|
||||
os.Setenv("ZK_NOTEBOOK_DIR", c.zk.Path)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Container) Zk() (*zk.Zk, error) {
|
||||
return c.zk, c.zkErr
|
||||
}
|
||||
@ -106,11 +116,11 @@ func (c *Container) TemplateLoader(lang string) *handlebars.Loader {
|
||||
return c.templateLoader
|
||||
}
|
||||
|
||||
func (c *Container) Parser(zk *zk.Zk) *markdown.Parser {
|
||||
func (c *Container) Parser() *markdown.Parser {
|
||||
return markdown.NewParser(markdown.ParserOpts{
|
||||
HashtagEnabled: zk.Config.Format.Markdown.Hashtags,
|
||||
MultiWordTagEnabled: zk.Config.Format.Markdown.MultiwordTags,
|
||||
ColontagEnabled: zk.Config.Format.Markdown.ColonTags,
|
||||
HashtagEnabled: c.Config.Format.Markdown.Hashtags,
|
||||
MultiWordTagEnabled: c.Config.Format.Markdown.MultiwordTags,
|
||||
ColontagEnabled: c.Config.Format.Markdown.ColonTags,
|
||||
})
|
||||
}
|
||||
|
||||
@ -127,10 +137,14 @@ func (c *Container) NoteIndexer(tx sqlite.Transaction) *sqlite.NoteIndexer {
|
||||
|
||||
// Database returns the DB instance for the given notebook, after executing any
|
||||
// pending migration and indexing the notes if needed.
|
||||
func (c *Container) Database(zk *zk.Zk, forceIndexing bool) (*sqlite.DB, note.IndexingStats, error) {
|
||||
func (c *Container) Database(forceIndexing bool) (*sqlite.DB, note.IndexingStats, error) {
|
||||
var stats note.IndexingStats
|
||||
|
||||
db, err := sqlite.Open(zk.DBPath())
|
||||
if c.zkErr != nil {
|
||||
return nil, stats, c.zkErr
|
||||
}
|
||||
|
||||
db, err := sqlite.Open(c.zk.DBPath())
|
||||
if err != nil {
|
||||
return nil, stats, err
|
||||
}
|
||||
@ -139,7 +153,7 @@ func (c *Container) Database(zk *zk.Zk, forceIndexing bool) (*sqlite.DB, note.In
|
||||
return nil, stats, errors.Wrap(err, "failed to migrate the database")
|
||||
}
|
||||
|
||||
stats, err = c.index(zk, db, forceIndexing || needsReindexing)
|
||||
stats, err = c.index(db, forceIndexing || needsReindexing)
|
||||
if err != nil {
|
||||
return nil, stats, err
|
||||
}
|
||||
@ -147,7 +161,7 @@ func (c *Container) Database(zk *zk.Zk, forceIndexing bool) (*sqlite.DB, note.In
|
||||
return db, stats, err
|
||||
}
|
||||
|
||||
func (c *Container) index(zk *zk.Zk, db *sqlite.DB, force bool) (note.IndexingStats, error) {
|
||||
func (c *Container) index(db *sqlite.DB, force bool) (note.IndexingStats, error) {
|
||||
var bar = progressbar.NewOptions(-1,
|
||||
progressbar.OptionSetWriter(os.Stderr),
|
||||
progressbar.OptionThrottle(100*time.Millisecond),
|
||||
@ -156,11 +170,16 @@ func (c *Container) index(zk *zk.Zk, db *sqlite.DB, force bool) (note.IndexingSt
|
||||
|
||||
var err error
|
||||
var stats note.IndexingStats
|
||||
|
||||
if c.zkErr != nil {
|
||||
return stats, c.zkErr
|
||||
}
|
||||
|
||||
err = db.WithTransaction(func(tx sqlite.Transaction) error {
|
||||
stats, err = note.Index(
|
||||
zk,
|
||||
c.zk,
|
||||
force,
|
||||
c.Parser(zk),
|
||||
c.Parser(),
|
||||
c.NoteIndexer(tx),
|
||||
c.Logger,
|
||||
func(change paths.DiffChange) {
|
||||
@ -179,8 +198,8 @@ func (c *Container) index(zk *zk.Zk, db *sqlite.DB, force bool) (note.IndexingSt
|
||||
// paginated if noPager is false, using the user's pager.
|
||||
//
|
||||
// You can write to the pager only in the run callback.
|
||||
func (c *Container) Paginate(noPager bool, config zk.Config, run func(out io.Writer) error) error {
|
||||
pager, err := c.pager(noPager || config.Tool.Pager.IsEmpty(), config)
|
||||
func (c *Container) Paginate(noPager bool, run func(out io.Writer) error) error {
|
||||
pager, err := c.pager(noPager || c.Config.Tool.Pager.IsEmpty())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -189,10 +208,10 @@ func (c *Container) Paginate(noPager bool, config zk.Config, run func(out io.Wri
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Container) pager(noPager bool, config zk.Config) (*pager.Pager, error) {
|
||||
func (c *Container) pager(noPager bool) (*pager.Pager, error) {
|
||||
if noPager || !c.Terminal.IsInteractive() {
|
||||
return pager.PassthroughPager, nil
|
||||
} else {
|
||||
return pager.New(config.Tool.Pager, c.Logger)
|
||||
return pager.New(c.Config.Tool.Pager, c.Logger)
|
||||
}
|
||||
}
|
||||
|
12
cmd/edit.go
12
cmd/edit.go
@ -2,7 +2,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/mickael-menu/zk/adapter/fzf"
|
||||
@ -26,17 +25,12 @@ func (cmd *Edit) Run(container *Container) error {
|
||||
return err
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts, err := NewFinderOpts(zk, cmd.Filtering, cmd.Sorting)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "incorrect criteria")
|
||||
}
|
||||
|
||||
db, _, err := container.Database(zk, false)
|
||||
db, _, err := container.Database(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -45,10 +39,10 @@ func (cmd *Edit) Run(container *Container) error {
|
||||
err = db.WithTransaction(func(tx sqlite.Transaction) error {
|
||||
finder := container.NoteFinder(tx, fzf.NoteFinderOpts{
|
||||
AlwaysFilter: true,
|
||||
PreviewCmd: zk.Config.Tool.FzfPreview,
|
||||
PreviewCmd: container.Config.Tool.FzfPreview,
|
||||
NewNoteDir: cmd.newNoteDir(zk),
|
||||
BasePath: zk.Path,
|
||||
CurrentPath: wd,
|
||||
CurrentPath: container.WorkingDir,
|
||||
})
|
||||
notes, err = finder.Find(*opts)
|
||||
return err
|
||||
|
@ -15,12 +15,7 @@ func (cmd *Index) Help() string {
|
||||
}
|
||||
|
||||
func (cmd *Index) Run(container *Container) error {
|
||||
zk, err := container.Zk()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, stats, err := container.Database(zk, cmd.Force)
|
||||
_, stats, err := container.Database(cmd.Force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
17
cmd/list.go
17
cmd/list.go
@ -39,20 +39,15 @@ func (cmd *List) Run(container *Container) error {
|
||||
return err
|
||||
}
|
||||
|
||||
db, _, err := container.Database(zk, false)
|
||||
db, _, err := container.Database(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
templates := container.TemplateLoader(zk.Config.Note.Lang)
|
||||
templates := container.TemplateLoader(container.Config.Note.Lang)
|
||||
styler := container.Terminal
|
||||
format := opt.NewNotEmptyString(cmd.Format)
|
||||
formatter, err := note.NewFormatter(zk.Path, wd, format, templates, styler)
|
||||
formatter, err := note.NewFormatter(zk.Path, container.WorkingDir, format, templates, styler)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -61,9 +56,9 @@ func (cmd *List) Run(container *Container) error {
|
||||
err = db.WithTransaction(func(tx sqlite.Transaction) error {
|
||||
finder := container.NoteFinder(tx, fzf.NoteFinderOpts{
|
||||
AlwaysFilter: false,
|
||||
PreviewCmd: zk.Config.Tool.FzfPreview,
|
||||
PreviewCmd: container.Config.Tool.FzfPreview,
|
||||
BasePath: zk.Path,
|
||||
CurrentPath: wd,
|
||||
CurrentPath: container.WorkingDir,
|
||||
})
|
||||
notes, err = finder.Find(*opts)
|
||||
return err
|
||||
@ -77,7 +72,7 @@ func (cmd *List) Run(container *Container) error {
|
||||
|
||||
count := len(notes)
|
||||
if count > 0 {
|
||||
err = container.Paginate(cmd.NoPager, zk.Config, func(out io.Writer) error {
|
||||
err = container.Paginate(cmd.NoPager, func(out io.Writer) error {
|
||||
for i, note := range notes {
|
||||
if i > 0 {
|
||||
fmt.Fprint(out, cmd.Delimiter)
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
|
||||
// New adds a new note to the notebook.
|
||||
type New struct {
|
||||
Directory string `arg optional type:"path" default:"." help:"Directory in which to create the note."`
|
||||
Directory string `arg optional default:"." help:"Directory in which to create the note."`
|
||||
|
||||
Title string `short:t placeholder:TITLE help:"Title of the new note."`
|
||||
Group string `short:g placeholder:NAME help:"Name of the config group this note belongs to. Takes precedence over the config of the directory."`
|
||||
@ -46,7 +46,7 @@ func (cmd *New) Run(container *Container) error {
|
||||
}
|
||||
|
||||
opts := note.CreateOpts{
|
||||
Config: zk.Config,
|
||||
Config: container.Config,
|
||||
Dir: *dir,
|
||||
Title: opt.NewNotEmptyString(cmd.Title),
|
||||
Content: content,
|
||||
|
@ -9,6 +9,13 @@ import (
|
||||
"github.com/mickael-menu/zk/util/paths"
|
||||
)
|
||||
|
||||
// ErrNotebookNotFound is an error returned when a notebook cannot be found at the given path or its parents.
|
||||
type ErrNotebookNotFound string
|
||||
|
||||
func (e ErrNotebookNotFound) Error() string {
|
||||
return fmt.Sprintf("no notebook found in %s or a parent directory", string(e))
|
||||
}
|
||||
|
||||
const defaultConfig = `# zk configuration file
|
||||
#
|
||||
# Uncomment the properties you want to customize.
|
||||
@ -150,7 +157,7 @@ hashtags = true
|
||||
#hist = "zk list --format path --delimiter0 --quiet $@ | xargs -t -0 git log --patch --"
|
||||
|
||||
# Edit this configuration file.
|
||||
#conf = '$EDITOR "$ZK_PATH/.zk/config.toml"'
|
||||
#conf = '$EDITOR "$ZK_NOTEBOOK_DIR/.zk/config.toml"'
|
||||
`
|
||||
|
||||
const defaultTemplate = `# {{title}}
|
||||
@ -164,6 +171,8 @@ type Zk struct {
|
||||
Path string
|
||||
// Global user configuration.
|
||||
Config Config
|
||||
// Working directory from which paths are relative.
|
||||
workingDir string
|
||||
}
|
||||
|
||||
// Dir represents a directory inside a notebook.
|
||||
@ -177,10 +186,10 @@ type Dir struct {
|
||||
}
|
||||
|
||||
// Open locates a notebook at the given path and parses its configuration.
|
||||
func Open(path string, parentConfig Config) (*Zk, error) {
|
||||
func Open(originalPath string, parentConfig Config) (*Zk, error) {
|
||||
wrap := errors.Wrapper("open failed")
|
||||
|
||||
path, err := filepath.Abs(path)
|
||||
path, err := filepath.Abs(originalPath)
|
||||
if err != nil {
|
||||
return nil, wrap(err)
|
||||
}
|
||||
@ -195,8 +204,9 @@ func Open(path string, parentConfig Config) (*Zk, error) {
|
||||
}
|
||||
|
||||
return &Zk{
|
||||
Path: path,
|
||||
Config: config,
|
||||
Path: path,
|
||||
Config: config,
|
||||
workingDir: originalPath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -237,7 +247,7 @@ func locateRoot(path string) (string, error) {
|
||||
var locate func(string) (string, error)
|
||||
locate = func(currentPath string) (string, error) {
|
||||
if currentPath == "/" || currentPath == "." {
|
||||
return "", fmt.Errorf("no notebook found in %v or a parent directory", path)
|
||||
return "", ErrNotebookNotFound(path)
|
||||
}
|
||||
exists, err := paths.DirExists(filepath.Join(currentPath, ".zk"))
|
||||
switch {
|
||||
@ -259,19 +269,20 @@ func (zk *Zk) DBPath() string {
|
||||
}
|
||||
|
||||
// RelPath returns the path relative to the notebook root to the given path.
|
||||
func (zk *Zk) RelPath(absPath string) (string, error) {
|
||||
wrap := errors.Wrapperf("%v: not a valid notebook path", absPath)
|
||||
func (zk *Zk) RelPath(originalPath string) (string, error) {
|
||||
wrap := errors.Wrapperf("%v: not a valid notebook path", originalPath)
|
||||
|
||||
path, err := filepath.Abs(absPath)
|
||||
path, err := zk.absPath(originalPath)
|
||||
if err != nil {
|
||||
return path, wrap(err)
|
||||
}
|
||||
|
||||
path, err = filepath.Rel(zk.Path, path)
|
||||
if err != nil {
|
||||
return path, wrap(err)
|
||||
}
|
||||
if strings.HasPrefix(path, "..") {
|
||||
return path, fmt.Errorf("%s: path is outside the notebook", absPath)
|
||||
return path, fmt.Errorf("%s: path is outside the notebook", originalPath)
|
||||
}
|
||||
if path == "." {
|
||||
path = ""
|
||||
@ -279,6 +290,23 @@ func (zk *Zk) RelPath(absPath string) (string, error) {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
// AbsPath makes the given path absolute, using the current working directory
|
||||
// as reference.
|
||||
func (zk *Zk) absPath(originalPath string) (string, error) {
|
||||
var err error
|
||||
|
||||
path := originalPath
|
||||
if !filepath.IsAbs(path) {
|
||||
path = filepath.Join(zk.workingDir, path)
|
||||
path, err = filepath.Abs(path)
|
||||
if err != nil {
|
||||
return path, err
|
||||
}
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
// RootDir returns the root Dir for this notebook.
|
||||
func (zk *Zk) RootDir() Dir {
|
||||
return Dir{
|
||||
@ -290,7 +318,7 @@ func (zk *Zk) RootDir() Dir {
|
||||
|
||||
// DirAt returns a Dir representation of the notebook directory at the given path.
|
||||
func (zk *Zk) DirAt(path string, overrides ...ConfigOverrides) (*Dir, error) {
|
||||
path, err := filepath.Abs(path)
|
||||
path, err := zk.absPath(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "%v: not a valid notebook directory", path)
|
||||
}
|
||||
|
@ -20,10 +20,10 @@ An alias can call other aliases but cannot call itself. This enables you to over
|
||||
edit = "zk edit --interactive $@"
|
||||
```
|
||||
|
||||
When running an alias, the `ZK_PATH` environment variable is set to the absolute path of the current notebook. You can use it to run commands working no matter the location of the working directory.
|
||||
When running an alias, the `ZK_NOTEBOOK_DIR` environment variable is set to the absolute path of the current notebook. You can use it to run commands working no matter the location of the working directory.
|
||||
|
||||
```toml
|
||||
journal = 'zk new "$ZK_PATH/journal"'
|
||||
journal = 'zk new "$ZK_NOTEBOOK_DIR/journal"'
|
||||
```
|
||||
|
||||
If you need to surround the path with quotes, make sure you use double quotes, otherwise environment variables will not be expanded.
|
||||
@ -70,10 +70,10 @@ recent = "zk edit --sort created- --created-after 'last two weeks' --interactive
|
||||
|
||||
### Edit the configuration file
|
||||
|
||||
Here's a concrete example using environment variables, in particular `ZK_PATH`. Note the double quotes around the path.
|
||||
Here's a concrete example using environment variables, in particular `ZK_NOTEBOOK_DIR`. Note the double quotes around the path.
|
||||
|
||||
```toml
|
||||
conf = '$EDITOR "$ZK_PATH/.zk/config.toml"'
|
||||
conf = '$EDITOR "$ZK_NOTEBOOK_DIR/.zk/config.toml"'
|
||||
```
|
||||
|
||||
### List paths in a command-line friendly fashion
|
||||
|
@ -34,12 +34,12 @@ That is a bit of a mouthful for a command called every day. Would it not be bett
|
||||
|
||||
```toml
|
||||
[alias]
|
||||
daily = 'zk new --no-input "$ZK_PATH/journal/daily"'
|
||||
daily = 'zk new --no-input "$ZK_NOTEBOOK_DIR/journal/daily"'
|
||||
```
|
||||
|
||||
Let's unpack this alias:
|
||||
|
||||
* `zk new` will refuse to overwrite notes. If you already created today's note, it will instead ask you if you wish to edit it. Using `--no-input` skips the prompt and edit the existing note right away.
|
||||
* `$ZK_PATH` is set to the absolute path of the current [notebook](notebook.md) when running an alias. Using it allows you to run `zk daily` no matter where you are in the notebook folder hierarchy.
|
||||
* We need to use double quotes around `$ZK_PATH`, otherwise it will not be expanded.
|
||||
* `$ZK_NOTEBOOK_DIR` is set to the absolute path of the current [notebook](notebook.md) when running an alias. Using it allows you to run `zk daily` no matter where you are in the notebook folder hierarchy.
|
||||
* We need to use double quotes around `$ZK_NOTEBOOK_DIR`, otherwise it will not be expanded.
|
||||
|
||||
|
@ -4,7 +4,7 @@ A *notebook* is a directory containing a collection of notes managed by `zk`. No
|
||||
|
||||
To create a new notebook, simply run `zk init [<directory>]`.
|
||||
|
||||
Most `zk` commands are operating "Git-style" on the notebook containing the current working directory (or one of its parents).
|
||||
Most `zk` commands are operating "Git-style" on the notebook containing the current working directory (or one of its parents). However, you can explicitly set which notebook to use with `--notebook-dir` or the `ZK_NOTEBOOK_DIR` environment variable. Setting `ZK_NOTEBOOK_DIR` in your shell configuration (e.g. `~/.profile`) can be used to define a default notebook which `zk` commands will use when the working directory is not in another notebook.
|
||||
|
||||
## Anatomy of a notebook
|
||||
|
||||
|
72
main.go
72
main.go
@ -1,10 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
"github.com/mickael-menu/zk/cmd"
|
||||
@ -23,7 +23,8 @@ var cli struct {
|
||||
List cmd.List `cmd group:"notes" help:"List notes matching the given criteria."`
|
||||
Edit cmd.Edit `cmd group:"notes" help:"Edit notes matching the given criteria."`
|
||||
|
||||
NoInput NoInput `help:"Never prompt or ask for confirmation."`
|
||||
NoInput NoInput `help:"Never prompt or ask for confirmation."`
|
||||
NotebookDir string `placeholder:"PATH" help:"Run as if zk was started in <PATH> instead of the current working directory."`
|
||||
|
||||
ShowHelp ShowHelp `cmd default:"1" hidden:true`
|
||||
Version kong.VersionFlag `help:"Print zk version." hidden:true`
|
||||
@ -57,9 +58,14 @@ func main() {
|
||||
container, err := cmd.NewContainer()
|
||||
fatalIfError(err)
|
||||
|
||||
// Open the notebook if there's any.
|
||||
searchPaths, err := notebookSearchPaths()
|
||||
fatalIfError(err)
|
||||
container.OpenNotebook(searchPaths)
|
||||
|
||||
// Run the alias or command.
|
||||
if isAlias, err := runAlias(container, os.Args[1:]); isAlias {
|
||||
fatalIfError(err)
|
||||
|
||||
} else {
|
||||
ctx := kong.Parse(&cli, options(container)...)
|
||||
err := ctx.Run(container)
|
||||
@ -112,6 +118,10 @@ func runAlias(container *cmd.Container, args []string) (bool, error) {
|
||||
// Prevent infinite loop if an alias calls itself.
|
||||
os.Setenv("ZK_RUNNING_ALIAS", alias)
|
||||
|
||||
// Move to the provided working directory if it is not the current one,
|
||||
// before running the alias.
|
||||
cmdStr = `cd "` + container.WorkingDir + `" && ` + cmdStr
|
||||
|
||||
cmd := executil.CommandFromString(cmdStr, args[1:]...)
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
@ -130,3 +140,59 @@ func runAlias(container *cmd.Container, args []string) (bool, error) {
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// notebookSearchPaths returns the places where zk will look for a notebook.
|
||||
// The first successful candidate will be used as the working directory from
|
||||
// which path arguments are relative from.
|
||||
//
|
||||
// By order of precedence:
|
||||
// 1. --notebook-dir flag
|
||||
// 2. current working directory
|
||||
// 3. ZK_NOTEBOOK_DIR environment variable
|
||||
func notebookSearchPaths() ([]string, error) {
|
||||
// 1. --notebook-dir flag
|
||||
notebookDir, err := parseNotebookDirFlag()
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
if notebookDir != "" {
|
||||
// If --notebook-dir is used, we want to only check there to report errors.
|
||||
return []string{notebookDir}, nil
|
||||
}
|
||||
|
||||
candidates := []string{}
|
||||
|
||||
// 2. current working directory
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
candidates = append(candidates, wd)
|
||||
|
||||
// 3. ZK_NOTEBOOK_DIR environment variable
|
||||
if notebookDir, ok := os.LookupEnv("ZK_NOTEBOOK_DIR"); ok {
|
||||
candidates = append(candidates, notebookDir)
|
||||
}
|
||||
|
||||
return candidates, nil
|
||||
}
|
||||
|
||||
// parseNotebookDir returns the path to the notebook specified with the
|
||||
// --notebook-dir flag.
|
||||
//
|
||||
// We need to parse the --notebook-dir flag before Kong, because we might need
|
||||
// it to resolve zk command aliases before parsing the CLI.
|
||||
func parseNotebookDirFlag() (string, error) {
|
||||
foundFlag := false
|
||||
for _, arg := range os.Args {
|
||||
if arg == "--notebook-dir" {
|
||||
foundFlag = true
|
||||
} else if foundFlag {
|
||||
return arg, nil
|
||||
}
|
||||
}
|
||||
if foundFlag {
|
||||
return "", errors.New("--notebook-dir requires an argument")
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user