Skip to content

Commit 1591b79

Browse files
authored
Merge pull request #19 from jrswab/0.7.0
v0.7.0
2 parents 3e2b921 + ffafcb2 commit 1591b79

File tree

7 files changed

+139
-23
lines changed

7 files changed

+139
-23
lines changed

.github/workflows/go.yml

+27-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11

2-
name: Test
2+
name: Check
33

44
on:
55
push:
66
branches: [ "master" ]
77
pull_request:
8-
branches: [ "master" ]
98

109
jobs:
1110

12-
build:
11+
lint:
1312
runs-on: ubuntu-latest
1413
steps:
1514
- uses: actions/checkout@v4
@@ -19,8 +18,31 @@ jobs:
1918
with:
2019
go-version: '1.23'
2120

22-
- name: Build
23-
run: go build -v ./...
21+
- name: Lint
22+
uses: golangci/[email protected]
23+
24+
test:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
29+
- name: Set up Go
30+
uses: actions/setup-go@v4
31+
with:
32+
go-version: '1.23'
2433

2534
- name: Test
2635
run: go test -v ./...
36+
37+
build:
38+
runs-on: ubuntu-latest
39+
steps:
40+
- uses: actions/checkout@v4
41+
42+
- name: Set up Go
43+
uses: actions/setup-go@v4
44+
with:
45+
go-version: '1.23'
46+
47+
- name: Build
48+
run: go build -v ./...

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
9+
### Added
10+
- Added "-a" flag to append text directly to the current journal page.
911

1012
## [0.6.0]
1113
### Added

main.go

+14
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ func main() {
2525
lsqCfgFileName := flag.String("c", "config.edn", "The config.edn file to use.")
2626
editorType := flag.String("e", "EDITOR", "The editor to use.")
2727
specDate := flag.String("s", "", "Open a specific journal. Use yyyy-MM-dd after the flag.")
28+
apnd := flag.String("a", "", "Append text to the current journal page. This will not open $EDITOR or the TUI.")
2829

2930
// Parse flags
3031
flag.Parse()
@@ -75,6 +76,18 @@ func main() {
7576
date = parsedDate.Format(config.ConvertDateFormat(cfg.FileNameFmt))
7677
}
7778

79+
if *apnd != "" {
80+
path := system.CreateFilePath(cfg, journalsDir, date)
81+
err := system.AppendToFile(path, *apnd)
82+
if err != nil {
83+
log.Printf("Error appending data to file: %v\n", err)
84+
os.Exit(1)
85+
}
86+
87+
// Don't open $EDITOR or TUI when append flag is used.
88+
return
89+
}
90+
7891
journalPath, err := system.GetJournal(cfg, journalsDir, date)
7992
if err != nil {
8093
log.Printf("Error setting journal path: %v\n", err)
@@ -124,3 +137,4 @@ func loadEditor(editor, path string) {
124137
os.Exit(1)
125138
}
126139
}
140+

system/journal.go

+35-2
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,20 @@ import (
1010
"github.com/jrswab/lsq/config"
1111
)
1212

13-
func GetJournal(cfg *config.Config, journalsDir, date string) (string, error) {
13+
func CreateFilePath(cfg *config.Config, journalsDir, date string) string {
14+
1415
// Construct today's journal file path
1516
var extension = ".md"
1617
if cfg.PreferredFmt == "Org" {
1718
extension = ".org"
1819
}
1920

2021
// Create the path for the specified date.
21-
path := filepath.Join(journalsDir, fmt.Sprintf("%s%s", date, extension))
22+
return filepath.Join(journalsDir, fmt.Sprintf("%s%s", date, extension))
23+
}
24+
25+
func GetJournal(cfg *config.Config, journalsDir, date string) (string, error) {
26+
path := CreateFilePath(cfg, journalsDir, date)
2227

2328
// Create file if it doesn't exist
2429
_, err := os.Stat(path)
@@ -32,3 +37,31 @@ func GetJournal(cfg *config.Config, journalsDir, date string) (string, error) {
3237

3338
return path, nil
3439
}
40+
41+
func AppendToFile(path, content string) error {
42+
bc := fmt.Sprintf("- %s", content)
43+
44+
// Try to create new file with O_EXCL
45+
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
46+
if err == nil {
47+
// Successfully created new file
48+
defer file.Close()
49+
return os.WriteFile(path, []byte(bc), 0644)
50+
}
51+
52+
// If error is not "file exists", return the error
53+
// (it should have been created at this point)
54+
if !os.IsExist(err) {
55+
return err
56+
}
57+
58+
// File exists, append to it
59+
file, err = os.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0644)
60+
if err != nil {
61+
return err
62+
}
63+
defer file.Close()
64+
65+
_, err = file.WriteString(fmt.Sprintf("\n%s", bc))
66+
return err
67+
}

system/journal_test.go

+61-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package system
1+
package system_test
22

33
import (
44
"os"
@@ -8,6 +8,7 @@ import (
88
"time"
99

1010
"github.com/jrswab/lsq/config"
11+
"github.com/jrswab/lsq/system"
1112
i "github.com/jrswab/lsq/tests/integration"
1213
)
1314

@@ -93,7 +94,7 @@ func TestBasicJournalCreation(t *testing.T) {
9394
}
9495
}
9596

96-
cfg, err := LoadConfig(tc.helper.ConfigPath)
97+
cfg, err := system.LoadConfig(tc.helper.ConfigPath)
9798
if err != nil {
9899
t.Fatalf("Failed to load config file: %v", err)
99100
}
@@ -114,7 +115,7 @@ func TestBasicJournalCreation(t *testing.T) {
114115
}
115116

116117
// Get journal path and create the journal entry if needed
117-
expectedPath, err := GetJournal(cfg, helper.JournalsDir, date)
118+
expectedPath, err := system.GetJournal(cfg, helper.JournalsDir, date)
118119
if err != nil {
119120
t.Fatalf("Failed to get journal file: %v", err)
120121
}
@@ -135,3 +136,60 @@ func TestBasicJournalCreation(t *testing.T) {
135136
})
136137
}
137138
}
139+
140+
func TestAppendToFile(t *testing.T) {
141+
tmpDir, err := os.MkdirTemp("", "test")
142+
if err != nil {
143+
t.Fatal(err)
144+
}
145+
defer os.RemoveAll(tmpDir)
146+
147+
t.Run("new file creation", func(t *testing.T) {
148+
testFile := filepath.Join(tmpDir, "new.md")
149+
if err := system.AppendToFile(testFile, "new content"); err != nil {
150+
t.Errorf("Failed to create new file: %v", err)
151+
}
152+
153+
content, err := os.ReadFile(testFile)
154+
if err != nil {
155+
t.Fatal(err)
156+
}
157+
expected := "- new content"
158+
if string(content) != expected {
159+
t.Errorf("Expected %q, got %q", expected, string(content))
160+
}
161+
})
162+
163+
t.Run("append to existing", func(t *testing.T) {
164+
testFile := filepath.Join(tmpDir, "existing.md")
165+
if err := system.AppendToFile(testFile, "first"); err != nil {
166+
t.Fatal(err)
167+
}
168+
if err := system.AppendToFile(testFile, "second"); err != nil {
169+
t.Errorf("Failed to append: %v", err)
170+
}
171+
172+
content, err := os.ReadFile(testFile)
173+
if err != nil {
174+
t.Fatal(err)
175+
}
176+
expected := "- first\n- second"
177+
if string(content) != expected {
178+
t.Errorf("Expected %q, got %q", expected, string(content))
179+
}
180+
})
181+
182+
t.Run("permission denied", func(t *testing.T) {
183+
readOnlyDir := filepath.Join(tmpDir, "readonly")
184+
if err := os.Mkdir(readOnlyDir, 0500); err != nil {
185+
t.Fatal(err)
186+
}
187+
188+
testFile := filepath.Join(readOnlyDir, "test.md")
189+
err := system.AppendToFile(testFile, "content")
190+
if err == nil {
191+
t.Error("Expected error for read-only directory")
192+
}
193+
})
194+
}
195+

trie/trie.go

-4
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,6 @@ func (t *Trie) InsertFileName(fileName string) {
128128
// Mark this as end of the word to help avoid false positives.
129129
current.IsEndOfWord = true
130130
current.FileName = fileName
131-
132-
return
133131
}
134132

135133
func (t *Trie) InsertAlias(alias, fileName string) {
@@ -158,8 +156,6 @@ func (t *Trie) InsertAlias(alias, fileName string) {
158156
current.IsEndOfWord = true
159157
current.FileName = fileName
160158
current.IsAlias = true
161-
162-
return
163159
}
164160

165161
func removeNonAlpha(fileName string) string {

tui/tui.go

-9
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,6 @@ type searchState struct {
2121
selectedIndex int
2222
}
2323

24-
// Message types for search operations
25-
type searchToggleMsg struct{}
26-
type searchUpdateMsg struct {
27-
query string
28-
}
29-
type searchSelectMsg struct {
30-
index int
31-
}
32-
3324
type tuiModel struct {
3425
textarea textarea.Model
3526
config *config.Config

0 commit comments

Comments
 (0)