Skip to content

Commit 1a696bb

Browse files
committed
feat: added basic branch pruning logic
1 parent d5e75eb commit 1a696bb

11 files changed

+138
-21
lines changed

internal/cmd/apply.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ func applyFunc(cmd *cobra.Command, _ []string) error {
5050
defer cfg.Close()
5151
ctx := cmd.Context()
5252

53-
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
53+
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
54+
if err != nil {
55+
return err
56+
}
57+
58+
dg, err := graph.ToDeploymentGraph(g)
5459
if err != nil {
5560
return err
5661
}

internal/cmd/common.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717

1818
type CommonFlags struct {
1919
configFile string
20-
siteName string
20+
site string
2121
ignoreVersion bool
2222
outputPath string
2323
varFile string
@@ -29,7 +29,7 @@ var commonFlags CommonFlags
2929
func registerCommonFlags(cmd *cobra.Command) {
3030
cmd.Flags().StringVarP(&commonFlags.configFile, "file", "f", "main.yml", "YAML file to parse.")
3131
cmd.Flags().StringVarP(&commonFlags.varFile, "var-file", "", "", "Use a variable file to parse the configuration with.")
32-
cmd.Flags().StringVarP(&commonFlags.siteName, "site", "s", "", "Site to parse. If not set parse all sites.")
32+
cmd.Flags().StringVarP(&commonFlags.site, "site", "s", "", "Site to parse. If not set parse all sites.")
3333
cmd.Flags().BoolVarP(&commonFlags.ignoreVersion, "ignore-version", "", false, "Skip MACH composer version check")
3434
cmd.Flags().StringVarP(&commonFlags.outputPath, "output-path", "", "deployments",
3535
"Outputs path to store the generated files.")
@@ -39,10 +39,6 @@ func registerCommonFlags(cmd *cobra.Command) {
3939
}
4040

4141
func preprocessCommonFlags(cmd *cobra.Command) {
42-
if commonFlags.siteName != "" {
43-
log.Warn().Msgf("Site option not implemented")
44-
}
45-
4642
handleError(cmd.MarkFlagFilename("var-file", "yml", "yaml"))
4743
handleError(cmd.MarkFlagFilename("file", "yml", "yaml"))
4844

internal/cmd/generate.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ func generateFunc(cmd *cobra.Command) error {
2626
cfg := loadConfig(cmd, true)
2727
defer cfg.Close()
2828

29-
gd, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
29+
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
30+
if err != nil {
31+
return err
32+
}
33+
34+
gd, err := graph.ToDeploymentGraph(g)
3035
if err != nil {
3136
return err
3237
}

internal/cmd/graph.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ func graphFunc(cmd *cobra.Command, _ []string) error {
5050
}
5151

5252
if graphFlags.deployment {
53-
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
53+
var opts []graph.Option
54+
if commonFlags.site != "" {
55+
opts = append(opts, graph.WithSite(commonFlags.site))
56+
}
57+
58+
dg, err := graph.ToDeploymentGraph(g, opts...)
5459
if err != nil {
5560
return err
5661
}

internal/cmd/init.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ func initFunc(cmd *cobra.Command, _ []string) error {
3535
defer cfg.Close()
3636
ctx := cmd.Context()
3737

38-
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
38+
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
39+
if err != nil {
40+
return err
41+
}
42+
43+
dg, err := graph.ToDeploymentGraph(g)
3944
if err != nil {
4045
return err
4146
}

internal/cmd/plan.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ func planFunc(cmd *cobra.Command, _ []string) error {
4747
defer cfg.Close()
4848
ctx := cmd.Context()
4949

50-
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
50+
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
51+
if err != nil {
52+
return err
53+
}
54+
55+
dg, err := graph.ToDeploymentGraph(g)
5156
if err != nil {
5257
return err
5358
}

internal/cmd/show-plan.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ func showPlanFunc(cmd *cobra.Command, _ []string) error {
4040
defer cfg.Close()
4141
ctx := cmd.Context()
4242

43-
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
43+
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
44+
if err != nil {
45+
return err
46+
}
47+
48+
dg, err := graph.ToDeploymentGraph(g)
4449
if err != nil {
4550
return err
4651
}

internal/cmd/terraform.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ func terraformFunc(cmd *cobra.Command, args []string) error {
3636
ctx := cmd.Context()
3737
defer cfg.Close()
3838

39-
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
39+
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
40+
if err != nil {
41+
return err
42+
}
43+
44+
dg, err := graph.ToDeploymentGraph(g)
4045
if err != nil {
4146
return err
4247
}

internal/graph/deployment.go

+43-7
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,42 @@ import (
44
"errors"
55
"fmt"
66
"github.com/dominikbraun/graph"
7-
"github.com/mach-composer/mach-composer-cli/internal/config"
87
)
98

9+
type options struct {
10+
site string
11+
}
12+
13+
type Option func(o *options)
14+
15+
func WithSite(site string) Option {
16+
return func(o *options) {
17+
o.site = site
18+
}
19+
}
20+
1021
// ToDeploymentGraph converts a MachConfig to a Graph ready for deployment.
1122
// This means that all nodes that are not independently deployable are pruned from the graph.
12-
func ToDeploymentGraph(cfg *config.MachConfig, outPath string) (*Graph, error) {
13-
g, err := ToDependencyGraph(cfg, outPath)
14-
if err != nil {
15-
return nil, err
23+
func ToDeploymentGraph(g *Graph, opts ...Option) (*Graph, error) {
24+
o := options{
25+
site: "",
26+
}
27+
28+
for _, opt := range opts {
29+
opt(&o)
1630
}
1731

18-
if err = validateDeployment(g); err != nil {
32+
if err := validateDeployment(g); err != nil {
1933
return nil, err
2034
}
2135

2236
// Remove all nodes that are not independent to site node
23-
if err = reduceNodes(g); err != nil {
37+
if err := reduceNodes(g); err != nil {
38+
return nil, err
39+
}
40+
41+
//Prune to only include the site node if provided
42+
if err := pruneSiteNodes(g, o.site); err != nil {
2443
return nil, err
2544
}
2645

@@ -132,3 +151,20 @@ func reduceNodes(g *Graph) error {
132151

133152
return pErr
134153
}
154+
155+
func pruneSiteNodes(g *Graph, site string) error {
156+
if site == "" {
157+
return nil
158+
}
159+
160+
for _, v := range g.Vertices() {
161+
if v.Type() == SiteType && v.Identifier() != site {
162+
err := pruneBranch(g, v)
163+
if err != nil {
164+
return err
165+
}
166+
}
167+
}
168+
169+
return nil
170+
}

internal/graph/deployment_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ func TestToDeploymentGraphSimple(t *testing.T) {
4141
},
4242
}
4343

44-
g, err := ToDeploymentGraph(cfg, "")
44+
dg, err := ToDependencyGraph(cfg, "")
45+
assert.NoError(t, err)
46+
47+
g, err := ToDeploymentGraph(dg)
4548
assert.NoError(t, err)
4649

4750
o, _ := g.Order()

internal/graph/utils.go

+47
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,50 @@ func fetchPathsToTarget(source, target string, pm map[string]map[string]graph.Ed
2525

2626
return paths
2727
}
28+
29+
func pruneBranch(g *Graph, n Node) error {
30+
var pErr error
31+
graph.DFS(g.Graph, n.Path(), func(p string) bool {
32+
n, err := g.Graph.Vertex(p)
33+
if err != nil {
34+
pErr = err
35+
return true
36+
}
37+
38+
e, err := g.Edges()
39+
if err != nil {
40+
pErr = err
41+
return true
42+
}
43+
44+
var edges []graph.Edge[string]
45+
46+
for _, edge := range e {
47+
if edge.Target == n.Path() {
48+
edges = append(edges, edge)
49+
}
50+
51+
if edge.Source == n.Path() {
52+
edges = append(edges, edge)
53+
}
54+
}
55+
56+
for _, edge := range edges {
57+
err = g.RemoveEdge(edge.Source, edge.Target)
58+
if err != nil {
59+
pErr = err
60+
return true
61+
}
62+
}
63+
64+
err = g.RemoveVertex(n.Path())
65+
if err != nil {
66+
pErr = err
67+
return true
68+
}
69+
70+
return false
71+
})
72+
73+
return pErr
74+
}

0 commit comments

Comments
 (0)