Skip to content

Commit

Permalink
feat: added basic branch pruning logic
Browse files Browse the repository at this point in the history
  • Loading branch information
demeyerthom committed Sep 6, 2024
1 parent b6c449e commit 623df4a
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 21 deletions.
7 changes: 6 additions & 1 deletion internal/cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ func applyFunc(cmd *cobra.Command, _ []string) error {
defer cfg.Close()
ctx := cmd.Context()

dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
if err != nil {
return err
}

dg, err := graph.ToDeploymentGraph(g)
if err != nil {
return err
}
Expand Down
8 changes: 2 additions & 6 deletions internal/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (

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

func preprocessCommonFlags(cmd *cobra.Command) {
if commonFlags.siteName != "" {
log.Warn().Msgf("Site option not implemented")
}

handleError(cmd.MarkFlagFilename("var-file", "yml", "yaml"))
handleError(cmd.MarkFlagFilename("file", "yml", "yaml"))

Expand Down
7 changes: 6 additions & 1 deletion internal/cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ func generateFunc(cmd *cobra.Command) error {
cfg := loadConfig(cmd, true)
defer cfg.Close()

gd, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
if err != nil {
return err
}

gd, err := graph.ToDeploymentGraph(g)
if err != nil {
return err
}
Expand Down
7 changes: 6 additions & 1 deletion internal/cmd/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ func graphFunc(cmd *cobra.Command, _ []string) error {
}

if graphFlags.deployment {
dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
var opts []graph.Option
if commonFlags.site != "" {
opts = append(opts, graph.WithSite(commonFlags.site))
}

dg, err := graph.ToDeploymentGraph(g, opts...)
if err != nil {
return err
}
Expand Down
7 changes: 6 additions & 1 deletion internal/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ func initFunc(cmd *cobra.Command, _ []string) error {
defer cfg.Close()
ctx := cmd.Context()

dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
if err != nil {
return err
}

dg, err := graph.ToDeploymentGraph(g)
if err != nil {
return err
}
Expand Down
7 changes: 6 additions & 1 deletion internal/cmd/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ func planFunc(cmd *cobra.Command, _ []string) error {
defer cfg.Close()
ctx := cmd.Context()

dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
if err != nil {
return err
}

dg, err := graph.ToDeploymentGraph(g)
if err != nil {
return err
}
Expand Down
7 changes: 6 additions & 1 deletion internal/cmd/show-plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ func showPlanFunc(cmd *cobra.Command, _ []string) error {
defer cfg.Close()
ctx := cmd.Context()

dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
if err != nil {
return err
}

dg, err := graph.ToDeploymentGraph(g)
if err != nil {
return err
}
Expand Down
7 changes: 6 additions & 1 deletion internal/cmd/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ func terraformFunc(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
defer cfg.Close()

dg, err := graph.ToDeploymentGraph(cfg, commonFlags.outputPath)
g, err := graph.ToDependencyGraph(cfg, commonFlags.outputPath)
if err != nil {
return err
}

dg, err := graph.ToDeploymentGraph(g)
if err != nil {
return err
}
Expand Down
50 changes: 43 additions & 7 deletions internal/graph/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,42 @@ import (
"errors"
"fmt"
"github.com/dominikbraun/graph"
"github.com/mach-composer/mach-composer-cli/internal/config"
)

type options struct {
site string
}

type Option func(o *options)

func WithSite(site string) Option {
return func(o *options) {
o.site = site
}
}

// ToDeploymentGraph converts a MachConfig to a Graph ready for deployment.
// This means that all nodes that are not independently deployable are pruned from the graph.
func ToDeploymentGraph(cfg *config.MachConfig, outPath string) (*Graph, error) {
g, err := ToDependencyGraph(cfg, outPath)
if err != nil {
return nil, err
func ToDeploymentGraph(g *Graph, opts ...Option) (*Graph, error) {
o := options{
site: "",
}

for _, opt := range opts {
opt(&o)
}

if err = validateDeployment(g); err != nil {
if err := validateDeployment(g); err != nil {
return nil, err
}

// Remove all nodes that are not independent to site node
if err = reduceNodes(g); err != nil {
if err := reduceNodes(g); err != nil {
return nil, err
}

//Prune to only include the site node if provided
if err := pruneSiteNodes(g, o.site); err != nil {
return nil, err
}

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

return pErr
}

func pruneSiteNodes(g *Graph, site string) error {
if site == "" {
return nil
}

for _, v := range g.Vertices() {
if v.Type() == SiteType && v.Identifier() != site {
err := pruneBranch(g, v)
if err != nil {
return err
}
}
}

return nil
}
5 changes: 4 additions & 1 deletion internal/graph/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ func TestToDeploymentGraphSimple(t *testing.T) {
},
}

g, err := ToDeploymentGraph(cfg, "")
dg, err := ToDependencyGraph(cfg, "")
assert.NoError(t, err)

g, err := ToDeploymentGraph(dg)
assert.NoError(t, err)

o, _ := g.Order()
Expand Down
47 changes: 47 additions & 0 deletions internal/graph/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,50 @@ func fetchPathsToTarget(source, target string, pm map[string]map[string]graph.Ed

return paths
}

func pruneBranch(g *Graph, n Node) error {
var pErr error
graph.DFS(g.Graph, n.Path(), func(p string) bool {

Check failure on line 31 in internal/graph/utils.go

View workflow job for this annotation

GitHub Actions / test

Error return value of `graph.DFS` is not checked (errcheck)
n, err := g.Graph.Vertex(p)
if err != nil {
pErr = err
return true
}

e, err := g.Edges()
if err != nil {
pErr = err
return true
}

var edges []graph.Edge[string]

for _, edge := range e {
if edge.Target == n.Path() {
edges = append(edges, edge)
}

if edge.Source == n.Path() {
edges = append(edges, edge)
}
}

for _, edge := range edges {
err = g.RemoveEdge(edge.Source, edge.Target)
if err != nil {
pErr = err
return true
}
}

err = g.RemoveVertex(n.Path())
if err != nil {
pErr = err
return true
}

return false
})

return pErr
}

0 comments on commit 623df4a

Please sign in to comment.