chore: move everything out from src
This commit is contained in:
8
command/command.go
Normal file
8
command/command.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package command
|
||||
|
||||
type Command interface {
|
||||
GetHelpText()
|
||||
GetName() string
|
||||
Run(args []string)
|
||||
}
|
||||
|
||||
22
command/info.go
Normal file
22
command/info.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package command
|
||||
|
||||
import "alma/helpers"
|
||||
|
||||
type InfoCommand struct {
|
||||
}
|
||||
|
||||
func (InfoCommand) GetName() string {
|
||||
return "info"
|
||||
}
|
||||
|
||||
func (InfoCommand) GetHelpText() {
|
||||
println(
|
||||
`Usage:
|
||||
alma info
|
||||
alma info [module]
|
||||
alma info [repository] [module]`)
|
||||
}
|
||||
|
||||
func (InfoCommand) Run(args []string) {
|
||||
println("Platform is '" + helpers.GetOsIdentifier() + "'")
|
||||
}
|
||||
99
command/install.go
Normal file
99
command/install.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"alma/config"
|
||||
"alma/helpers"
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type InstallCommand struct {
|
||||
}
|
||||
|
||||
type shellNotFoundError struct {
|
||||
shell string
|
||||
}
|
||||
|
||||
func (e *shellNotFoundError) Error() string {
|
||||
return "Shell not found"
|
||||
}
|
||||
|
||||
func (InstallCommand) GetName() string {
|
||||
return "install"
|
||||
}
|
||||
|
||||
func (InstallCommand) GetHelpText() {
|
||||
println("Install a package")
|
||||
}
|
||||
|
||||
func (InstallCommand) Run(args []string) {
|
||||
moduleInfo, err := helpers.GetModuleInfo(args)
|
||||
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
moduleDirectory := moduleInfo.ModuleDirectory
|
||||
|
||||
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() {
|
||||
println("Error: .alma-config.json not found")
|
||||
return
|
||||
}
|
||||
|
||||
moduleConfiguration = config.LoadModuleConfiguration(filepath.Join(moduleDirectory, ".alma-config.json"))
|
||||
installCommand := moduleConfiguration.Install
|
||||
|
||||
if dryRun {
|
||||
println("Dry run, otherwise would run " + installCommand)
|
||||
return
|
||||
}
|
||||
println("Running command: " + installCommand)
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
err := runShellCommand("sh", "-c", installCommand)
|
||||
|
||||
var shellNotFoundError *shellNotFoundError
|
||||
if errors.As(err, &shellNotFoundError) {
|
||||
println(shellNotFoundError.shell + " not found")
|
||||
}
|
||||
|
||||
case "windows":
|
||||
err := runShellCommand("pwsh", "-c", installCommand)
|
||||
|
||||
var shellNotFoundError *shellNotFoundError
|
||||
if errors.As(err, &shellNotFoundError) {
|
||||
println(shellNotFoundError.shell + " not found")
|
||||
}
|
||||
default:
|
||||
println("Unsupported OS")
|
||||
}
|
||||
}
|
||||
|
||||
func runShellCommand(shellCommand string, args ...string) error {
|
||||
shell, pwshErrshellErr := exec.LookPath(shellCommand)
|
||||
if pwshErrshellErr != nil {
|
||||
return &shellNotFoundError{shell: shellCommand}
|
||||
}
|
||||
|
||||
shellArgs := append([]string{shellCommand}, args...)
|
||||
env := os.Environ()
|
||||
execErr := syscall.Exec(shell, shellArgs, env)
|
||||
if execErr != nil {
|
||||
return errors.New("Error running shell command")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
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