Skip to content

Commit 2d3ee4b

Browse files
committed
refactor(cli): make readme an optional field and don't system space init
1 parent f550c06 commit 2d3ee4b

File tree

12 files changed

+238
-206
lines changed

12 files changed

+238
-206
lines changed

cells/std/cli.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ in {
2121

2222
src = ./cli;
2323

24-
vendorSha256 = "sha256-nT98rJtnATPNQYi1a29H7H8xd4JLEACSawR+Cn5eyYg=";
24+
vendorHash = "sha256-1le14dcr2b8TDUNdhIFbZGX3khQoCcEZRH86eqlZaQE=";
2525

2626
nativeBuildInputs = [nixpkgs.installShellFiles];
2727

cells/std/cli/cli.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/spf13/cobra"
1414

1515
"github.com/divnix/std/data"
16+
"github.com/divnix/std/flake"
1617
)
1718

1819
type Spec struct {
@@ -45,7 +46,7 @@ var rootCmd = &cobra.Command{
4546
if err := re.MatchToTarget(args[0], s); err != nil {
4647
return err
4748
}
48-
nix, nixargs, err := GetActionEvalCmdArgs(s.Cell, s.Block, s.Target, s.Action)
49+
nix, nixargs, err := flake.GetActionEvalCmdArgs(s.Cell, s.Block, s.Target, s.Action)
4950
if err != nil {
5051
// TODO: remove non relevant nix fragment search paths from error msg
5152
return err
@@ -67,7 +68,7 @@ Use this command to cold-start or refresh the CLI cache.
6768
The TUI does this automatically, but the command completion needs manual initialization of the CLI cache.`,
6869
Args: cobra.NoArgs,
6970
RunE: func(cmd *cobra.Command, args []string) error {
70-
c, key, loadCmd, buf, err := LoadFlakeCmd()
71+
c, key, loadCmd, buf, err := flake.LoadFlakeCmd()
7172
if err != nil {
7273
return fmt.Errorf("while loading flake (cmd '%v'): %w", loadCmd, err)
7374
}
@@ -84,7 +85,7 @@ Returns a non-zero exit code and an error message if the repository is not a val
8485
The TUI does this automatically.`,
8586
Args: cobra.NoArgs,
8687
RunE: func(cmd *cobra.Command, args []string) error {
87-
_, _, loadCmd, _, err := LoadFlakeCmd()
88+
_, _, loadCmd, _, err := flake.LoadFlakeCmd()
8889
if err != nil {
8990
return fmt.Errorf("while loading flake (cmd '%v'): %w", loadCmd, err)
9091
}
@@ -105,7 +106,7 @@ Shows a list of all available targets. Can be used as an alternative to the TUI.
105106
Also loads the CLI cache, if no cache is found. Reads the cache, otherwise.`,
106107
Args: cobra.NoArgs,
107108
RunE: func(cmd *cobra.Command, args []string) error {
108-
cache, key, loadCmd, buf, err := LoadFlakeCmd()
109+
cache, key, loadCmd, buf, err := flake.LoadFlakeCmd()
109110
if err != nil {
110111
return fmt.Errorf("while loading flake (cmd '%v'): %w", loadCmd, err)
111112
}
@@ -131,7 +132,8 @@ Also loads the CLI cache, if no cache is found. Reads the cache, otherwise.`,
131132
for _, o := range c.Blocks {
132133
for _, t := range o.Targets {
133134
for _, a := range t.Actions {
134-
fmt.Fprintln(w, fmt.Sprintf("//%s/%s/%s:%s\t--\t%s: %s", c.Cell, o.Block, t.Target, a.Name, t.Description, a.Descr))
135+
fmt.Fprintln(w, fmt.Sprintf(
136+
"//%s/%s/%s:%s\t--\t%s: %s", c.Name, o.Name, t.Name, a.Name, t.Description(), a.Description()))
135137
}
136138
}
137139
}
@@ -156,7 +158,7 @@ func init() {
156158
// completes: '//cell/block/target:action'
157159
carapace.Gen(rootCmd).PositionalCompletion(
158160
carapace.ActionCallback(func(c carapace.Context) carapace.Action {
159-
cache, key, _, _, err := LoadFlakeCmd()
161+
cache, key, _, _, err := flake.LoadFlakeCmd()
160162
if err != nil {
161163
return carapace.ActionMessage(fmt.Sprintf("%v\n", err))
162164
}

cells/std/cli/data/data.go

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,41 @@ package data
22

33
import (
44
"fmt"
5+
6+
"github.com/hymkor/go-lazy"
7+
8+
"github.com/divnix/std/flake"
59
)
610

711
var (
812
targetTemplate = "//%s/%s/%s"
913
actionTemplate = "//%s/%s/%s:%s"
14+
noReadme = "🥺 No Readme available ...\n\n💡 But hey! You could create one ...\n\n💪 Start with: `$EDITOR %s`\n\n👉 It will also be rendered in the docs!"
15+
noDescription = "🥺 Target has no 'meta.description' attribute"
16+
cellsFrom = lazy.Of[string]{
17+
New: func() string {
18+
if s, err := flake.GetCellsFrom(); err != nil {
19+
return "${cellsFrom}"
20+
} else {
21+
return s
22+
}
23+
},
24+
}
1025
)
1126

1227
type Root struct {
1328
Cells []Cell
1429
}
1530

1631
type Cell struct {
17-
Cell string `json:"cell"`
18-
Readme string `json:"readme"`
32+
Name string `json:"cell"`
33+
Readme *string `json:"readme,omitempty"`
1934
Blocks []Block `json:"cellBlocks"`
2035
}
2136

2237
type Block struct {
23-
Block string `json:"cellBlock"`
24-
Readme string `json:"readme"`
38+
Name string `json:"cellBlock"`
39+
Readme *string `json:"readme,omitempty"`
2540
Blocktype string `json:"blockType"`
2641
Targets []Target `json:"targets"`
2742
}
@@ -36,11 +51,19 @@ func (a Action) Description() string { return a.Descr }
3651
func (a Action) FilterValue() string { return a.Title() }
3752

3853
type Target struct {
39-
Target string `json:"name"`
40-
Readme string `json:"readme"`
41-
Deps []string `json:"deps"`
42-
Description string `json:"description"`
43-
Actions []Action `json:"actions"`
54+
Name string `json:"name"`
55+
Readme *string `json:"readme,omitempty"`
56+
Deps []string `json:"deps"`
57+
Descr *string `json:"description,omitempty"`
58+
Actions []Action `json:"actions"`
59+
}
60+
61+
func (t Target) Description() string {
62+
if t.Descr != nil {
63+
return "💡 " + *t.Descr
64+
} else {
65+
return noDescription
66+
}
4467
}
4568

4669
func (r *Root) Select(ci, oi, ti int) (Cell, Block, Target) {
@@ -55,7 +78,7 @@ func (r *Root) Select(ci, oi, ti int) (Cell, Block, Target) {
5578
func (r *Root) ActionArg(ci, oi, ti, ai int) string {
5679
c, o, t := r.Select(ci, oi, ti)
5780
a := t.Actions[ai]
58-
return fmt.Sprintf(actionTemplate, c.Cell, o.Block, t.Target, a.Name)
81+
return fmt.Sprintf(actionTemplate, c.Name, o.Name, t.Name, a.Name)
5982
}
6083

6184
func (r *Root) ActionTitle(ci, oi, ti, ai int) string {
@@ -72,22 +95,52 @@ func (r *Root) ActionDescription(ci, oi, ti, ai int) string {
7295

7396
func (r *Root) TargetTitle(ci, oi, ti int) string {
7497
c, o, t := r.Select(ci, oi, ti)
75-
return fmt.Sprintf(targetTemplate, c.Cell, o.Block, t.Target)
98+
return fmt.Sprintf(targetTemplate, c.Name, o.Name, t.Name)
7699
}
77100

78101
func (r *Root) TargetDescription(ci, oi, ti int) string {
79102
_, _, t := r.Select(ci, oi, ti)
80-
return t.Description
81-
}
82-
func (r *Root) Cell(ci, oi, ti int) string { c, _, _ := r.Select(ci, oi, ti); return c.Cell }
83-
func (r *Root) CellHelp(ci, oi, ti int) string { c, _, _ := r.Select(ci, oi, ti); return c.Readme }
84-
func (r *Root) HasCellHelp(ci, oi, ti int) bool { return r.CellHelp(ci, oi, ti) != "" }
85-
func (r *Root) Block(ci, oi, ti int) string { _, o, _ := r.Select(ci, oi, ti); return o.Block }
86-
func (r *Root) BlockHelp(ci, oi, ti int) string { _, o, _ := r.Select(ci, oi, ti); return o.Readme }
87-
func (r *Root) HasBlockHelp(ci, oi, ti int) bool { return r.BlockHelp(ci, oi, ti) != "" }
88-
func (r *Root) Target(ci, oi, ti int) string { _, _, t := r.Select(ci, oi, ti); return t.Target }
89-
func (r *Root) TargetHelp(ci, oi, ti int) string { _, _, t := r.Select(ci, oi, ti); return t.Readme }
90-
func (r *Root) HasTargetHelp(ci, oi, ti int) bool { return r.TargetHelp(ci, oi, ti) != "" }
103+
return t.Description()
104+
}
105+
func (r *Root) Cell(ci, oi, ti int) Cell { c, _, _ := r.Select(ci, oi, ti); return c }
106+
func (r *Root) CellName(ci, oi, ti int) string { return r.Cell(ci, oi, ti).Name }
107+
func (r *Root) CellHelp(ci, oi, ti int) string {
108+
if r.HasCellHelp(ci, oi, ti) {
109+
return *r.Cell(ci, oi, ti).Readme
110+
} else {
111+
return fmt.Sprintf(noReadme, fmt.Sprintf("%s/%s/Readme.md", cellsFrom.Value(), r.CellName(ci, oi, ti)))
112+
}
113+
}
114+
func (r *Root) HasCellHelp(ci, oi, ti int) bool {
115+
c := r.Cell(ci, oi, ti)
116+
return c.Readme != nil
117+
}
118+
func (r *Root) Block(ci, oi, ti int) Block { _, o, _ := r.Select(ci, oi, ti); return o }
119+
func (r *Root) BlockName(ci, oi, ti int) string { return r.Block(ci, oi, ti).Name }
120+
func (r *Root) BlockHelp(ci, oi, ti int) string {
121+
if r.HasBlockHelp(ci, oi, ti) {
122+
return *r.Block(ci, oi, ti).Readme
123+
} else {
124+
return fmt.Sprintf(noReadme, fmt.Sprintf("%s/%s/%s/Readme.md", cellsFrom.Value(), r.CellName(ci, oi, ti), r.BlockName(ci, oi, ti)))
125+
}
126+
}
127+
func (r *Root) HasBlockHelp(ci, oi, ti int) bool {
128+
b := r.Block(ci, oi, ti)
129+
return b.Readme != nil
130+
}
131+
func (r *Root) Target(ci, oi, ti int) Target { _, _, t := r.Select(ci, oi, ti); return t }
132+
func (r *Root) TargetName(ci, oi, ti int) string { return r.Target(ci, oi, ti).Name }
133+
func (r *Root) TargetHelp(ci, oi, ti int) string {
134+
if r.HasTargetHelp(ci, oi, ti) {
135+
return *r.Target(ci, oi, ti).Readme
136+
} else {
137+
return fmt.Sprintf(noReadme, fmt.Sprintf("%s/%s/%s/%s.md", cellsFrom.Value(), r.CellName(ci, oi, ti), r.BlockName(ci, oi, ti), r.TargetName(ci, oi, ti)))
138+
}
139+
}
140+
func (r *Root) HasTargetHelp(ci, oi, ti int) bool {
141+
t := r.Target(ci, oi, ti)
142+
return t.Readme != nil
143+
}
91144

92145
func (r *Root) Len() int {
93146
sum := 0

cells/std/cli/env.go renamed to cells/std/cli/env/env.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package main
1+
package env
22

33
import (
44
"bytes"
@@ -21,7 +21,18 @@ const (
2121
prjLastActionTmpl = "%s/.std/last-action"
2222
)
2323

24-
func setEnv() (string, string, string, string, error) {
24+
// extraNixConfig implements quality of life flags for the nix command invocation
25+
var extraNixConfig = strings.Join([]string{
26+
// can never occur: actions invoke store path copies of the flake
27+
// "warn-dirty = false",
28+
"accept-flake-config = true",
29+
"builders-use-substitutes = true",
30+
// TODO: these are unfortunately not available for setting as env flags
31+
// update-lock-file = false,
32+
// write-lock-file = false,
33+
}, "\n")
34+
35+
func SetEnv() (string, string, string, string, error) {
2536
var prjRoot string
2637
prjRoot, present := os.LookupEnv(PRJ_ROOT)
2738
if !present {

cells/std/cli/flake.go renamed to cells/std/cli/flake/flake.go

Lines changed: 30 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1-
package main
1+
package flake
22

33
import (
44
"bytes"
5-
"encoding/json"
65
"errors"
76
"fmt"
8-
"io"
97
"os"
108
"os/exec"
119
"strings"
1210

13-
"github.com/TylerBrock/colorjson"
14-
1511
"github.com/divnix/std/cache"
16-
"github.com/divnix/std/data"
12+
"github.com/divnix/std/env"
1713
)
1814

1915
type outt struct {
@@ -22,10 +18,12 @@ type outt struct {
2218
}
2319

2420
var (
25-
currentSystemArgs = []string{"eval", "--raw", "--impure", "--expr", "builtins.currentSystem"}
26-
flakeInitFragment = "%s#__std.init.%s"
27-
flakeActionsFragment = "%s#__std.actions.%s.%s.%s.%s.%s"
28-
flakeEvalJson = []string{
21+
currentSystemArgs = []string{"eval", "--raw", "--impure", "--expr", "builtins.currentSystem"}
22+
cellsFromArgs = []string{"eval", "--raw"}
23+
flakeCellsFromFragment = "%s#__std.cellsFrom"
24+
flakeInitFragment = "%s#__std.init"
25+
flakeActionsFragment = "%s#__std.actions.%s.%s.%s.%s.%s"
26+
flakeEvalJson = []string{
2927
"eval",
3028
"--json",
3129
"--no-update-lock-file",
@@ -46,7 +44,7 @@ var (
4644
}
4745
)
4846

49-
func GetNix() (string, error) {
47+
func getNix() (string, error) {
5048
nix, err := exec.LookPath("nix")
5149
if err != nil {
5250
return "", errors.New("You need to install 'nix' in order to use 'std'")
@@ -56,7 +54,7 @@ func GetNix() (string, error) {
5654

5755
func getCurrentSystem() ([]byte, error) {
5856
// detect the current system
59-
nix, err := GetNix()
57+
nix, err := getNix()
6058
if err != nil {
6159
return nil, err
6260
}
@@ -70,22 +68,33 @@ func getCurrentSystem() ([]byte, error) {
7068
return currentSystem, nil
7169
}
7270

73-
func GetInitEvalCmdArgs() (string, []string, error) {
74-
nix, err := GetNix()
71+
func GetCellsFrom() (string, error) {
72+
nix, err := getNix()
7573
if err != nil {
76-
return "", nil, err
74+
return "", err
7775
}
76+
cellsFrom, err := exec.Command(nix, append(cellsFromArgs, fmt.Sprintf(flakeCellsFromFragment, "."))...).Output()
77+
if err != nil {
78+
if exitErr, ok := err.(*exec.ExitError); ok {
79+
return "", fmt.Errorf("%w, stderr:\n%s", exitErr, exitErr.Stderr)
80+
}
81+
return "", err
82+
}
83+
return string(cellsFrom[:]), nil
84+
}
7885

79-
currentSystem, err := getCurrentSystem()
86+
func getInitEvalCmdArgs() (string, []string, error) {
87+
nix, err := getNix()
8088
if err != nil {
8189
return "", nil, err
8290
}
91+
8392
return nix, append(
84-
flakeEvalJson, fmt.Sprintf(flakeInitFragment, ".", currentSystem)), nil
93+
flakeEvalJson, fmt.Sprintf(flakeInitFragment, ".")), nil
8594
}
8695

8796
func GetActionEvalCmdArgs(c, o, t, a string) (string, []string, error) {
88-
nix, err := GetNix()
97+
nix, err := getNix()
8998
if err != nil {
9099
return "", nil, err
91100
}
@@ -94,42 +103,17 @@ func GetActionEvalCmdArgs(c, o, t, a string) (string, []string, error) {
94103
if err != nil {
95104
return "", nil, err
96105
}
97-
_, _, _, actionPath, err := setEnv()
106+
_, _, _, actionPath, err := env.SetEnv()
98107
if err != nil {
99108
return "", nil, err
100109
}
101110
return nix, append(
102111
flakeBuild(actionPath), fmt.Sprintf(flakeActionsFragment, ".", currentSystem, c, o, t, a)), nil
103112
}
104113

105-
func LoadJson(r io.Reader) (*data.Root, error) {
106-
var root = &data.Root{}
107-
108-
var r2 bytes.Buffer
109-
r1 := io.TeeReader(r, &r2)
110-
111-
var dec = json.NewDecoder(r1)
112-
113-
if err := dec.Decode(&root.Cells); err != nil {
114-
var serr *json.SyntaxError
115-
if errors.As(err, &serr) {
116-
return nil, fmt.Errorf("json syntax error: %w: string:\n%v", err, r2.String())
117-
}
118-
var obj interface{}
119-
var debugDecoder = json.NewDecoder(&r2)
120-
debugDecoder.Decode(&obj)
121-
f := colorjson.NewFormatter()
122-
f.Indent = 2
123-
s, _ := f.Marshal(obj)
124-
return nil, fmt.Errorf("%w - object: %s", err, s)
125-
}
126-
127-
return root, nil
128-
}
129-
130114
func LoadFlakeCmd() (*cache.Cache, *cache.ActionID, *exec.Cmd, *bytes.Buffer, error) {
131115

132-
nix, args, err := GetInitEvalCmdArgs()
116+
nix, args, err := getInitEvalCmdArgs()
133117
if err != nil {
134118
return nil, nil, nil, nil, err
135119
}
@@ -145,7 +129,7 @@ func LoadFlakeCmd() (*cache.Cache, *cache.ActionID, *exec.Cmd, *bytes.Buffer, er
145129
cmd.Stdout = buf
146130

147131
// initialize cache
148-
_, _, prjCacheDir, _, err := setEnv()
132+
_, _, prjCacheDir, _, err := env.SetEnv()
149133
if err != nil {
150134
return nil, nil, nil, nil, err
151135
}

0 commit comments

Comments
 (0)