Skip to content

Commit d24750e

Browse files
iignatevichdavidferlay
authored andcommitted
Move dependencies commands to bump plugin
1 parent 99f270c commit d24750e

File tree

4 files changed

+192
-5
lines changed

4 files changed

+192
-5
lines changed
File renamed without changes.

action.dependencies.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
runtime: plugin
2+
action:
3+
title: Dependencies
4+
description: "Shows dependencies and dependent resources of selected resource"
5+
alias:
6+
- deps
7+
arguments:
8+
- name: target
9+
title: Target
10+
description: Target resource
11+
required: true
12+
options:
13+
- name: source
14+
title: Source
15+
description: Resources source dir
16+
type: string
17+
default: ".compose/build"
18+
- name: mrn
19+
title: MRN
20+
description: Show MRN instead of paths
21+
type: boolean
22+
default: false
23+
- name: tree
24+
title: Tree
25+
description: "Show dependencies in tree-like output"
26+
type: boolean
27+
default: false
28+
- name: depth
29+
title: Depth
30+
description: "Limit recursion lookup depth"
31+
type: integer
32+
default: 99

dependencies.go

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package plasmactlbump
2+
3+
import (
4+
"fmt"
5+
"sort"
6+
7+
"github.com/launchrctl/launchr"
8+
"github.com/launchrctl/launchr/pkg/action"
9+
"github.com/skilld-labs/plasmactl-bump/v2/pkg/sync"
10+
)
11+
12+
type dependenciesAction struct {
13+
action.WithLogger
14+
action.WithTerm
15+
}
16+
17+
func (a *dependenciesAction) run(target, source string, toPath, showTree bool, depth int8) error {
18+
searchMrn := target
19+
_, errConvert := sync.ConvertMRNtoPath(searchMrn)
20+
21+
if errConvert != nil {
22+
r := sync.BuildResourceFromPath(target, source)
23+
if r == nil {
24+
return fmt.Errorf("not valid resource %q", target)
25+
}
26+
27+
searchMrn = r.GetName()
28+
}
29+
30+
var header string
31+
if toPath {
32+
header, _ = sync.ConvertMRNtoPath(searchMrn)
33+
} else {
34+
header = searchMrn
35+
}
36+
37+
inv, err := sync.NewInventory(source, a.Log())
38+
if err != nil {
39+
return err
40+
}
41+
parents := inv.GetRequiredByResources(searchMrn, depth)
42+
if len(parents) > 0 {
43+
a.Term().Info().Println("Dependent resources:")
44+
if showTree {
45+
var parentsTree forwardTree = inv.GetRequiredByMap()
46+
parentsTree.print(a.Term(), header, "", 1, depth, searchMrn, toPath)
47+
} else {
48+
a.printList(parents, toPath)
49+
}
50+
}
51+
52+
children := inv.GetDependsOnResources(searchMrn, depth)
53+
if len(children) > 0 {
54+
a.Term().Info().Println("Dependencies:")
55+
if showTree {
56+
var childrenTree forwardTree = inv.GetDependsOnMap()
57+
childrenTree.print(a.Term(), header, "", 1, depth, searchMrn, toPath)
58+
} else {
59+
a.printList(children, toPath)
60+
}
61+
}
62+
63+
return nil
64+
}
65+
66+
func (a *dependenciesAction) printList(items map[string]bool, toPath bool) {
67+
keys := make([]string, 0, len(items))
68+
for k := range items {
69+
keys = append(keys, k)
70+
}
71+
72+
sort.Strings(keys)
73+
for _, item := range keys {
74+
res := item
75+
if toPath {
76+
res, _ = sync.ConvertMRNtoPath(res)
77+
}
78+
79+
a.Term().Print(res + "\n")
80+
}
81+
}
82+
83+
type forwardTree map[string]*sync.OrderedMap[bool]
84+
85+
func (t forwardTree) print(printer *launchr.Terminal, header, indent string, depth, limit int8, parent string, toPath bool) {
86+
if indent == "" {
87+
printer.Printfln(header)
88+
}
89+
90+
if depth == limit {
91+
return
92+
}
93+
94+
children, ok := t[parent]
95+
if !ok {
96+
return
97+
}
98+
99+
keys := children.Keys()
100+
sort.Strings(keys)
101+
102+
for i, node := range keys {
103+
isLast := i == len(keys)-1
104+
var newIndent, edge string
105+
106+
if isLast {
107+
newIndent = indent + " "
108+
edge = "└── "
109+
} else {
110+
newIndent = indent + "│ "
111+
edge = "├── "
112+
}
113+
114+
value := node
115+
if toPath {
116+
value, _ = sync.ConvertMRNtoPath(value)
117+
}
118+
119+
printer.Printfln(indent + edge + value)
120+
t.print(printer, "", newIndent, depth+1, limit, node, toPath)
121+
}
122+
}

plugin.go

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ package plasmactlbump
44
import (
55
"context"
66
_ "embed"
7+
"fmt"
8+
"os"
79

810
"github.com/launchrctl/keyring"
911
"github.com/launchrctl/launchr"
1012
"github.com/launchrctl/launchr/pkg/action"
1113
)
1214

13-
//go:embed action.yaml
14-
var actionYaml []byte
15+
//go:embed action.bump.yaml
16+
var actionBumpYaml []byte
17+
18+
//go:embed action.dependencies.yaml
19+
var actionDependenciesYaml []byte
1520

1621
func init() {
1722
launchr.RegisterPlugin(&Plugin{})
@@ -39,8 +44,8 @@ func (p *Plugin) OnAppInit(app launchr.App) error {
3944

4045
// DiscoverActions implements [launchr.ActionDiscoveryPlugin] interface.
4146
func (p *Plugin) DiscoverActions(_ context.Context) ([]*action.Action, error) {
42-
a := action.NewFromYAML("bump", actionYaml)
43-
a.SetRuntime(action.NewFnRuntime(func(_ context.Context, a *action.Action) error {
47+
ba := action.NewFromYAML("bump", actionBumpYaml)
48+
ba.SetRuntime(action.NewFnRuntime(func(_ context.Context, a *action.Action) error {
4449
input := a.Input()
4550
doSync := input.Opt("sync").(bool)
4651
dryRun := input.Opt("dry-run").(bool)
@@ -88,7 +93,35 @@ func (p *Plugin) DiscoverActions(_ context.Context) ([]*action.Action, error) {
8893

8994
return nil
9095
}))
91-
return []*action.Action{a}, nil
96+
97+
da := action.NewFromYAML("dependencies", actionDependenciesYaml)
98+
da.SetRuntime(action.NewFnRuntime(func(_ context.Context, a *action.Action) error {
99+
log, _, _, term := getLogger(a)
100+
101+
input := a.Input()
102+
source := input.Opt("source").(string)
103+
if _, err := os.Stat(source); os.IsNotExist(err) {
104+
term.Warning().Printfln("%s doesn't exist, fallback to current dir", source)
105+
source = "."
106+
} else {
107+
term.Info().Printfln("Selected source is %s", source)
108+
}
109+
110+
showPaths := input.Opt("mrn").(bool)
111+
showTree := input.Opt("tree").(bool)
112+
depth := int8(input.Opt("depth").(int)) //nolint:gosec
113+
if depth == 0 {
114+
return fmt.Errorf("depth value should not be zero")
115+
}
116+
117+
target := input.Arg("target").(string)
118+
dependencies := &dependenciesAction{}
119+
dependencies.SetLogger(log)
120+
dependencies.SetTerm(term)
121+
return dependencies.run(target, source, !showPaths, showTree, depth)
122+
}))
123+
124+
return []*action.Action{ba, da}, nil
92125
}
93126

94127
func getLogger(a *action.Action) (*launchr.Logger, launchr.LogLevel, launchr.Streams, *launchr.Terminal) {

0 commit comments

Comments
 (0)