Install command

This commit is contained in:
2024-08-23 17:45:09 +02:00
parent 448728061c
commit a84628e426
6 changed files with 163 additions and 39 deletions

99
src/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
}

View File

@@ -34,48 +34,31 @@ Options:
} }
func (LinkCommand) Run(args []string) { func (LinkCommand) Run(args []string) {
repoName, moduleName := helpers.GetRepositoryAndModuleName(args) moduleInfo, err := helpers.GetModuleInfo(args)
if moduleName == nil { if err != nil {
println("Module name is required") println(err.Error())
return return
} }
moduleDirectory := moduleInfo.ModuleDirectory
targetDirectory := moduleInfo.TargetDirectory
dryRun := lo.ContainsBy(args, func(item string) bool { return (item == "-d" || item == "--dry-run") }) dryRun := lo.ContainsBy(args, func(item string) bool { return (item == "-d" || item == "--dry-run") })
sourceDirectory, targetDirectory := helpers.GetRepositorySourceAndTargetDirectory(repoName)
if sourceDirectory == nil {
println("Source directory not exists")
return
}
sourceDirectoryFolderInfo, err := os.Stat(*sourceDirectory)
if err != nil || !sourceDirectoryFolderInfo.IsDir() {
println("Source directory not exists", *sourceDirectory)
return
}
moduleNameAsPath := strings.ReplaceAll((*moduleName), "/", string(filepath.Separator))
moduleDirectory := filepath.Join(*sourceDirectory, moduleNameAsPath)
moduleDirectoryFolderInfo, err := os.Stat(moduleDirectory)
if err != nil || !moduleDirectoryFolderInfo.IsDir() {
println("Module directory not exists", moduleDirectory)
return
}
almaConfigFilePath, err := os.Stat(filepath.Join(moduleDirectory, ".alma-config.json")) almaConfigFilePath, err := os.Stat(filepath.Join(moduleDirectory, ".alma-config.json"))
moduleConfiguration := &config.ModuleConfiguration{} moduleConfiguration := &config.ModuleConfiguration{}
if err == nil && !almaConfigFilePath.IsDir() { if err == nil && !almaConfigFilePath.IsDir() {
moduleConfiguration = config.LoadModuleConfiguration(filepath.Join(moduleDirectory, ".alma-config.json")) moduleConfiguration = config.LoadModuleConfiguration(filepath.Join(moduleDirectory, ".alma-config.json"))
targetDirectory1 := helpers.ResolvePath(moduleConfiguration.Target) targetDirectory = helpers.ResolvePath(moduleConfiguration.Target)
targetDirectory = &targetDirectory1
} }
itemsToLink := TraverseTree( itemsToLink := TraverseTree(
&moduleDirectory, &moduleDirectory,
targetDirectory, &targetDirectory,
&moduleDirectory, &moduleDirectory,
targetDirectory, &targetDirectory,
moduleConfiguration, moduleConfiguration,
) )

View File

@@ -1,44 +1,75 @@
package helpers package helpers
import ( import (
"alma/models"
"errors"
"os" "os"
"path" "path"
"path/filepath"
"strings" "strings"
"github.com/samber/lo" "github.com/samber/lo"
) )
func GetRepositoryAndModuleName(args []string) (*string, *string) { func GetModuleInfo(args []string) (moduleInfo models.ModuleInfo, error error) {
repoName, moduleName := GetRepositoryAndModuleName(args)
if moduleName == "" {
return models.ModuleInfo{}, errors.New("module name is required")
}
sourceDirectory, targetDirectory := GetRepositorySourceAndTargetDirectory(repoName)
if sourceDirectory == "" {
return models.ModuleInfo{}, errors.New("source directory not exists")
}
sourceDirectoryFolderInfo, err := os.Stat(sourceDirectory)
if err != nil || !sourceDirectoryFolderInfo.IsDir() {
return models.ModuleInfo{}, errors.New("source directory not exists")
}
moduleNameAsPath := strings.ReplaceAll(moduleName, "/", string(filepath.Separator))
moduleDirectory := filepath.Join(sourceDirectory, moduleNameAsPath)
return models.ModuleInfo{
RepositoryName: repoName,
ModuleName: moduleName,
SourceDirectory: sourceDirectory,
TargetDirectory: targetDirectory,
ModuleDirectory: moduleDirectory}, nil
}
func GetRepositoryAndModuleName(args []string) (string, string) {
return getRepositoryAndModuleName(args, false) return getRepositoryAndModuleName(args, false)
} }
func getRepositoryAndModuleName(args []string, singleParamIsRepository bool) (*string, *string) { func getRepositoryAndModuleName(args []string, singleParamIsRepository bool) (string, string) {
var repositoryName, moduleName *string = nil, nil var repositoryName, moduleName string = "", ""
usefulArgs := lo.Filter(args, func(arg string, index int) bool { return !strings.HasPrefix(arg, "-") }) usefulArgs := lo.Filter(args, func(arg string, index int) bool { return !strings.HasPrefix(arg, "-") })
if len(usefulArgs) == 1 { if len(usefulArgs) == 1 {
if singleParamIsRepository { if singleParamIsRepository {
repositoryName = &usefulArgs[0] repositoryName = usefulArgs[0]
} else { } else {
moduleName = &usefulArgs[0] moduleName = usefulArgs[0]
} }
} else if len(usefulArgs) >= 1 { } else if len(usefulArgs) >= 1 {
repositoryName = &usefulArgs[0] repositoryName = usefulArgs[0]
moduleName = &usefulArgs[1] moduleName = usefulArgs[1]
} }
return repositoryName, moduleName return repositoryName, moduleName
} }
func GetRepositorySourceAndTargetDirectory(repoName *string) (*string, *string) { func GetRepositorySourceAndTargetDirectory(repoName string) (string, string) {
repoSourceDirectory, _ := os.Getwd() repoSourceDirectory, _ := os.Getwd()
repoTargetDirectory, _ := os.Getwd() repoTargetDirectory, _ := os.Getwd()
repoTargetDirectory = path.Join(repoTargetDirectory, "..") repoTargetDirectory = path.Join(repoTargetDirectory, "..")
return GetRepositorySourceAndTargetDirectoryWithFallback(repoName, &repoSourceDirectory, &repoTargetDirectory) return GetRepositorySourceAndTargetDirectoryWithFallback(repoName, repoSourceDirectory, repoTargetDirectory)
} }
func GetRepositorySourceAndTargetDirectoryWithFallback(repoName *string, sourceFallback *string, targetFallback *string) (*string, *string) { func GetRepositorySourceAndTargetDirectoryWithFallback(repoName string, sourceFallback string, targetFallback string) (string, string) {
//TODO: Use repository configuration //TODO: Use repository configuration
return sourceFallback, targetFallback return sourceFallback, targetFallback
} }

View File

@@ -9,6 +9,7 @@ func main() {
commands := []command.Command{ commands := []command.Command{
command.LinkCommand{}, command.LinkCommand{},
command.InfoCommand{}, command.InfoCommand{},
command.InstallCommand{},
} }
run(commands, os.Args[1:]) run(commands, os.Args[1:])

9
src/models/moduleInfo.go Normal file
View File

@@ -0,0 +1,9 @@
package models
type ModuleInfo struct {
RepositoryName string
ModuleName string
SourceDirectory string
TargetDirectory string
ModuleDirectory string
}

View File

@@ -4,7 +4,8 @@
"links": { "links": {
"test_folder": "test_folder", "test_folder": "test_folder",
"test_folder2": "test_folder3" "test_folder2": "test_folder3"
} },
"install": "echo 'INSTALL WORKS!! install command for test_module'"
}, },
"win": { "win": {
}, },