Skip to content

Commit 19af9a3

Browse files
committed
build: add generic github repo fetching utility
* add leaflet lexicons * add prod build flag
1 parent dbc1b8d commit 19af9a3

File tree

10 files changed

+422
-13
lines changed

10 files changed

+422
-13
lines changed

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,53 @@ go install
3030
### First Steps
3131

3232
For a comprehensive walkthrough including task management, time tracking, notes, and media tracking, see the [Quickstart Guide](website/docs/Quickstart.md).
33+
34+
## Development
35+
36+
Noteleaf uses [Task](https://taskfile.dev) for build automation. Development builds include additional tooling commands not available in production builds.
37+
38+
### Building
39+
40+
```sh
41+
# Production build
42+
task build
43+
44+
# Development build (with version info and dev tools)
45+
task build:dev
46+
47+
# Run tests
48+
task test
49+
task cov # ...with coverage
50+
```
51+
52+
### Development Tools
53+
54+
Dev builds (`task build:dev`) include a `tools` subcommand with maintenance utilities:
55+
56+
**Documentation Generation:**
57+
58+
```sh
59+
# Generate Docusaurus documentation
60+
noteleaf tools docgen --format docusaurus --out website/docs/manual
61+
62+
# Generate man pages
63+
noteleaf tools docgen --format man --out docs/manual
64+
```
65+
66+
**Data Synchronization:**
67+
68+
```sh
69+
# Fetch Leaflet lexicons from GitHub
70+
noteleaf tools fetch lexicons
71+
72+
# Fetch from a specific commit
73+
noteleaf tools fetch lexicons --sha abc123def
74+
75+
# Generic GitHub repository archive fetcher
76+
noteleaf tools fetch gh-repo \
77+
--repo owner/repo \
78+
--path schemas/ \
79+
--output local/schemas/
80+
```
81+
82+
Production builds (`task build:rc`, `task build:prod`) use the `-tags prod` flag to exclude dev tools.

Taskfile.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ tasks:
5151
- echo "Built {{.BUILD_DIR}}/{{.BINARY_NAME}}"
5252

5353
build:dev:
54-
desc: Build binary with dev version (includes git commit hash)
54+
desc: Build binary with dev version (includes git commit hash and dev tools)
5555
vars:
5656
VERSION: "{{.GIT_DESCRIBE}}"
5757
LDFLAGS: "-X {{.VERSION_PKG}}.Version={{.VERSION}} -X {{.VERSION_PKG}}.Commit={{.GIT_COMMIT}} -X {{.VERSION_PKG}}.BuildDate={{.BUILD_DATE}}"
@@ -61,7 +61,7 @@ tasks:
6161
- 'echo "Built {{.BUILD_DIR}}/{{.BINARY_NAME}} (version: {{.VERSION}})"'
6262

6363
build:rc:
64-
desc: Build release candidate binary (requires git tag with -rc suffix)
64+
desc: Build release candidate binary (requires git tag with -rc suffix, excludes dev tools)
6565
vars:
6666
VERSION: "{{.GIT_TAG}}"
6767
LDFLAGS: "-X {{.VERSION_PKG}}.Version={{.VERSION}} -X {{.VERSION_PKG}}.Commit={{.GIT_COMMIT}} -X {{.VERSION_PKG}}.BuildDate={{.BUILD_DATE}}"
@@ -72,11 +72,11 @@ tasks:
7272
msg: "Git tag must contain '-rc' for release candidate builds (e.g., v1.0.0-rc1)"
7373
cmds:
7474
- mkdir -p {{.BUILD_DIR}}
75-
- go build -ldflags "{{.LDFLAGS}}" -o {{.BUILD_DIR}}/{{.BINARY_NAME}} {{.CMD_DIR}}
75+
- go build -tags prod -ldflags "{{.LDFLAGS}}" -o {{.BUILD_DIR}}/{{.BINARY_NAME}} {{.CMD_DIR}}
7676
- 'echo "Built {{.BUILD_DIR}}/{{.BINARY_NAME}} (version: {{.VERSION}})"'
7777

7878
build:prod:
79-
desc: Build production binary (requires clean semver git tag)
79+
desc: Build production binary (requires clean semver git tag, excludes dev tools)
8080
vars:
8181
VERSION: "{{.GIT_TAG}}"
8282
LDFLAGS: "-X {{.VERSION_PKG}}.Version={{.VERSION}} -X {{.VERSION_PKG}}.Commit={{.GIT_COMMIT}} -X {{.VERSION_PKG}}.BuildDate={{.BUILD_DATE}}"
@@ -89,7 +89,7 @@ tasks:
8989
msg: "Working directory must be clean (no uncommitted changes) for production builds"
9090
cmds:
9191
- mkdir -p {{.BUILD_DIR}}
92-
- go build -ldflags "{{.LDFLAGS}}" -o {{.BUILD_DIR}}/{{.BINARY_NAME}} {{.CMD_DIR}}
92+
- go build -tags prod -ldflags "{{.LDFLAGS}}" -o {{.BUILD_DIR}}/{{.BINARY_NAME}} {{.CMD_DIR}}
9393
- 'echo "Built {{.BUILD_DIR}}/{{.BINARY_NAME}} (version: {{.VERSION}})"'
9494

9595
clean:

cmd/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"github.com/stormlightlabs/noteleaf/internal/ui"
1515
"github.com/stormlightlabs/noteleaf/internal/utils"
1616
"github.com/stormlightlabs/noteleaf/internal/version"
17-
"github.com/stormlightlabs/noteleaf/tools"
1817
)
1918

2019
var (
@@ -251,7 +250,7 @@ history of completed media.`,
251250
root.AddCommand(cmd)
252251
}
253252

254-
root.AddCommand(tools.NewDocGenCommand(root))
253+
registerTools(root)
255254

256255
opts := []fang.Option{
257256
fang.WithVersion(version.String()),

cmd/tools_dev.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//go:build !prod
2+
3+
package main
4+
5+
import (
6+
"github.com/spf13/cobra"
7+
"github.com/stormlightlabs/noteleaf/tools"
8+
)
9+
10+
// registerTools adds development tools to the root command
11+
func registerTools(root *cobra.Command) {
12+
root.AddCommand(tools.NewToolsCommand(root))
13+
}

cmd/tools_prod.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//go:build prod
2+
3+
package main
4+
5+
import "github.com/spf13/cobra"
6+
7+
// registerTools is a no-op in production builds
8+
func registerTools(*cobra.Command) {}

tools/docgen.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build !prod
2+
13
package tools
24

35
import (
@@ -324,7 +326,7 @@ func findCommand(root *cobra.Command, path []string) *cobra.Command {
324326
}
325327

326328
for _, cmd := range root.Commands() {
327-
if cmd.Name() == path[0] || contains(cmd.Aliases, path[0]) {
329+
if cmd.Name() == path[0] || slices.Contains(cmd.Aliases, path[0]) {
328330
if len(path) == 1 {
329331
return cmd
330332
}
@@ -334,8 +336,3 @@ func findCommand(root *cobra.Command, path []string) *cobra.Command {
334336

335337
return nil
336338
}
337-
338-
// contains checks if a string is in a slice
339-
func contains(slice []string, str string) bool {
340-
return slices.Contains(slice, str)
341-
}

tools/fetch.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//go:build !prod
2+
3+
package tools
4+
5+
import "github.com/spf13/cobra"
6+
7+
// NewFetchCommand creates a parent command for fetching remote resources
8+
func NewFetchCommand() *cobra.Command {
9+
cmd := &cobra.Command{
10+
Use: "fetch",
11+
Short: "Fetch remote resources",
12+
Long: `Fetch and synchronize remote resources from GitHub repositories.
13+
14+
Includes commands for fetching lexicons, schemas, and other data files.`,
15+
}
16+
17+
cmd.AddCommand(NewGHRepoCommand())
18+
cmd.AddCommand(NewLexiconsCommand())
19+
20+
return cmd
21+
}

tools/lexicon_fetch.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//go:build !prod
2+
3+
package tools
4+
5+
import (
6+
"context"
7+
8+
"github.com/spf13/cobra"
9+
)
10+
11+
// NewLexiconsCommand creates a command for fetching Leaflet lexicons
12+
func NewLexiconsCommand() *cobra.Command {
13+
var sha string
14+
var output string
15+
16+
cmd := &cobra.Command{
17+
Use: "lexicons",
18+
Short: "Fetch Leaflet lexicons from GitHub",
19+
Long: `Fetches Leaflet lexicons from the hyperlink-academy/leaflet repository.
20+
21+
This is a convenience wrapper around gh-repo with pre-configured defaults
22+
for the Leaflet lexicon repository.`,
23+
Example: ` # Fetch latest lexicons
24+
noteleaf tools fetch lexicons
25+
26+
# Fetch from a specific commit
27+
noteleaf tools fetch lexicons --sha abc123def
28+
29+
# Fetch to a custom directory
30+
noteleaf tools fetch lexicons --output ./tmp/lexicons`,
31+
RunE: func(cmd *cobra.Command, args []string) error {
32+
config := ArchiveConfig{
33+
Repo: "hyperlink-academy/leaflet",
34+
Path: "lexicons/pub/leaflet/",
35+
Output: output,
36+
SHA: sha,
37+
FormatJSON: true,
38+
}
39+
40+
ctx := cmd.Context()
41+
if ctx == nil {
42+
ctx = context.Background()
43+
}
44+
45+
return fetchAndExtractArchive(ctx, config, cmd.OutOrStdout())
46+
},
47+
}
48+
cmd.Flags().StringVar(&sha, "sha", "", "Specific commit SHA (default: latest)")
49+
cmd.Flags().StringVar(&output, "output", "lexdocs/leaflet/", "Output directory for lexicons")
50+
return cmd
51+
}

tools/registry.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//go:build !prod
2+
3+
package tools
4+
5+
import "github.com/spf13/cobra"
6+
7+
// NewToolsCommand creates a parent command for all development tools
8+
func NewToolsCommand(root *cobra.Command) *cobra.Command {
9+
cmd := &cobra.Command{
10+
Use: "tools",
11+
Short: "Development and maintenance tools",
12+
Long: `Development tools for documentation generation, data synchronization,
13+
and maintenance tasks. These commands are only available in dev builds.`,
14+
}
15+
cmd.AddCommand(NewDocGenCommand(root))
16+
cmd.AddCommand(NewFetchCommand())
17+
18+
return cmd
19+
}

0 commit comments

Comments
 (0)