Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ LOCAL_BIN:=$(CURDIR)/bin

# Linter config.
GOLANGCI_BIN:=$(LOCAL_BIN)/golangci-lint
GOLANGCI_TAG:=1.61.0
GOLANGCI_TAG:=1.64.5

.PHONY: all
all: deps test build
Expand Down
40 changes: 26 additions & 14 deletions compose/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/launchrctl/launchr"
"github.com/launchrctl/launchr/pkg/action"
"github.com/stevenle/topsort"
)

Expand Down Expand Up @@ -122,6 +122,9 @@ func identifyStrategy(name string) (mergeStrategyType, mergeStrategyTarget) {

// Builder struct, provides methods to merge packages into build
type Builder struct {
action.WithLogger
action.WithTerm

platformDir string
targetDir string
sourceDir string
Expand All @@ -138,8 +141,17 @@ type fsEntry struct {
From string
}

func createBuilder(platformDir, targetDir, sourceDir string, skipNotVersioned, logConflicts bool, packages []*Package) *Builder {
return &Builder{platformDir, targetDir, sourceDir, skipNotVersioned, logConflicts, packages}
func createBuilder(c *Composer, targetDir, sourceDir string, packages []*Package) *Builder {
return &Builder{
c.WithLogger,
c.WithTerm,
c.pwd,
targetDir,
sourceDir,
c.options.SkipNotVersioned,
c.options.ConflictsVerbosity,
packages,
}
}

func getVersionedMap(gitDir string) (map[string]bool, error) {
Expand Down Expand Up @@ -169,7 +181,7 @@ func getVersionedMap(gitDir string) (map[string]bool, error) {
}

func (b *Builder) build(ctx context.Context) error {
launchr.Term().Println("Creating composition...")
b.Term().Println("Creating composition...")
err := EnsureDirExists(b.targetDir)
if err != nil {
return err
Expand Down Expand Up @@ -245,7 +257,7 @@ func (b *Builder) build(ctx context.Context) error {
targetsMap := getTargetsMap(b.packages)

if b.logConflicts {
launchr.Term().Info().Printf("Conflicting files:\n")
b.Term().Info().Printf("Conflicting files:\n")
}

for i := 0; i < len(items); i++ {
Expand Down Expand Up @@ -280,7 +292,7 @@ func (b *Builder) build(ctx context.Context) error {
}

if b.logConflicts && !finfo.IsDir() {
logConflictResolve(conflictReslv, path, pkgName, entriesMap[path])
b.logConflictResolve(conflictReslv, path, pkgName, entriesMap[path])
}

return nil
Expand Down Expand Up @@ -332,6 +344,14 @@ func (b *Builder) build(ctx context.Context) error {
return nil
}

func (b *Builder) logConflictResolve(resolveto mergeConflictResolve, path, pkgName string, entry *fsEntry) {
if resolveto == noConflict {
return
}

b.Term().Info().Printfln("[%s] - %s > Selected from %s", pkgName, path, entry.From)
}

func getTargetsMap(packages []*Package) map[string]string {
targets := make(map[string]string)
for _, p := range packages {
Expand All @@ -341,14 +361,6 @@ func getTargetsMap(packages []*Package) map[string]string {
return targets
}

func logConflictResolve(resolveto mergeConflictResolve, path, pkgName string, entry *fsEntry) {
if resolveto == noConflict {
return
}

launchr.Term().Info().Printfln("[%s] - %s > Selected from %s", pkgName, path, entry.From)
}

func addEntries(entriesTree []*fsEntry, entriesMap map[string]*fsEntry, entry *fsEntry, path string) ([]*fsEntry, mergeConflictResolve) {
conflictResolve := noConflict
if _, ok := entriesMap[path]; !ok {
Expand Down
102 changes: 57 additions & 45 deletions compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import (
"syscall"

"github.com/launchrctl/keyring"
"github.com/launchrctl/launchr"
"github.com/launchrctl/launchr/pkg/action"
)

const (
MainDir = ".compose" // MainDir is a compose directory.
BuildDir = MainDir + "/build" // BuildDir is a result directory of compose action.
// MainDir is a compose directory.
MainDir = ".compose"
// BuildDir is a result directory of compose action.
BuildDir = MainDir + "/build"
composeFile = "plasma-compose.yaml"
dirPermissions = 0755
)
Expand All @@ -25,40 +27,10 @@ var (
errComposeBadStructure = errors.New("incorrect mapping for plasma-compose.yaml, ensure structure is correct")
)

// Composer stores compose definition
type Composer struct {
pwd string
options *ComposerOptions
compose *YamlCompose
k keyring.Keyring
}

// ComposerOptions - list of possible composer options
type ComposerOptions struct {
Clean bool
WorkingDir string
SkipNotVersioned bool
ConflictsVerbosity bool
Interactive bool
}

// CreateComposer instance
func CreateComposer(pwd string, opts ComposerOptions, k keyring.Keyring) (*Composer, error) {
config, err := Lookup(os.DirFS(pwd))
if err != nil {
return nil, err
}

for _, dep := range config.Dependencies {
if dep.Source.Tag != "" {
launchr.Term().Warning().Printfln("found deprecated field `tag` in `%s` dependency. Use `ref` field for tags or branches.", dep.Name)
}
}

return &Composer{pwd, &opts, config, k}, nil
}

type keyringWrapper struct {
action.WithLogger
action.WithTerm

keyringService keyring.Keyring
interactive bool
shouldUpdate bool
Expand All @@ -70,7 +42,7 @@ func (kw *keyringWrapper) getForURL(url string) (keyring.CredentialsItem, error)
if errors.Is(errGet, keyring.ErrEmptyPass) {
return ci, errGet
} else if !errors.Is(errGet, keyring.ErrNotFound) {
launchr.Log().Debug(errGet.Error())
kw.Log().Debug(errGet.Error())
return ci, errors.New("the keyring is malformed or wrong passphrase provided")
}

Expand Down Expand Up @@ -98,7 +70,7 @@ func (kw *keyringWrapper) getForURL(url string) (keyring.CredentialsItem, error)

func (kw *keyringWrapper) fillCredentials(ci keyring.CredentialsItem) (keyring.CredentialsItem, error) {
if ci.URL != "" {
launchr.Term().Printfln("Please add login and password for URL - %s", ci.URL)
kw.Term().Printfln("Please add login and password for URL - %s", ci.URL)
}
err := keyring.RequestCredentialsFromTty(&ci)
if err != nil {
Expand All @@ -108,6 +80,36 @@ func (kw *keyringWrapper) fillCredentials(ci keyring.CredentialsItem) (keyring.C
return ci, nil
}

// Composer stores compose definition
type Composer struct {
action.WithLogger
action.WithTerm

pwd string
options *ComposerOptions
compose *YamlCompose
k keyring.Keyring
}

// ComposerOptions - list of possible composer options
type ComposerOptions struct {
Clean bool
WorkingDir string
SkipNotVersioned bool
ConflictsVerbosity bool
Interactive bool
}

// CreateComposer instance
func CreateComposer(pwd string, opts ComposerOptions, k keyring.Keyring) (*Composer, error) {
config, err := Lookup(os.DirFS(pwd))
if err != nil {
return nil, err
}

return &Composer{pwd: pwd, options: &opts, compose: config, k: k}, nil
}

// RunInstall on Composer
func (c *Composer) RunInstall() error {
ctx, cancel := context.WithCancel(context.Background())
Expand All @@ -117,7 +119,7 @@ func (c *Composer) RunInstall() error {

go func() {
<-signalChan
launchr.Term().Printfln("\nTermination signal received. Cleaning up...")
c.Term().Printfln("\nTermination signal received. Cleaning up...")
// cleanup dir
_, _, _ = c.prepareInstall(false)

Expand All @@ -133,37 +135,47 @@ func (c *Composer) RunInstall() error {
return err
}

kw := &keyringWrapper{keyringService: c.getKeyring(), shouldUpdate: false, interactive: c.options.Interactive}
kw := &keyringWrapper{
keyringService: c.getKeyring(),
shouldUpdate: false,
interactive: c.options.Interactive,
}
kw.SetLogger(c.Log())
kw.SetTerm(c.Term())
dm := CreateDownloadManager(kw)
packages, err := dm.Download(ctx, c.getCompose(), packagesDir)
if err != nil {
return err
}

builder := createBuilder(
c.pwd,
c,
buildDir,
packagesDir,
c.options.SkipNotVersioned,
c.options.ConflictsVerbosity,
packages,
)
return builder.build(ctx)
}
}

func (c *Composer) prepareInstall(clean bool) (string, string, error) {
for _, dep := range c.compose.Dependencies {
if dep.Source.Tag != "" {
c.Term().Warning().Printfln("found deprecated field `tag` in `%s` dependency. Use `ref` field for tags or branches.", dep.Name)
}
}

buildPath := c.getPath(BuildDir)
packagesPath := c.getPath(c.options.WorkingDir)

launchr.Term().Printfln("Cleaning build dir: %s", BuildDir)
c.Term().Printfln("Cleaning build dir: %s", BuildDir)
err := os.RemoveAll(buildPath)
if err != nil {
return "", "", err
}

if clean {
launchr.Term().Printfln("Cleaning packages dir: %s", packagesPath)
c.Term().Printfln("Cleaning packages dir: %s", packagesPath)
err = os.RemoveAll(packagesPath)
if err != nil {
return "", "", err
Expand Down
26 changes: 12 additions & 14 deletions compose/downloadManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"io"
"os"
"path/filepath"

"github.com/launchrctl/launchr"
)

const (
Expand Down Expand Up @@ -36,14 +34,14 @@ func CreateDownloadManager(keyring *keyringWrapper) DownloadManager {
return DownloadManager{kw: keyring}
}

func getDownloaderForPackage(downloadType string, kw *keyringWrapper) Downloader {
func (m DownloadManager) getDownloaderForPackage(downloadType string) Downloader {
switch {
case downloadType == GitType:
return newGit(kw)
case downloadType == HTTPType:
return newHTTP(kw)
return newHTTP(m.kw)
case downloadType == GitType:
fallthrough
default:
return newGit(kw)
return newGit(m.kw)
}
}

Expand All @@ -57,7 +55,7 @@ func (m DownloadManager) Download(ctx context.Context, c *YamlCompose, targetDir
}

kw := m.getKeyring()
packages, err = m.recursiveDownload(ctx, c, kw, packages, nil, targetDir)
packages, err = m.recursiveDownload(ctx, c, packages, nil, targetDir)
if err != nil {
return packages, err
}
Expand All @@ -70,7 +68,7 @@ func (m DownloadManager) Download(ctx context.Context, c *YamlCompose, targetDir
return packages, err
}

func (m DownloadManager) recursiveDownload(ctx context.Context, yc *YamlCompose, kw *keyringWrapper, packages []*Package, parent *Package, targetDir string) ([]*Package, error) {
func (m DownloadManager) recursiveDownload(ctx context.Context, yc *YamlCompose, packages []*Package, parent *Package, targetDir string) ([]*Package, error) {
for _, d := range yc.Dependencies {
select {
case <-ctx.Done():
Expand All @@ -90,7 +88,7 @@ func (m DownloadManager) recursiveDownload(ctx context.Context, yc *YamlCompose,

packagePath := filepath.Join(targetDir, pkg.GetName(), pkg.GetTarget())

err := downloadPackage(ctx, pkg, targetDir, kw)
err := m.downloadPackage(ctx, pkg, targetDir)
if err != nil {
return packages, err
}
Expand All @@ -99,7 +97,7 @@ func (m DownloadManager) recursiveDownload(ctx context.Context, yc *YamlCompose,
if _, err = os.Stat(filepath.Join(packagePath, composeFile)); !os.IsNotExist(err) {
cfg, err := Lookup(os.DirFS(packagePath))
if err == nil {
packages, err = m.recursiveDownload(ctx, cfg, kw, packages, pkg, targetDir)
packages, err = m.recursiveDownload(ctx, cfg, packages, pkg, targetDir)
if err != nil {
return packages, err
}
Expand All @@ -113,8 +111,8 @@ func (m DownloadManager) recursiveDownload(ctx context.Context, yc *YamlCompose,
return packages, nil
}

func downloadPackage(ctx context.Context, pkg *Package, targetDir string, kw *keyringWrapper) error {
downloader := getDownloaderForPackage(pkg.GetType(), kw)
func (m DownloadManager) downloadPackage(ctx context.Context, pkg *Package, targetDir string) error {
downloader := m.getDownloaderForPackage(pkg.GetType())
packagePath := filepath.Join(targetDir, pkg.GetName())
downloadPath := filepath.Join(packagePath, pkg.GetTarget())

Expand Down Expand Up @@ -142,7 +140,7 @@ func downloadPackage(ctx context.Context, pkg *Package, targetDir string, kw *ke
if err != nil {
errRemove := os.RemoveAll(downloadPath)
if errRemove != nil {
launchr.Log().Debug("error cleaning package folder", "path", downloadPath, "err", err)
m.kw.Log().Debug("error cleaning package folder", "path", downloadPath, "err", err)
}
}

Expand Down
Loading
Loading