Skip to content

Commit

Permalink
Merge pull request #17 from b4b4r07/feature/dependency
Browse files Browse the repository at this point in the history
Add package dependency
  • Loading branch information
b4b4r07 authored Feb 17, 2022
2 parents 652d406 + 1046687 commit 3e0e1e0
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 19 deletions.
16 changes: 12 additions & 4 deletions cmd/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,18 @@ func (m *meta) init(args []string) error {
return errors.Wrapf(err, "%s: failed to walk dir", cfgRoot)
}

var pkgs []config.Package
app := &config.DefaultAppConfig
for _, file := range files {
cfg, err := config.Read(file)
if err != nil {
return errors.Wrapf(err, "%s: failed to read config", file)
}
pkgs, err := cfg.Parse()
parsed, err := cfg.Parse()
if err != nil {
return errors.Wrapf(err, "%s: failed to parse config", file)
}
m.Packages = append(m.Packages, pkgs...)
pkgs = append(pkgs, parsed...)

if cfg.AppConfig != nil {
app = cfg.AppConfig
Expand All @@ -68,10 +69,17 @@ func (m *meta) init(args []string) error {

m.AppConfig = app

if err := config.Validate(m.Packages); err != nil {
return errors.Wrap(err, "%s: failed to validate packages")
if err := config.Validate(pkgs); err != nil {
return errors.Wrap(err, "failed to validate packages")
}

pkgs, err = config.Sort(pkgs)
if err != nil {
return errors.Wrap(err, "failed to resolve dependencies between packages")
}

m.Packages = pkgs

m.Env = env.New(cache)
m.Env.Add(env.Variables{
"AFX_CONFIG_PATH": env.Variable{Value: cfgRoot},
Expand Down
1 change: 1 addition & 0 deletions docs/configuration/package/gist.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ owner | string | yes | Gist owner
id | string | yes | Gist page id
command | section | | See [Command](../command.md) page
plugin | section | | See [Plugin](../plugin.md) page
depends-on | array | Dependency list (you can write package name here)
1 change: 1 addition & 0 deletions docs/configuration/package/github.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ release.name | string | yes (in `release`) | GitHub release name
release.tag | string | | GitHub release tag
command | section | | See [Command](../command.md) page
plugin | section | | See [Plugin](../plugin.md) page
depends-on | array | Dependency list (you can write package name here)
1 change: 1 addition & 0 deletions docs/configuration/package/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ url | string | yes | URL which can be downloaded.
output | string | | TBD
command | section | | See [Command](../command.md) page
plugin | section | | See [Plugin](../plugin.md) page
depends-on | array | Dependency list (you can write package name here)
1 change: 1 addition & 0 deletions docs/configuration/package/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ description | string | | A description of a package
directory | string | yes | Directory path where the target files are placed
command | section | | See [Command](../command.md) page
plugin | section | | See [Plugin](../plugin.md) page
depends-on | array | Dependency list (you can write package name here)
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667 // indirect
github.com/agext/levenshtein v1.2.2 // indirect
github.com/creativeprojects/go-selfupdate v0.6.1
github.com/deckarep/golang-set v1.8.0
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/fatih/color v1.10.0
github.com/frankban/quicktest v1.4.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ github.com/creativeprojects/go-selfupdate v0.6.1/go.mod h1:Zr5CB9GEee179eQpho5k6
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
Expand Down
68 changes: 68 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"log"
"os"
"path/filepath"
"strings"

"github.com/b4b4r07/afx/pkg/dependency"
"github.com/b4b4r07/afx/pkg/errors"
"github.com/go-playground/validator/v10"
"github.com/goccy/go-yaml"
Expand Down Expand Up @@ -49,6 +51,8 @@ var DefaultAppConfig AppConfig = AppConfig{

// Read reads yaml file based on given path
func Read(path string) (Config, error) {
log.Printf("[INFO] Reading config %s...", path)

var cfg Config

f, err := os.Open(path)
Expand All @@ -73,6 +77,7 @@ func Read(path string) (Config, error) {

func parse(cfg Config) []Package {
var pkgs []Package

for _, pkg := range cfg.GitHub {
// TODO: Remove?
if pkg.HasReleaseBlock() {
Expand Down Expand Up @@ -112,6 +117,8 @@ func parse(cfg Config) []Package {

// Parse parses a config given via yaml files and converts it into package interface
func (c Config) Parse() ([]Package, error) {
log.Printf("[INFO] Parsing config...")
// TODO: divide from parse()
return parse(c), nil
}

Expand Down Expand Up @@ -146,3 +153,64 @@ func WalkDir(path string) ([]string, error) {
}
return files, nil
}

func Sort(given []Package) ([]Package, error) {
var pkgs []Package
var graph dependency.Graph

table := map[string]Package{}

for _, pkg := range given {
table[pkg.GetName()] = pkg
}

var errs errors.Errors
for name, pkg := range table {
dependencies := pkg.GetDependsOn()
for _, dep := range pkg.GetDependsOn() {
if _, ok := table[dep]; !ok {
errs.Append(
fmt.Errorf("%q: not valid package name in depends-on: %s", dep, pkg.GetName()),
)
}
}
graph = append(graph, dependency.NewNode(name, dependencies...))
}

if dependency.Has(graph) {
log.Printf("[DEBUG] dependency graph is here: \n%s", graph)
}

resolved, err := dependency.Resolve(graph)
if err != nil {
return pkgs, errors.Wrap(err, "failed to resolve dependency graph")
}

for _, node := range resolved {
pkgs = append(pkgs, table[node.Name])
}

return pkgs, errs.ErrorOrNil()
}

// Validate validates if packages are not violated some rules
func Validate(pkgs []Package) error {
m := make(map[string]bool)
var list []string

for _, pkg := range pkgs {
name := pkg.GetName()
_, exist := m[name]
if exist {
list = append(list, name)
continue
}
m[name] = true
}

if len(list) > 0 {
return fmt.Errorf("duplicated packages: [%s]", strings.Join(list, ","))
}

return nil
}
6 changes: 6 additions & 0 deletions pkg/config/gist.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type Gist struct {

Plugin *Plugin `yaml:"plugin"`
Command *Command `yaml:"command"`

DependsOn []string `yaml:"depends-on"`
}

func NewGist(owner, id string) (Gist, error) {
Expand Down Expand Up @@ -188,3 +190,7 @@ func (c Gist) GetName() string {
func (c Gist) GetHome() string {
return filepath.Join(os.Getenv("HOME"), ".afx", "gist.github.com", c.Owner, c.ID)
}

func (c Gist) GetDependsOn() []string {
return c.DependsOn
}
6 changes: 6 additions & 0 deletions pkg/config/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type GitHub struct {

Plugin *Plugin `yaml:"plugin"`
Command *Command `yaml:"command"` // validate:"required_with=Release"

DependsOn []string `yaml:"depends-on"`
}

type GitHubOption struct {
Expand Down Expand Up @@ -599,3 +601,7 @@ func (c GitHub) GetName() string {
func (c GitHub) GetHome() string {
return filepath.Join(os.Getenv("HOME"), ".afx", "github.com", c.Owner, c.Repo)
}

func (c GitHub) GetDependsOn() []string {
return c.DependsOn
}
6 changes: 6 additions & 0 deletions pkg/config/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type HTTP struct {

Plugin *Plugin `yaml:"plugin"`
Command *Command `yaml:"command"`

DependsOn []string `yaml:"depends-on"`
}

// Init is
Expand Down Expand Up @@ -213,3 +215,7 @@ func (c HTTP) GetHome() string {
u, _ := url.Parse(c.URL)
return filepath.Join(os.Getenv("HOME"), ".afx", u.Host, filepath.Dir(u.Path))
}

func (c HTTP) GetDependsOn() []string {
return c.DependsOn
}
6 changes: 6 additions & 0 deletions pkg/config/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type Local struct {

Plugin *Plugin `yaml:"plugin"`
Command *Command `yaml:"command"`

DependsOn []string `yaml:"depends-on"`
}

// Init is
Expand Down Expand Up @@ -80,3 +82,7 @@ func (c Local) GetName() string {
func (c Local) GetHome() string {
return expandTilda(os.ExpandEnv(c.Directory))
}

func (c Local) GetDependsOn() []string {
return c.DependsOn
}
17 changes: 2 additions & 15 deletions pkg/config/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package config

import (
"context"
"fmt"

"github.com/mattn/go-shellwords"
)
Expand All @@ -28,6 +27,8 @@ type Handler interface {
HasCommandBlock() bool
GetPluginBlock() Plugin
GetCommandBlock() Command

GetDependsOn() []string
}

// Package is an interface related to package itself
Expand Down Expand Up @@ -80,17 +81,3 @@ func HasSudoInCommandBuildSteps(pkgs []Package) bool {
}
return false
}

// Validate checks if keys of given packages are not duplicated
func Validate(pkgs []Package) error {
done := make(map[string]bool, len(pkgs))
for _, pkg := range pkgs {
name := pkg.GetName()
_, already := done[name]
if already {
return fmt.Errorf("%s: duplicated", name)
}
done[name] = true
}
return nil
}
Loading

0 comments on commit 3e0e1e0

Please sign in to comment.