Skip to content

Commit 4e844a7

Browse files
bevel-zgatesjotaen
andauthored
Add --create flag for klog bookmarks set
Resolves https://github.com/jotaen/klog/issues/310 Co-authored-by: Jan Heuermann <[email protected]>
1 parent ac17267 commit 4e844a7

File tree

3 files changed

+64
-8
lines changed

3 files changed

+64
-8
lines changed

klog/app/cli/bookmarks.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package cli
22

33
import (
4+
"strings"
5+
46
"github.com/jotaen/klog/klog/app"
57
"github.com/jotaen/klog/klog/app/cli/util"
6-
"strings"
78
)
89

910
type Bookmarks struct {
@@ -24,7 +25,7 @@ type Bookmarks struct {
2425
func (opt *Bookmarks) Help() string {
2526
return `
2627
Bookmarks allow you to interact with often-used files via an alias, independent of your current working directory.
27-
You can think of a bookmark as some sort of klog-specific symlink, that’s always available when you invoke klog, and that resolves to the designated file.
28+
You can think of a bookmark as some sort of klog-specific symlink, that’s always available when you invoke klog, and that resolves to the designated target file.
2829
Use the subcommands below to set up and manage your bookmarks.
2930
3031
A bookmark name is denoted by the prefix '@'. For example, if you have a bookmark named '@work', that points to a .klg file, you can use klog like this:
@@ -38,6 +39,8 @@ This is useful in case you only have one main file at a time, and allows you to
3839
3940
klog total
4041
klog start --summary 'Started new project'
42+
43+
When creating a bookmark, you can also create the respective target file by using the '--create' flag.
4144
`
4245
}
4346

@@ -89,9 +92,10 @@ func (opt *BookmarksInfo) Run(ctx app.Context) error {
8992
}
9093

9194
type BookmarksSet struct {
92-
File string `arg:"" type:"string" predictor:"file" help:".klg source file"`
93-
Name string `arg:"" name:"bookmark" type:"string" optional:"1" help:"The name of the bookmark."`
94-
Force bool `name:"force" help:"Force to set, even if target file does not exist or is invalid"`
95+
File string `arg:"" type:"string" predictor:"file" help:".klg target file"`
96+
Name string `arg:"" name:"bookmark" type:"string" optional:"1" help:"The name of the bookmark."`
97+
Create bool `name:"create" short:"c" help:"Create the target file"`
98+
Force bool `name:"force" help:"Force to set, even if target file does not exist or is invalid"`
9599
util.QuietArgs
96100
}
97101

@@ -100,6 +104,14 @@ func (opt *BookmarksSet) Run(ctx app.Context) error {
100104
if err != nil {
101105
return err
102106
}
107+
108+
if opt.Create {
109+
cErr := app.CreateEmptyFile(file)
110+
if cErr != nil {
111+
return cErr
112+
}
113+
}
114+
103115
if !opt.Force {
104116
_, rErr := ctx.ReadInputs(app.FileOrBookmarkName(file.Path()))
105117
if rErr != nil {
@@ -128,10 +140,14 @@ func (opt *BookmarksSet) Run(ctx app.Context) error {
128140
}
129141
if !opt.Quiet {
130142
if didBookmarkAlreadyExist {
131-
ctx.Print("Changed bookmark:\n")
143+
ctx.Print("Changed bookmark")
132144
} else {
133-
ctx.Print("Created new bookmark:\n")
145+
ctx.Print("Created new bookmark")
146+
}
147+
if opt.Create {
148+
ctx.Print(" and created target file")
134149
}
150+
ctx.Print(":\n")
135151
}
136152
ctx.Print(bookmark.Name().ValuePretty() + " -> " + bookmark.Target().Path() + "\n")
137153
return nil

klog/app/file.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,31 @@ func WriteToFile(target File, contents string) Error {
131131
return nil
132132
}
133133

134+
// CreateEmptyFile creates a new file on disk.
135+
// It returns an error if the file already exists, or if the file cannot be
136+
// created.
137+
func CreateEmptyFile(file File) Error {
138+
if _, sErr := os.Stat(file.Path()); !os.IsNotExist(sErr) {
139+
return NewErrorWithCode(
140+
GENERAL_ERROR,
141+
"Cannot create file",
142+
"There is already a file at that location",
143+
sErr,
144+
)
145+
}
146+
// Note: `os.Create` would truncate the file if it already exists.
147+
_, cErr := os.Create(file.Path())
148+
if cErr != nil {
149+
return NewErrorWithCode(
150+
GENERAL_ERROR,
151+
"Cannot create file",
152+
"Please check the file name and permissions",
153+
cErr,
154+
)
155+
}
156+
return nil
157+
}
158+
134159
// ReadStdin reads the entire input from stdin and returns it as string.
135160
// It returns an error if stdin cannot be accessed, or if reading from it fails.
136161
func ReadStdin() (string, Error) {

klog/app/main/cli_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestPrintAppErrors(t *testing.T) {
4646
assert.True(t, strings.Contains(out[2], "There is already an open range in this record"), out)
4747
}
4848

49-
func TestBookmarkFile(t *testing.T) {
49+
func TestConfigureAndUseBookmark(t *testing.T) {
5050
klog := &Env{
5151
files: map[string]string{
5252
"test.klg": "2020-01-01\nSome stuff\n\t1h7m\n",
@@ -71,6 +71,21 @@ func TestBookmarkFile(t *testing.T) {
7171
assert.True(t, strings.Contains(out[3], "1h7m"), out)
7272
}
7373

74+
func TestCreateBookmarkTargetFileOnDemand(t *testing.T) {
75+
klog := &Env{}
76+
out := klog.run(
77+
[]string{"bookmarks", "set", "--create", "test.klg", "tst"},
78+
[]string{"bookmarks", "set", "--create", "test.klg", "tst"},
79+
)
80+
// Out 0 like: `Created new bookmark`, `@tst -> /tmp/.../test.klg`
81+
assert.True(t, strings.Contains(out[0], "Created new bookmark and created target file:"), out)
82+
assert.True(t, strings.Contains(out[0], "@tst"), out)
83+
assert.True(t, strings.Contains(out[0], "test.klg"), out)
84+
// Out 1 like: `Error: Cannot create file`, `There is already a file at that location`
85+
assert.True(t, strings.Contains(out[1], "Error: Cannot create file"), out)
86+
assert.True(t, strings.Contains(out[1], "There is already a file at that location"), out)
87+
}
88+
7489
func TestWriteToFile(t *testing.T) {
7590
klog := &Env{
7691
files: map[string]string{

0 commit comments

Comments
 (0)