chore: move everything out from src
This commit is contained in:
180
command/link.go
Normal file
180
command/link.go
Normal file
@@ -0,0 +1,180 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"alma/config"
|
||||
"alma/helpers"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type LinkCommand struct {
|
||||
}
|
||||
|
||||
type itemToLink struct {
|
||||
source string
|
||||
target string
|
||||
}
|
||||
|
||||
func (LinkCommand) GetName() string {
|
||||
return "link"
|
||||
}
|
||||
|
||||
func (LinkCommand) GetHelpText() {
|
||||
println(
|
||||
`Usage:
|
||||
alma link [module]
|
||||
alma link [repository] [module]
|
||||
|
||||
Options:
|
||||
--help Show this message
|
||||
-d, --dry-run Show what would be linked without actually linking`)
|
||||
}
|
||||
|
||||
func (LinkCommand) Run(args []string) {
|
||||
moduleInfo, err := helpers.GetModuleInfo(args)
|
||||
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
moduleDirectory := moduleInfo.ModuleDirectory
|
||||
targetDirectory := moduleInfo.TargetDirectory
|
||||
|
||||
dryRun := lo.ContainsBy(args, func(item string) bool { return (item == "-d" || item == "--dry-run") })
|
||||
|
||||
almaConfigFilePath, err := os.Stat(filepath.Join(moduleDirectory, ".alma-config.json"))
|
||||
moduleConfiguration := &config.ModuleConfiguration{}
|
||||
|
||||
if err == nil && !almaConfigFilePath.IsDir() {
|
||||
moduleConfiguration = config.LoadModuleConfiguration(filepath.Join(moduleDirectory, ".alma-config.json"))
|
||||
targetDirectory = helpers.ResolvePath(moduleConfiguration.Target)
|
||||
}
|
||||
|
||||
itemsToLink := TraverseTree(
|
||||
&moduleDirectory,
|
||||
&targetDirectory,
|
||||
&moduleDirectory,
|
||||
&targetDirectory,
|
||||
moduleConfiguration,
|
||||
)
|
||||
|
||||
filteredItemsToLink := lo.Filter(itemsToLink, func(item itemToLink, index int) bool {
|
||||
for _, exclude := range moduleConfiguration.Exclude {
|
||||
sourceRelative := item.source[len(moduleDirectory)+1:]
|
||||
if strings.HasPrefix(sourceRelative, exclude) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if dryRun {
|
||||
println("Dry run. No links will be created. The following links would be created:")
|
||||
}
|
||||
|
||||
linkItems(filteredItemsToLink, dryRun)
|
||||
|
||||
// Not yet used things
|
||||
|
||||
_ = targetDirectory
|
||||
_ = moduleConfiguration
|
||||
|
||||
}
|
||||
|
||||
func TraverseTree(
|
||||
currentDirectory *string,
|
||||
currentTargetDirectory *string,
|
||||
moduleDirectory *string,
|
||||
targetDirectory *string,
|
||||
moduleConfiguration *config.ModuleConfiguration) []itemToLink {
|
||||
content, err := os.ReadDir(*currentDirectory)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
itemsToLink := make([]itemToLink, 0, len(content))
|
||||
for _, item := range content {
|
||||
if item.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
if currentDirectory == moduleDirectory && item.Name() == ".alma-config.json" {
|
||||
continue
|
||||
}
|
||||
|
||||
itemConfigTargetPath := moduleConfiguration.Links[item.Name()]
|
||||
|
||||
var targetPath string
|
||||
if itemConfigTargetPath != "" {
|
||||
targetPath = helpers.ResolvePathWithDefault(moduleConfiguration.Links[item.Name()], *targetDirectory)
|
||||
} else {
|
||||
targetPath = filepath.Join(*currentTargetDirectory, item.Name())
|
||||
}
|
||||
|
||||
itemsToLink = append(itemsToLink, itemToLink{
|
||||
source: filepath.Join(*currentDirectory, item.Name()),
|
||||
target: targetPath,
|
||||
})
|
||||
}
|
||||
|
||||
for _, item := range content {
|
||||
if !item.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
relativePath := getRelativePath(filepath.Join(*currentDirectory, item.Name()), *moduleDirectory)
|
||||
|
||||
itemConfigTargetPath := moduleConfiguration.Links[relativePath]
|
||||
|
||||
if itemConfigTargetPath != "" {
|
||||
itemsToLink = append(itemsToLink, itemToLink{
|
||||
source: filepath.Join(*currentDirectory, item.Name()),
|
||||
target: helpers.ResolvePathWithDefault(itemConfigTargetPath, *targetDirectory),
|
||||
})
|
||||
} else {
|
||||
newCurrentDirectory := filepath.Join(*currentDirectory, item.Name())
|
||||
newTargetDirectory := filepath.Join(*currentTargetDirectory, item.Name())
|
||||
items := TraverseTree(
|
||||
&newCurrentDirectory,
|
||||
&newTargetDirectory,
|
||||
moduleDirectory,
|
||||
targetDirectory,
|
||||
moduleConfiguration,
|
||||
)
|
||||
|
||||
if items != nil {
|
||||
itemsToLink = append(itemsToLink, items...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return itemsToLink
|
||||
}
|
||||
|
||||
func linkItems(itemsToLink []itemToLink, dryRun bool) {
|
||||
for _, item := range itemsToLink {
|
||||
_, err := os.Stat(item.target)
|
||||
if err == nil {
|
||||
println("Target already exists", item.target)
|
||||
continue
|
||||
}
|
||||
|
||||
if dryRun {
|
||||
println("Linking", item.source, item.target)
|
||||
continue
|
||||
}
|
||||
|
||||
err = os.Symlink(item.source, item.target)
|
||||
if err != nil {
|
||||
println("Error while linking", item.source, item.target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getRelativePath(full string, parent string) string {
|
||||
return strings.TrimPrefix(full[len(parent):], string(filepath.Separator))
|
||||
}
|
||||
Reference in New Issue
Block a user