chore: move everything out from src

This commit is contained in:
2025-03-03 06:52:47 +01:00
parent 469e737bb3
commit 23d1aaad55
19 changed files with 1 additions and 0 deletions

8
command/command.go Normal file
View File

@@ -0,0 +1,8 @@
package command
type Command interface {
GetHelpText()
GetName() string
Run(args []string)
}

22
command/info.go Normal file
View 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
View 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
View 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))
}