Skip to content

Commit

Permalink
Add InstallScripts to install preparation
Browse files Browse the repository at this point in the history
  • Loading branch information
evanpurkhiser committed Jul 14, 2019
1 parent b1fd959 commit e0bdc0a
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 38 deletions.
1 change: 0 additions & 1 deletion cmd/dots/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ var diffCmd = cobra.Command{
installConfig := installer.InstallConfig{
SourceConfig: sourceConfig,
OverrideInstallPath: sourceTmp,
SkipInstallScripts: true,
}

dotfiles := resolver.ResolveDotfiles(*sourceConfig, *sourceLockfile)
Expand Down
34 changes: 5 additions & 29 deletions installer/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"sync"

"go.evanpurkhiser.com/dots/config"
"go.evanpurkhiser.com/dots/resolver"
)

const separator = string(os.PathSeparator)
Expand All @@ -29,9 +28,6 @@ type InstallConfig struct {
// changed from its source. This implies that install scripts will be run.
ForceReinstall bool

// SkipInstallScripts disables execution of any triggered install scripts
SkipInstallScripts bool

// TODO We can probably add a channel here to pipe logging output so that we
// can output some logging
}
Expand Down Expand Up @@ -102,26 +98,13 @@ func InstallDotfile(dotfile *PreparedDotfile, config InstallConfig) error {
return err
}

// RunInstallScripts executes all install scripts for a single dotfile.
func RunInstallScripts(dotfile *resolver.Dotfile, config InstallConfig) error {
for range dotfile.InstallScripts {
continue
}

// TODO actually implement this
fmt.Println(dotfile.InstallScripts)

return nil
}

// InstallDotfiles asynchronously calls InstalledDotfile on all passed
// PreparedDotfiles. Once all dotfiles have been installed, all install scripts
// will execute, in order of installation (unless SkipInstallScripts is on).
func InstallDotfiles(dotfiles PreparedDotfiles, config InstallConfig) []*InstalledDotfile {
// PreparedDotfiles.
func InstallDotfiles(install PreparedInstall, config InstallConfig) []*InstalledDotfile {
waitGroup := sync.WaitGroup{}
waitGroup.Add(len(dotfiles))
waitGroup.Add(len(install.Dotfiles))

installed := make([]*InstalledDotfile, len(dotfiles))
installed := make([]*InstalledDotfile, len(install.Dotfiles))

doInstall := func(i int, dotfile *PreparedDotfile) {
err := InstallDotfile(dotfile, config)
Expand All @@ -134,18 +117,11 @@ func InstallDotfiles(dotfiles PreparedDotfiles, config InstallConfig) []*Install
waitGroup.Done()
}

for i, dotfile := range dotfiles {
for i, dotfile := range install.Dotfiles {
go doInstall(i, dotfile)
}

waitGroup.Wait()

// Nothing left to do if there are no install scripts to run
if config.SkipInstallScripts {
return installed
}

// TODO After all dotfiles are installed, we now must run our installation scripts

return installed
}
64 changes: 58 additions & 6 deletions installer/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import (
"go.evanpurkhiser.com/dots/resolver"
)

// PreparedInstall represents the set of dotfiles that which have been prepared
// for installation, and the install scripts which are associated to the set of
// dotfiles. The install scripts from dotfiles have been normalized so that
// each script is only represented once in the list.
type PreparedInstall struct {
Dotfiles []*PreparedDotfile
InstallScripts []*InstallScript
}

// A PreparedDotfile represents a dotfile that has been "prepared" for
// installation by verifying it's contents against the existing dotfile, and
// checking various other flags that require knowledge of the existing dotfile.
Expand Down Expand Up @@ -74,13 +83,29 @@ func (d FileMode) IsChanged() bool {
return d.New != d.Old
}

// PreparedDotfiles is a list of prepared dotfiles.
type PreparedDotfiles []*PreparedDotfile
// InstallScript represents a single installation script that is mapped to one
// or more dotfiles.
type InstallScript struct {
Path string
RequiredBy []*PreparedDotfile
}

// ShouldInstall indicates weather the installation script should be executed.
// This will check weather any of the required dotfiles have changed.
func (i *InstallScript) ShouldInstall() bool {
for _, dotfile := range i.RequiredBy {
if dotfile.IsChanged() {
return true
}
}

return false
}

// PrepareDotfiles iterates all passed dotfiles and creates an associated
// PreparedDotfile, returning a list of all prepared dotfiles.
func PrepareDotfiles(dotfiles resolver.Dotfiles, config config.SourceConfig) PreparedDotfiles {
preparedDotfiles := make(PreparedDotfiles, len(dotfiles))
// PreparedDotfile, returning a PreparedInstall object.
func PrepareDotfiles(dotfiles resolver.Dotfiles, config config.SourceConfig) PreparedInstall {
preparedDotfiles := make([]*PreparedDotfile, len(dotfiles))

waitGroup := sync.WaitGroup{}
waitGroup.Add(len(dotfiles))
Expand Down Expand Up @@ -188,5 +213,32 @@ func PrepareDotfiles(dotfiles resolver.Dotfiles, config config.SourceConfig) Pre

waitGroup.Wait()

return preparedDotfiles
// Once all dotfiles have been prepared, we can prepare the list of
// InstallScripts. This list will be normalized sot that each install script
// appears only once.
scriptMap := map[string][]*PreparedDotfile{}

for _, dotfile := range preparedDotfiles {
for _, path := range dotfile.InstallScripts {
if scriptMap[path] == nil {
scriptMap[path] = []*PreparedDotfile{dotfile}
} else {
scriptMap[path] = append(scriptMap[path], dotfile)
}
}
}

installScripts := make([]*InstallScript, 0, len(scriptMap))

for path, dotfiles := range scriptMap {
installScripts = append(installScripts, &InstallScript{
RequiredBy: dotfiles,
Path: path,
})
}

return PreparedInstall{
Dotfiles: preparedDotfiles,
InstallScripts: installScripts,
}
}
4 changes: 2 additions & 2 deletions resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ type Dotfile struct {
// Sources is the set of SourceFiles
Sources []*SourceFile

// InstallScripts is the list of installation scripts that will be executed
// when the dotfile has been installed or modified.
// InstallScripts is the list of installation script pathsthat will be
// executed when the dotfile has been installed or modified.
InstallScripts []string
}

Expand Down

0 comments on commit e0bdc0a

Please sign in to comment.