Skip to content

Commit

Permalink
Merge pull request #179 from Bedrock-OSS/app-data-dot-regolith-storage
Browse files Browse the repository at this point in the history
`.regolith` folder located in AppData (optional feature)
  • Loading branch information
Nusiq authored Jul 14, 2022
2 parents 139c64e + 965c311 commit 2332762
Show file tree
Hide file tree
Showing 21 changed files with 453 additions and 193 deletions.
6 changes: 5 additions & 1 deletion docs/_pages/docs/documentation/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ Example config, with many options explained:

// These fields are for Regolith specifically
"regolith": {

// "useAppData" determines whether or not to use the app data folder, regolith should save its cache
// in user app data folder (true) or in the project folder in ".regolith" (false). This setting is
// optional and defaults to false.
"useAppData": false,
// Profiles are a list of filters and export information, which can be run with 'regolith run <profile>'
"profiles": {
// 'default' is the default profile. You can add more.
Expand All @@ -51,6 +54,7 @@ Example config, with many options explained:
// Settings object, which configure how name_ninja will run (optional)
"settings": {
"language": "en_GB.lang"
}
},
{
// A second filter, which will run after 'name_ninja'
Expand Down
18 changes: 14 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,28 @@ func main() {
},
{
Name: "clean",
Usage: "Cleans cache from the .regolith folder.",
Usage: "Cleans Regolith cache.",
Action: func(c *cli.Context) error {
clearPathStates := c.Bool("path-states")
return regolith.Clean(debug, clearPathStates)
userCache := c.Bool("user-cache")
return regolith.Clean(debug, userCache, clearPathStates)
},
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "path-states",
Aliases: []string{"p"},
Usage: "Deletes file used for caching contents of " +
"paths used by Regolith (useful when Regolith " +
"doesn't export files propertly).",
"paths used by Regolith. This is useful when you " +
"work in --recycled mode and Regolith doesn't " +
"export files propertly).",
},
&cli.BoolFlag{
Name: "user-cache",
Aliases: []string{},
Usage: "Clears data of the projects cached in the " +
"user app data folder. This is useful to clean " +
"up leftover files from old projects that use " +
"the \"useAppData\" option.",
},
},
},
Expand Down
21 changes: 11 additions & 10 deletions regolith/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@ const StandardLibraryUrl = "github.com/Bedrock-OSS/regolith-filters"
const ConfigFilePath = "config.json"
const GitIgnore = "/build\n/.regolith"

var ConfigurationFolders = []string{
"packs",
"packs/data",
"packs/BP",
"packs/RP",
".regolith",
".regolith/cache",
".regolith/cache/venvs",
}

// Config represents the full configuration file of Regolith, as saved in
// "config.json".
type Config struct {
Expand Down Expand Up @@ -47,6 +37,7 @@ 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 @@ -160,6 +151,16 @@ 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, WrappedError(
"The \"useAppData\" property is not a boolean.")
}
}
result.UseAppData = useAppData
return result, nil
}

Expand Down
19 changes: 19 additions & 0 deletions regolith/config_unparsed.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,22 @@ 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, WrappedError("Missing \"regolith\" property.")
}
filterDefinitionsInterface, ok := regolith["useAppData"]
if !ok { // false by default
return false, nil
}
filterDefinitions, ok := filterDefinitionsInterface.(bool)
if !ok {
return false, WrappedError("\"regolith\"->\"useAppData\" property " +
"must be a boolean.")
}
return filterDefinitions, nil
}
31 changes: 16 additions & 15 deletions regolith/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ func GetExportPaths(
// into the project's export target. The paths are generated with
// GetExportPaths. The function uses cached data about the state of the project
// files to reduce the number of file system operations.
func RecycledExportProject(profile Profile, name string, dataPath string) error {
func RecycledExportProject(
profile Profile, name, dataPath, dotRegolithPath string,
) error {
exportTarget := profile.ExportTarget
bpPath, rpPath, err := GetExportPaths(exportTarget, name)
if err != nil {
Expand All @@ -94,7 +96,7 @@ func RecycledExportProject(profile Profile, name string, dataPath string) error
}

// Loading edited_files.json or creating empty object
editedFiles := LoadEditedFiles()
editedFiles := LoadEditedFiles(dotRegolithPath)
err = editedFiles.CheckDeletionSafety(rpPath, bpPath)
if err != nil {
return WrapErrorf(
Expand All @@ -109,9 +111,8 @@ func RecycledExportProject(profile Profile, name string, dataPath string) error
}

Logger.Infof("Exporting behavior pack to \"%s\".", bpPath)
// err = MoveOrCopy(".regolith/tmp/BP", bpPath, exportTarget.ReadOnly, true)
err = FullRecycledMoveOrCopy(
".regolith/tmp/BP", bpPath,
filepath.Join(dotRegolithPath, "tmp/BP"), bpPath,
RecycledMoveOrCopySettings{
canMove: true,
saveSourceHashes: true,
Expand All @@ -124,9 +125,8 @@ func RecycledExportProject(profile Profile, name string, dataPath string) error
return WrapError(err, "Failed to export behavior pack.")
}
Logger.Infof("Exporting project to \"%s\".", rpPath)
// err = MoveOrCopy(".regolith/tmp/RP", rpPath, exportTarget.ReadOnly, true)
err = FullRecycledMoveOrCopy(
".regolith/tmp/RP", rpPath,
filepath.Join(dotRegolithPath, "tmp/RP"), rpPath,
RecycledMoveOrCopySettings{
canMove: true,
saveSourceHashes: true,
Expand All @@ -138,9 +138,8 @@ func RecycledExportProject(profile Profile, name string, dataPath string) error
if err != nil {
return WrapError(err, "Failed to export resource pack.")
}
// err = MoveOrCopy(".regolith/tmp/data", dataPath, false, false)
err = FullRecycledMoveOrCopy(
".regolith/tmp/data", dataPath,
filepath.Join(dotRegolithPath, "tmp/data"), dataPath,
RecycledMoveOrCopySettings{
canMove: true,
saveSourceHashes: true,
Expand All @@ -162,7 +161,7 @@ func RecycledExportProject(profile Profile, name string, dataPath string) error
err,
"Failed to create a list of files edited by this 'regolith run'")
}
err = editedFiles.Dump()
err = editedFiles.Dump(dotRegolithPath)
if err != nil {
return WrapError(
err, "Failed to update the list of the files edited by Regolith."+
Expand All @@ -173,7 +172,9 @@ func RecycledExportProject(profile Profile, name string, dataPath string) error

// ExportProject copies files from the tmp paths (tmp/BP and tmp/RP) into
// the project's export target. The paths are generated with GetExportPaths.
func ExportProject(profile Profile, name string, dataPath string) error {
func ExportProject(
profile Profile, name, dataPath, dotRegolithPath string,
) error {
exportTarget := profile.ExportTarget
bpPath, rpPath, err := GetExportPaths(exportTarget, name)
if err != nil {
Expand All @@ -182,7 +183,7 @@ func ExportProject(profile Profile, name string, dataPath string) error {
}

// Loading edited_files.json or creating empty object
editedFiles := LoadEditedFiles()
editedFiles := LoadEditedFiles(dotRegolithPath)
err = editedFiles.CheckDeletionSafety(rpPath, bpPath)
if err != nil {
return WrapErrorf(
Expand Down Expand Up @@ -230,16 +231,16 @@ func ExportProject(profile Profile, name string, dataPath string) error {
}

Logger.Infof("Exporting behavior pack to \"%s\".", bpPath)
err = MoveOrCopy(".regolith/tmp/BP", bpPath, exportTarget.ReadOnly, true)
err = MoveOrCopy(filepath.Join(dotRegolithPath, "tmp/BP"), bpPath, exportTarget.ReadOnly, true)
if err != nil {
return WrapError(err, "Failed to export behavior pack.")
}
Logger.Infof("Exporting project to \"%s\".", rpPath)
err = MoveOrCopy(".regolith/tmp/RP", rpPath, exportTarget.ReadOnly, true)
err = MoveOrCopy(filepath.Join(dotRegolithPath, "tmp/RP"), rpPath, exportTarget.ReadOnly, true)
if err != nil {
return WrapError(err, "Failed to export resource pack.")
}
err = MoveOrCopy(".regolith/tmp/data", dataPath, false, false)
err = MoveOrCopy(filepath.Join(dotRegolithPath, "tmp/data"), dataPath, false, false)
if err != nil {
return WrapError(
err, "Failed to move the filter data back to the project's "+
Expand All @@ -253,7 +254,7 @@ func ExportProject(profile Profile, name string, dataPath string) error {
err,
"Failed to create a list of files edited by this 'regolith run'")
}
err = editedFiles.Dump()
err = editedFiles.Dump(dotRegolithPath)
if err != nil {
return WrapError(
err, "Failed to update the list of the files edited by Regolith."+
Expand Down
16 changes: 8 additions & 8 deletions regolith/file_protection.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"path/filepath"
)

const EditedFilesPath = ".regolith/cache/edited_files.json"
const EditedFilesPath = "cache/edited_files.json"

// PathList is an alias for []string. It's used to store a list of file paths.
type filesList = []string
Expand All @@ -21,8 +21,8 @@ type EditedFiles struct {

// LoadEditedFiles data from edited_files.json or returns an empty object
// if file doesn't exist.
func LoadEditedFiles() EditedFiles {
data, err := os.ReadFile(EditedFilesPath)
func LoadEditedFiles(dotRegolithPath string) EditedFiles {
data, err := os.ReadFile(filepath.Join(dotRegolithPath, EditedFilesPath))
if err != nil {
return NewEditedFiles()
}
Expand All @@ -35,24 +35,24 @@ func LoadEditedFiles() EditedFiles {
}

// Dump dumps EditedFiles to EditedFilesPath in JSON format.
func (f *EditedFiles) Dump() error {
func (f *EditedFiles) Dump(dotRegolithPath string) error {
result, err := json.MarshalIndent(f, "", "\t")
if err != nil {
return WrapError(err, "Failed to marshal edited files list JSON.")
}
// Create parent directory of EditedFilesPath
parentDir := filepath.Dir(EditedFilesPath)
efp := filepath.Join(dotRegolithPath, EditedFilesPath)
parentDir := filepath.Dir(efp)
err = os.MkdirAll(parentDir, 0666)
if err != nil {
return WrapErrorf(
err, "Failed to create \"%s\" directory for edited files list.",
parentDir)
}
err = os.WriteFile(EditedFilesPath, result, 0666)
err = os.WriteFile(efp, result, 0666)
if err != nil {
return WrapErrorf(
err, "Failed to save edited files list in \"%s\".",
EditedFilesPath)
err, "Failed to save edited files list in \"%s\".", efp)
}
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion regolith/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type RunContext struct {
Config *Config
Profile string
Parent *RunContext
DotRegolithPath string

// interruptionChannel is a channel that is used to notify about changes
// in the sourec files, in order to trigger a restart of the program in
Expand Down Expand Up @@ -145,7 +146,7 @@ func FilterFromObject(obj map[string]interface{}) (*Filter, error) {
}

type FilterInstaller interface {
InstallDependencies(parent *RemoteFilterDefinition) error
InstallDependencies(parent *RemoteFilterDefinition, dotRegolithPath string) error
Check(context RunContext) error
CreateFilterRunner(runConfiguration map[string]interface{}) (FilterRunner, error)
}
Expand Down
8 changes: 4 additions & 4 deletions regolith/filter_deno.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (f *DenoFilter) run(context RunContext) error {
f.Arguments...,
),
context.AbsoluteLocation,
GetAbsoluteWorkingDirectory(),
GetAbsoluteWorkingDirectory(context.DotRegolithPath),
ShortFilterName(f.Id),
)
if err != nil {
Expand All @@ -56,7 +56,7 @@ func (f *DenoFilter) run(context RunContext) error {
f.Definition.Script,
string(jsonSettings)}, f.Arguments...),
context.AbsoluteLocation,
GetAbsoluteWorkingDirectory(),
GetAbsoluteWorkingDirectory(context.DotRegolithPath),
ShortFilterName(f.Id),
)
if err != nil {
Expand Down Expand Up @@ -102,11 +102,11 @@ func (f *DenoFilterDefinition) Check(context RunContext) error {
}

func (f *DenoFilterDefinition) InstallDependencies(
parent *RemoteFilterDefinition,
parent *RemoteFilterDefinition, dotRegolithPath string,
) error {
return nil
}

func (f *DenoFilter) Check(context RunContext) error {
return f.Definition.Check(context)
}
}
13 changes: 7 additions & 6 deletions regolith/filter_exe.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func ExeFilterDefinitionFromObject(
}

func (f *ExeFilter) Run(context RunContext) (bool, error) {
if err := f.run(f.Settings, context.AbsoluteLocation); err != nil {
if err := f.run(f.Settings, context); err != nil {
return false, PassError(err)
}
return context.IsInterrupted(), nil
Expand All @@ -52,7 +52,7 @@ func (f *ExeFilterDefinition) CreateFilterRunner(
}

func (f *ExeFilterDefinition) InstallDependencies(
parent *RemoteFilterDefinition,
*RemoteFilterDefinition, string,
) error {
return nil
}
Expand All @@ -67,20 +67,21 @@ func (f *ExeFilter) Check(context RunContext) error {

func (f *ExeFilter) run(
settings map[string]interface{},
absoluteLocation string,
context RunContext,
) error {
var err error = nil
if len(settings) == 0 {
err = executeExeFile(f.Id,
f.Definition.Exe,
f.Arguments, absoluteLocation,
GetAbsoluteWorkingDirectory())
f.Arguments, context.AbsoluteLocation,
GetAbsoluteWorkingDirectory(context.DotRegolithPath))
} else {
jsonSettings, _ := json.Marshal(settings)
err = executeExeFile(f.Id,
f.Definition.Exe,
append([]string{string(jsonSettings)}, f.Arguments...),
absoluteLocation, GetAbsoluteWorkingDirectory())
context.AbsoluteLocation, GetAbsoluteWorkingDirectory(
context.DotRegolithPath))
}
if err != nil {
return WrapError(err, "Failed to run shell filter.")
Expand Down
6 changes: 3 additions & 3 deletions regolith/filter_java.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (f *JavaFilter) run(context RunContext) error {
f.Arguments...,
),
context.AbsoluteLocation,
GetAbsoluteWorkingDirectory(),
GetAbsoluteWorkingDirectory(context.DotRegolithPath),
ShortFilterName(f.Id),
)
if err != nil {
Expand All @@ -69,7 +69,7 @@ func (f *JavaFilter) run(context RunContext) error {
f.Arguments...,
),
context.AbsoluteLocation,
GetAbsoluteWorkingDirectory(),
GetAbsoluteWorkingDirectory(context.DotRegolithPath),
ShortFilterName(f.Id),
)
if err != nil {
Expand All @@ -91,7 +91,7 @@ func (f *JavaFilterDefinition) CreateFilterRunner(runConfiguration map[string]in
return filter, nil
}

func (f *JavaFilterDefinition) InstallDependencies(*RemoteFilterDefinition) error {
func (f *JavaFilterDefinition) InstallDependencies(*RemoteFilterDefinition, string) error {
return nil
}

Expand Down
Loading

0 comments on commit 2332762

Please sign in to comment.