Skip to content

Commit

Permalink
Merge pull request #225 from Bedrock-OSS/user-config
Browse files Browse the repository at this point in the history
Add user configuration
  • Loading branch information
Nusiq authored Nov 7, 2022
2 parents 564d348 + 6a63a48 commit d0eaab7
Show file tree
Hide file tree
Showing 16 changed files with 891 additions and 239 deletions.
6 changes: 5 additions & 1 deletion docs/_data/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ sidebar:
url: /docs/troubleshooting
- title: Project Configuration
children:
- title: "Configuration File"
- title: "Project Configuration File"
url: /docs/configuration
- title: "Data Folder"
url: /docs/data-folder
- title: "Export Targets"
url: /docs/export-targets
- title: "Profiles"
url: /docs/profiles
- title: User Configuration
children:
- title: "User Configuration"
url: /docs/user_config
- title: Working with filters
children:
- title: "Installing and Updating Filters"
Expand Down
4 changes: 2 additions & 2 deletions docs/_pages/docs/documentation/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
permalink: /docs/configuration
layout: single
classes: wide
title: Configuration File
title: Project Configuration File
sidebar:
nav: "sidebar"
---

The configuration of regolith is stored inside of `config.json`, at the top level of your Regolith project. This file will be created when you run `regolith init`.
The configuration of Regolith project is stored inside of `config.json`, at the top level of your Regolith project. This file will be created when you run `regolith init`.

## Project Config Standard

Expand Down
74 changes: 74 additions & 0 deletions docs/_pages/docs/user_config/user_config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
permalink: /docs/user_config
layout: single
classes: wide
title: User Configuration
sidebar:
nav: "sidebar"
---

User configuration file is stored in the Regolith app data folder. On Windows, it's
`%localappdata%\regolith\user_config.json`**\***. The file is used to store the user
preferences for Regolith.


# Available Options

### `use_project_app_data_storage: bool`

Default: `false`

If set to `true`, the Regolith projects will store their cache (filters, their dependencies, etc.) in the app data folder, instead of the `.regolith` folder in the project folder.
### `username: string`

Default: `"Your name"`

The username of the user, which will be used in the `author` field of the `manifest.json` file when creating a new project.

### `resolvers: list[string]`

Default: `["github.com/Bedrock-OSS/regolith-filter-resolver/resolver.json"]`

A list of resolvers, which will be used to resolve filter names to URLs for downloding when using the `regolith install` command. The default URL is always added to the end of the list. Note that the "URLs" used by the resolvers are not actual URLs. They have two parts, separated by `/`. The first part is an url to a repository on GitHub, and the second part is a path to the resolver file relative to the root of the repository. For example, the default resolver is on the `github.com/Bedrock-OSS/regolith-filter-resolver` repository, in the `resolver.json` file, but `github.com/Bedrock-OSS/regolith-filter-resolver/resolver.json` is not a valid URL.

# The `regolith config` command

The `regolith config` command is used to manage the user configuration of Regolith. It can access and modify
the user configuration file. The data is stored in the application data folder in the
"user_config.json" file.

The behavior of the command changes based on the used flags and the number of provided arguments.
The cheetsheet below shows the possible combinations of flags and arguments and what they do:

- `regolith config` - printing all properties
- `regolith config <key>` - printing specified property
- `regolith config <key> <value>` - setting property value
- `regolith config <key> --delete` - deleting a property
- `regolith config <key> <value> --append` - appending to a list proeprty
- `regolith config <key> <value> --index <index>` - replacing item in a list property
- `regolith config <key> --index <index> --delete` - deleting item in a list property

The commands that print text can take the `--full` flag to print configuration with the default values
included (if they're not defined in the config file). Without the flag, the undefined properties
will be printed as null or empty list.

# The structure of the user configuration file

The `user_config.json` file is just a regular JSON file without any nesting. You can edit it manually
if you want to but you don't have to because everything can be done with the `regolith config` command.


# Example config file
```json
{
"use_project_app_data_storage": false,
"username": "Bedrock-OSS",
"resolvers": [
"github.com/Bedrock-OSS/regolith-filter-resolver/resolver.json"
]
}
```

----

**\*** *On other platforms you can refer to Go's [os.UserCacheDir](https://pkg.go.dev/os#UserCacheDir) documentation. It's in "regolith" subdirectory of the path returned by this function*.
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ go 1.18
require (
github.com/fatih/color v1.13.0
github.com/google/go-github/v39 v39.2.0
github.com/hashicorp/go-getter v1.5.11
github.com/hashicorp/go-getter v1.6.2
github.com/nightlyone/lockfile v1.0.0
github.com/otiai10/copy v1.7.0
github.com/spf13/cobra v1.6.1
go.uber.org/zap v1.21.0
golang.org/x/mod v0.5.1
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e
muzzammil.xyz/jsonc v1.0.0
)

replace github.com/hashicorp/go-getter => github.com/arikkfir/go-getter v1.6.3-0.20220803164326-281b7670b734

require (
cloud.google.com/go v0.100.2 // indirect
cloud.google.com/go/compute v1.5.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/arikkfir/go-getter v1.6.3-0.20220803164326-281b7670b734 h1:csFUhbcumnsC5d0SMF8CvtR6Z/i4UeNgOZ6xUaQUYas=
github.com/arikkfir/go-getter v1.6.3-0.20220803164326-281b7670b734/go.mod h1:IZCrswsZPeWv9IkVnLElzRU/gz/QPi6pZHn4tv6vbwA=
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/aws/aws-sdk-go v1.43.25 h1:PtdVewK7GZAGnu7JFdi4XFgH+j2AICXkHRjaAXow/4s=
github.com/aws/aws-sdk-go v1.43.25/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
Expand Down Expand Up @@ -189,8 +191,6 @@ github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/Oth
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-getter v1.5.11 h1:wioTuNmaBU3IE9vdFtFMcmZWj0QzLc6DYaP6sNe5onY=
github.com/hashicorp/go-getter v1.5.11/go.mod h1:9i48BP6wpWweI/0/+FBjqLrp9S8XtwUGjiu0QkWHEaY=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
Expand Down Expand Up @@ -458,8 +458,8 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e h1:w36l2Uw3dRan1K3TyXriXvY+6T56GNmlKGcqiQUJDfM=
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
53 changes: 47 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,27 @@ the Regolith data folder to remove the cache files of the projects that you don'
You can clear caches of all projects stored in user data by using the "--user-cache" flag.
`

const regolithConfigDesc = `
The config command is used to manage the user configuration of Regolith. It can access and modify
the user configuration file. The data is stored in the application data folder in the
"user_config.json" file.
The behavior of the command changes based on the used flags and the number of provided arguments.
The cheetsheet below shows the possible combinations of flags and arguments and what they do:
Printing all properties: regolith config
Printing specified property: regolith config <key>
Setting property value: regolith config <key> <value>
Deleting a property: regolith config <key> --delete
Appending to a list proeprty: regolith config <key> <value> --append
Replacing item in a list property: regolith config <key> <value> --index <index>
Deleting item in a list property: regolith config <key> --index <index> --delete
The printing commands can take the --full flag to print configuration with the default values
included (if they're not defined in the config file). Without the flag, the undefined properties
will be printed as null or empty list.
`

func main() {
// Schedule error handling
var err error
Expand Down Expand Up @@ -190,6 +211,10 @@ func main() {
Short: "Downloads and installs filters from the internet and adds them to the filterDefinitions list",
Long: regolithInitDesc,
Run: func(cmd *cobra.Command, filters []string) {
if len(filters) == 0 {
cmd.Help()
return
}
err = regolith.Install(filters, force, regolith.Debug)
},
}
Expand Down Expand Up @@ -243,10 +268,7 @@ func main() {
Long: regolithToolDesc,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
err = regolith.WrappedError(
"You must specify a filter name when running " +
"the \"regolith tool\" command.\n" +
"Use \"regolith help tool\" to learn more details.")
cmd.Help()
return
}
filter := args[0]
Expand All @@ -265,16 +287,35 @@ func main() {
err = regolith.Clean(regolith.Debug, userCache)
},
}
// regolith config
cmdConfig := &cobra.Command{
Use: "config [key] [value]",
Short: " Print or modify the user configuration.",
Long: regolithConfigDesc,
Run: func(cmd *cobra.Command, args []string) {
regolith.InitLogging(regolith.Debug)
full, _ := cmd.Flags().GetBool("full")
delete, _ := cmd.Flags().GetBool("delete")
append, _ := cmd.Flags().GetBool("append")
index, _ := cmd.Flags().GetInt("index")
err = regolith.ManageConfig(regolith.Debug, full, delete, append, index, args)
},
}
cmdConfig.Flags().BoolP("full", "f", false, "When printing, prints the full configuration including default values.")
cmdConfig.Flags().BoolP("delete", "d", false, "Delete property")
cmdConfig.Flags().BoolP("append", "a", false, "Append value to array property")
cmdConfig.Flags().IntP("index", "i", -1, "The index of the array property on which to act")
subcomands = append(subcomands, cmdConfig)

cmdClean.Flags().BoolVarP(
&userCache, "user-cache", "u", false, "Clears all caches stored in user data, instead of the cache of "+
"the current project")
subcomands = append(subcomands, cmdClean)
// add --debug flag to every command
for _, cmd := range subcomands {
cmd.Flags().BoolVarP(&regolith.Debug, "debug", "d", false, "Enables debugging")
cmd.Flags().BoolVarP(&regolith.Debug, "debug", "", false, "Enables debugging")
}
// Build and run CLI
rootCmd.AddCommand(subcomands...)
rootCmd.Execute()

}
11 changes: 0 additions & 11 deletions regolith/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ type RegolithProject struct {
Profiles map[string]Profile `json:"profiles,omitempty"`
FilterDefinitions map[string]FilterInstaller `json:"filterDefinitions"`
DataPath string `json:"dataPath,omitempty"`
UseAppData bool `json:"useAppData,omitempty"`
}

// ConfigFromObject creates a "Config" object from map[string]interface{}
Expand Down Expand Up @@ -154,16 +153,6 @@ func RegolithProjectFromObject(
}
result.Profiles[profileName] = profileValue
}
// UseAppData (optional, false by default)
useAppData := false
if _, ok := obj["useAppData"]; ok {
useAppData, ok = obj["useAppData"].(bool)
if !ok {
return result, WrappedErrorf(
jsonPropertyTypeError, "useAppData", "boolean")
}
}
result.UseAppData = useAppData
return result, nil
}

Expand Down
19 changes: 0 additions & 19 deletions regolith/config_unparsed.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,3 @@ func filterDefinitionsFromConfigMap(
}
return filterDefinitions, nil
}

// useAppDataFromConfigMap returns the useAppData value from the config file
// map, without parsing it to a Config object.
func useAppDataFromConfigMap(config map[string]interface{}) (bool, error) {
regolith, ok := config["regolith"].(map[string]interface{})
if !ok {
return false, WrappedErrorf(jsonPathMissingError, "regolith")
}
filterDefinitionsInterface, ok := regolith["useAppData"]
if !ok { // false by default
return false, nil
}
filterDefinitions, ok := filterDefinitionsInterface.(bool)
if !ok {
return false, WrappedErrorf(
jsonPathTypeError, "regolith->useAppData", "bool")
}
return filterDefinitions, nil
}
17 changes: 16 additions & 1 deletion regolith/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ const (
filterRunnerRunError = "Failed to run filter.\nFilter: %s"

// Error used when GetRegolithConfigPath fails
getRegolithConfigPathError = "Failed to get path to Regolith's app data folder."
getRegolithAppDataPathError = "Failed to get path to Regolith's app data folder."

// Error used when GetUserConfig function fails
getUserConfigError = "Failed to get user configuration."

// Error used whe Regolith fails to undo failed file system operation.
fsUndoError = "Filed to undo file system operation."
Expand All @@ -172,4 +175,16 @@ const (
"program (usually terminal).\n" +
"Please close your terminal and try again.\n" +
"Make sure that you open it directly inside the root of the Regolith project."

// Error used on attempt to access user config property that is not known
// to Regolith.
invalidUserConfigPropertyError = "Invalid user configuration property:\n" +
"Property name: %s\n"

// Error used when the getGlobalUserConfigPath function fails
getGlobalUserConfigPathError = "Failed to get global user_config.json path"

// Error used when the dump method of the UserConfig object failse
userConfigDumpError = "Failed to save the user configuration.\n" +
"Path: %s"
)
4 changes: 2 additions & 2 deletions regolith/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func ExportProject(
}
}
backupPath := filepath.Join(dotRegolithPath, ".dataBackup")
revertibleOps, err := NewrevertibleFsOperations(backupPath)
revertibleOps, err := NewRevertibleFsOperations(backupPath)
if err != nil {
return WrapErrorf(err, newRevertibleFsOperationsError, backupPath)
}
Expand Down Expand Up @@ -214,7 +214,7 @@ func InplaceExportProject(
) error {
// Create revertible ops object
backupPath := filepath.Join(dotRegolithPath, ".dataBackup")
revertibleOps, err := NewrevertibleFsOperations(backupPath)
revertibleOps, err := NewRevertibleFsOperations(backupPath)
if err != nil {
return WrapErrorf(err, newRevertibleFsOperationsError, backupPath)
}
Expand Down
4 changes: 2 additions & 2 deletions regolith/file_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ type revertibleFsOperations struct {
backupFileCounter int
}

// NewrevertibleFsOperations creates a new FsOperationBatch struct.
func NewrevertibleFsOperations(backupPath string) (*revertibleFsOperations, error) {
// NewRevertibleFsOperations creates a new FsOperationBatch struct.
func NewRevertibleFsOperations(backupPath string) (*revertibleFsOperations, error) {
// Resolve the path to backups in case of changing the working directory
// during runtime
fullBackupPath, err := filepath.Abs(backupPath)
Expand Down
Loading

0 comments on commit d0eaab7

Please sign in to comment.