Skip to content

Commit

Permalink
Restructure packages, add show command
Browse files Browse the repository at this point in the history
  • Loading branch information
simbados committed Feb 8, 2024
1 parent efd595d commit 11d223a
Show file tree
Hide file tree
Showing 15 changed files with 146 additions and 74 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
- [ ] More testing for critical parts of the tool
- [x] Sophisticated parsing of config json keys with glob expansion
- [x] Add support of adding new config files with sb
- [ ] Helper command to show all configs file for a binary and their content and which will be applied
- [x] Helper command to show all configs file for a binary and their content and which will be applied
- [ ] Add support for removing config files with sb
- [ ] Possibility to add overall config json file to apply to all commands
- [ ] Add TLDR; for README
Expand Down
41 changes: 34 additions & 7 deletions cmd/sb/sb.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"os/user"
"sb/internal/log"
"sb/internal/osHelper"
"sb/internal/parse"
"sb/internal/sandbox"
"sb/internal/types"
"sb/internal/util"
Expand All @@ -25,9 +24,10 @@ func main() {

// set config parameter
setConfigParams(&context, input)

// parse config files
if context.Config.CliConfig == nil {
context.Config.SbConfig = parse.ConfigFileParsing(&context)
context.Config.SbConfig = util.ConfigFileParsing(&context)
} else {
log.LogDebug("Using cli options")
context.Config.SbConfig = context.Config.CliConfig
Expand Down Expand Up @@ -58,15 +58,43 @@ func parseEnvs() {
}
}

func setConfigParams(context *types.Context, args []string) {
cliOptions, cliConfig, commands := parse.OptionsParsing(&context.Paths, args[1:])
if types.CliOptions.EditEnabled {
util.EditFile(commands, context.Paths)
func checkCliOptions(context *types.Context, commands []string) {
for _, currentOption := range context.Config.CliOptions {
if currentOption == "--debug" || currentOption == "-d" {
types.CliOptions.DebugEnabled = true
} else if currentOption == "--dry-run" || currentOption == "-dr" {
types.CliOptions.DryRunEnabled = true
} else if currentOption == "--create-exe" || currentOption == "-ce" {
types.CliOptions.CreateExeEnabled = true
} else if currentOption == "--help" || currentOption == "-h" {
util.PrintHelp()
} else if currentOption == "--version" || currentOption == "-v" {
util.ShowVersion()
} else if currentOption == "--init" || currentOption == "-i" {
util.Init(&context.Paths)
} else if currentOption == "--edit" || currentOption == "-e" {
util.EditFile(commands, context.Paths)
} else if currentOption == "--show" || currentOption == "-s" {
fmt.Println(commands)
if len(commands) != 1 {
log.LogErr(`
You need to specify which config files you want to see
E.g. sb -s npm
`)
}
util.ShowConfig(context, commands[0])
}
}
}

func setConfigParams(context *types.Context, args []string) {
cliOptions, cliConfig, commands := util.OptionsParsing(&context.Paths, args[1:])
context.Config.CliConfig = cliConfig
if len(cliOptions) != 0 {
context.Config.CliOptions = cliOptions
}
// Check which options are enabled from the user
checkCliOptions(context, commands)
context.Paths.BinaryPath = getPathToExecutable(commands[0])
context.Config.BinaryName = commands[0]
context.Config.Commands = commands[1:]
Expand All @@ -85,7 +113,6 @@ func configAllPath(context *types.Context) {
context.Paths.RootConfigPath = context.Paths.HomePath + types.ConfigRepo
context.Paths.WorkingDir = getWorkingDir()
context.Paths.BinPath = "/usr/bin"
context.Paths.LocalConfigPath = context.Paths.WorkingDir + types.LocalConfigPath
sbBinPath, err := os.Executable()
if err != nil {
log.LogErr(err)
Expand Down
1 change: 1 addition & 0 deletions internal/types/cliOptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ var ValidCliOptions = map[string]string{
"-i": "-i",
"--edit": "--edit",
"-e": "-e",
"-s": "--show",
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
33 changes: 23 additions & 10 deletions internal/util/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
)

func EditFile(commands []string, paths types.Paths) {
fmt.Println(commands)
if len(commands) != 2 {
showError()
}
Expand All @@ -26,9 +27,21 @@ func EditFile(commands []string, paths types.Paths) {
defaultEditor = string(output[:len(output)-1])
}
if commands[0] == "root" {
path = getPath(commands[1], paths.RootConfigPath, path)
path = getPath(commands[1], paths.RootConfigPath)
} else if commands[0] == "local" {
path = getPath(commands[1], paths.LocalConfigPath, path)
allPath := GetSubdirectories(paths.WorkingDir, paths.HomePath)
var localConfigExists bool
for _, localPath := range allPath {
localConfigPath := localPath + types.LocalConfigPath
localConfigExists, _ = DoesPathExist(localConfigPath)
if localConfigExists {
path = getPath(commands[1], localConfigPath)
break
}
}
if !localConfigExists {
log.LogErr("No local config directory found")
}
} else {
showError()
}
Expand All @@ -37,17 +50,17 @@ func EditFile(commands []string, paths types.Paths) {
os.Exit(0)
}

func getPath(binaryName string, configPath, path string) string {
path = filepath.Join(configPath, binaryName+".json")
func getPath(binaryName string, configPath string) string {
path := filepath.Join(configPath, binaryName+".json")
if exists, _ := DoesPathExist(path); !exists {
var answer string
log.LogInfoSl(fmt.Sprintf("File does not exist, do you want to create it at path %v? (y)es/(n)o ", path))
if _, scanErr := fmt.Scanln(&answer); scanErr != nil {
showErrorIfError(scanErr)
} else {
if configPathExists, err := DoesPathExist(configPath); !configPathExists {
showErrorIfError(err)
}
}
if answer != "y" {
log.LogInfoLn("No file is created, exiting sb")
os.Exit(0)
}
}
return path
Expand All @@ -60,10 +73,10 @@ func showErrorIfError(error error) {
}

func showError() {
log.LogErr(fmt.Printf(`
log.LogErr(`
You must provide two values to edit a configuration file
Valid options are:
sb -e local <binary name>
sb -e root <binary name>
`))
`)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package parse
package util

import (
"sb/internal/types"
Expand Down
3 changes: 2 additions & 1 deletion internal/util/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func PrintHelp() {
"--dry-run -dr Do not execute the sandbox with the wanted binary will set debug and print to true so that you have all the information what sb would do\n" +
"--create-exe -ce Creates executable shim for binary, so that you can use the sandboxed binary within other programs which would natively use the normal binary\n" +
"--help -h Print this help section\n" +
"--version -v Show which version of sb is installed\n")
"--version -v Show which version of sb is installed\n" +
"--show -s Show location of all config files for this binary and the content of the file that would be applied\n")
os.Exit(0)
}
5 changes: 2 additions & 3 deletions internal/sandbox/init.go → internal/util/init.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package sandbox
package util

import (
"embed"
Expand All @@ -9,7 +9,6 @@ import (
"path/filepath"
"sb/internal/log"
"sb/internal/types"
"sb/internal/util"
)

func Init(paths *types.Paths) {
Expand Down Expand Up @@ -96,7 +95,7 @@ var configDir embed.FS

func createSbConfig(sbConfigPath string) {
log.LogInfoLn("Creating .sb-config...")
if val, _ := util.DoesPathExist(sbConfigPath); val {
if val, _ := DoesPathExist(sbConfigPath); val {
log.LogWarn(fmt.Sprintf("There is already an existing config directory at %v \nPlease create a backup or remove it to have the default configuration", sbConfigPath))
} else {
log.LogInfoLn(fmt.Sprintf("Creating directory at destination %v", sbConfigPath))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,14 @@
package parse
package util

import (
"errors"
"path/filepath"
"regexp"
"sb/internal/log"
"sb/internal/sandbox"
"sb/internal/types"
"sb/internal/util"
"strings"
)

func parseCliOptions(paths *types.Paths, option string) {
currentOption := types.ValidCliOptions[option]
if currentOption == "--debug" || currentOption == "-d" {
types.CliOptions.DebugEnabled = true
} else if currentOption == "--dry-run" || currentOption == "-dr" {
types.CliOptions.DryRunEnabled = true
} else if currentOption == "--create-exe" || currentOption == "-ce" {
types.CliOptions.CreateExeEnabled = true
} else if currentOption == "--help" || currentOption == "-h" {
util.PrintHelp()
} else if currentOption == "--version" || currentOption == "-v" {
util.ShowVersion()
} else if currentOption == "--init" || currentOption == "-i" {
sandbox.Init(paths)
} else if currentOption == "--edit" || currentOption == "-e" {
types.CliOptions.EditEnabled = true
}
}

func OptionsParsing(paths *types.Paths, args []string) ([]string, *types.SbConfig, []string) {
var options []string
var cliConfigSb types.SbConfig
Expand All @@ -40,7 +19,6 @@ func OptionsParsing(paths *types.Paths, args []string) ([]string, *types.SbConfi
split, splitValue := parseCliConfigParam(value)
if _, exist := types.ValidCliOptions[split]; exist {
options = append(options, value)
parseCliOptions(paths, value)
} else if _, configExists := types.AllowedConfigKeys[split]; configExists && len(splitValue) > 0 {
cliConfig = addToCliConfig(paths, cliConfig, cliConfigSb, splitValue, split)
} else {
Expand All @@ -51,13 +29,14 @@ func OptionsParsing(paths *types.Paths, args []string) ([]string, *types.SbConfi
break
}
}
if len(options) == len(args) {
log.LogErr("Please specify the program that you want to sandbox")
var commands []string
if len(args) != len(options) {
commands = args[optionsUntilIndex:]
}
if cliConfig != nil {
return options, cliConfig, args[optionsUntilIndex:]
return options, cliConfig, commands
} else {
return options, nil, args[optionsUntilIndex:]
return options, nil, commands
}
}

Expand Down
59 changes: 40 additions & 19 deletions internal/parse/parseConfig.go → internal/util/parseConfig.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package parse
package util

import (
"fmt"
"sb/internal/log"
"sb/internal/types"
"sb/internal/util"
"slices"
"strings"
)

func doesRootConfigDirExist(path string) bool {
isRootConfigExisting, err := util.DoesPathExist(path)
isRootConfigExisting, err := DoesPathExist(path)
if !isRootConfigExisting {
log.LogWarn("Root config directory does not exist", err)
// TODO: this could be on first run we might want to make sure it exists at this point
Expand All @@ -20,7 +19,7 @@ func doesRootConfigDirExist(path string) bool {
return true
}

func getSubdirectories(path string, homePath string) []string {
func GetSubdirectories(path string, homePath string) []string {
var allPaths []string
currentPath := ""
paths := strings.Split(path, "/")
Expand All @@ -35,49 +34,71 @@ func getSubdirectories(path string, homePath string) []string {
return allPaths
}

// ConfigFileParsing Here we only parse the config files, cli configs have already been parsed
func ConfigFileParsing(context *types.Context) *types.SbConfig {
globalConfig := &types.SbConfig{}
allLocalPath := getSubdirectories(context.Paths.WorkingDir, context.Paths.HomePath)
func LocalConfigPath(paths *types.Paths, binaryName string) (string, bool) {
allLocalPath := GetSubdirectories(paths.WorkingDir, paths.HomePath)
var localConfigExists bool
var localConfigPath string
for _, localPath := range allLocalPath {
localConfigPath = localPath + types.LocalConfigPath + "/" + context.Config.BinaryName + ".json"
localConfigExists, _ = util.DoesPathExist(localConfigPath)
localConfigPath = localPath + types.LocalConfigPath + "/" + binaryName + ".json"
localConfigExists, _ = DoesPathExist(localConfigPath)
if localConfigExists {
break
}
}
return localConfigPath, localConfigExists
}

// ConfigFileParsing Here we only parse the config files, cli configs have already been parsed
func ConfigFileParsing(context *types.Context) *types.SbConfig {
globalConfig := &types.SbConfig{}
sbConfig, localConfigExists := extractLocalConfig(context)
if localConfigExists {
localConfig := parseRootBinaryConfig(&context.Paths, localConfigPath, context.Config.Commands)
log.LogDebug("Using local config file")
return localConfig
return sbConfig
}
config, rootConfigExists := extractRootConfig(context, globalConfig)
if rootConfigExists {
return config
}
return nil
}

func extractLocalConfig(context *types.Context) (*types.SbConfig, bool) {
localConfigPath, localConfigExists := LocalConfigPath(&context.Paths, context.Config.BinaryName)
if localConfigExists {
context.Paths.LocalConfigPath = localConfigPath
localConfig := parseJsonConfig(&context.Paths, localConfigPath, context.Config.Commands)
log.LogDebug("Using local config file at path ", localConfigPath)
return localConfig, true
} else {
log.LogDebug("No local config file found at: ", localConfigPath)
log.LogDebug("Proceeding without local config")
}
return nil, false
}

func extractRootConfig(context *types.Context, globalConfig *types.SbConfig) (*types.SbConfig, bool) {
if doesRootConfigDirExist(context.Paths.RootConfigPath) {
binaryGlobalConfigPath := context.Paths.RootConfigPath + "/" + context.Config.BinaryName + ".json"
binaryPathExists, _ := util.DoesPathExist(binaryGlobalConfigPath)
binaryPathExists, _ := DoesPathExist(binaryGlobalConfigPath)
if !binaryPathExists {
log.LogWarn("No config for binary found. You might want to create a config file at: ", context.Paths.RootConfigPath)
} else {
globalConfig = parseRootBinaryConfig(&context.Paths, binaryGlobalConfigPath, context.Config.Commands)
globalConfig = parseJsonConfig(&context.Paths, binaryGlobalConfigPath, context.Config.Commands)
log.LogDebug("Using global config file")
return globalConfig
return globalConfig, true
}
} else {
log.LogDebug("No root config file found at: ", context.Paths.RootConfigPath)
log.LogDebug("Proceeding without global config")
}
return nil
return nil, false
}

func parseRootBinaryConfig(paths *types.Paths, path string, commands []string) *types.SbConfig {
func parseJsonConfig(paths *types.Paths, path string, commands []string) *types.SbConfig {
mapping := buildCommandMap(commands)
mapping["__root-config__"] = true
var configs []*types.SbConfig
configJson := util.ParseJson(path)
configJson := ParseJson(path)
for key, val := range configJson {
var command string
if strings.Contains(key, "*") {
Expand Down
Loading

0 comments on commit 11d223a

Please sign in to comment.