github.com/bilus/oya@v0.0.3-0.20190301162104-da4acbd394c6/pkg/deptree/deptree.go (about)

     1  package deptree
     2  
     3  import (
     4  	"github.com/bilus/oya/pkg/deptree/internal"
     5  	"github.com/bilus/oya/pkg/mvs"
     6  	"github.com/bilus/oya/pkg/oyafile"
     7  	"github.com/bilus/oya/pkg/pack"
     8  	"github.com/bilus/oya/pkg/types"
     9  )
    10  
    11  // DependencyTree defines a project's dependencies, allowing for loading them.
    12  type DependencyTree struct {
    13  	installDirs  []string
    14  	dependencies []pack.Pack
    15  	reqs         *internal.Reqs
    16  }
    17  
    18  // New returns a new dependency tree.
    19  // BUG(bilus): It's called a 'tree' but it currently does not take into account inter-pack
    20  // dependencies. This will likely change and then the name will fit like a glove. ;)
    21  func New(rootDir string, installDirs []string, dependencies []pack.Pack) (*DependencyTree, error) {
    22  	return &DependencyTree{
    23  		installDirs:  installDirs,
    24  		dependencies: dependencies,
    25  		reqs:         internal.NewReqs(rootDir, installDirs),
    26  	}, nil
    27  }
    28  
    29  // Explode takes the initial list of dependencies and builds the full list,
    30  // taking into account packs' dependencies and using Minimal Version Selection.
    31  func (dt *DependencyTree) Explode() error {
    32  	list, err := mvs.List(dt.dependencies, dt.reqs)
    33  	if err != nil {
    34  		return err
    35  	}
    36  	dt.dependencies = list
    37  	return nil
    38  }
    39  
    40  // Load loads an pack's Oyafile based on its import path.
    41  // It supports two types of import paths:
    42  // - referring to the project's Require: section (e.g. github.com/tooploox/oya-packs/docker), in this case it will load, the required version;
    43  // - path relative to the project's root (e.g. /) -- does not support versioning, loads Oyafile directly from the path (<root dir>/<import path>).
    44  func (dt *DependencyTree) Load(importPath types.ImportPath) (*oyafile.Oyafile, bool, error) {
    45  	pack, found, err := dt.findRequiredPack(importPath)
    46  	if err != nil {
    47  		return nil, false, err
    48  	}
    49  	if found {
    50  		return dt.reqs.LoadLocalOyafile(pack)
    51  	}
    52  	return nil, false, nil
    53  }
    54  
    55  // Find lookups pack by its import path.
    56  func (dt *DependencyTree) Find(importPath types.ImportPath) (pack.Pack, bool, error) {
    57  	for _, pack := range dt.dependencies {
    58  		if pack.ImportPath() == importPath {
    59  			return pack, true, nil
    60  		}
    61  	}
    62  	return pack.Pack{}, false, nil
    63  }
    64  
    65  // ForEach iterates through the packs.
    66  func (dt *DependencyTree) ForEach(f func(pack.Pack) error) error {
    67  	for _, pack := range dt.dependencies {
    68  		if err := f(pack); err != nil {
    69  			return err
    70  		}
    71  	}
    72  	return nil
    73  }
    74  
    75  func (dt *DependencyTree) findRequiredPack(importPath types.ImportPath) (pack.Pack, bool, error) {
    76  	for _, pack := range dt.dependencies {
    77  		if pack.ImportPath() == importPath {
    78  			return pack, true, nil
    79  		}
    80  	}
    81  	return pack.Pack{}, false, nil
    82  }