From de85f24185e178a923c5399d4d264e4e052d423f Mon Sep 17 00:00:00 2001 From: stirante Date: Sun, 29 Oct 2023 14:09:25 +0100 Subject: [PATCH 01/45] Introduce none export target, allow changing the directory name and refactor exporting --- regolith/config.go | 9 + .../{condition_evaluator.go => evaluator.go} | 28 ++- regolith/export.go | 169 +++++++++++------- regolith/profile.go | 11 +- 4 files changed, 145 insertions(+), 72 deletions(-) rename regolith/{condition_evaluator.go => evaluator.go} (50%) diff --git a/regolith/config.go b/regolith/config.go index a3e7b612..46913cde 100644 --- a/regolith/config.go +++ b/regolith/config.go @@ -17,10 +17,13 @@ type Config struct { // ExportTarget is a part of "config.json" that contains export information // for a profile, which denotes where compiled files will go. +// When editing, adjust ExportTargetFromObject function as well. type ExportTarget struct { Target string `json:"target,omitempty"` // The mode of exporting. "develop" or "exact" RpPath string `json:"rpPath,omitempty"` // Relative or absolute path to resource pack for "exact" export target BpPath string `json:"bpPath,omitempty"` // Relative or absolute path to resource pack for "exact" export target + RpName string `json:"rpName,omitempty"` + BpName string `json:"bpName,omitempty"` WorldName string `json:"worldName,omitempty"` WorldPath string `json:"worldPath,omitempty"` ReadOnly bool `json:"readOnly"` // Whether the exported files should be read-only @@ -179,6 +182,12 @@ func ExportTargetFromObject(obj map[string]interface{}) (ExportTarget, error) { // BpPath - can be empty bpPath, _ := obj["bpPath"].(string) result.BpPath = bpPath + // RpName - can be empty + rpName, _ := obj["rpName"].(string) + result.RpName = rpName + // BpName - can be empty + bpName, _ := obj["bpName"].(string) + result.BpName = bpName // WorldName - can be empty worldName, _ := obj["worldName"].(string) result.WorldName = worldName diff --git a/regolith/condition_evaluator.go b/regolith/evaluator.go similarity index 50% rename from regolith/condition_evaluator.go rename to regolith/evaluator.go index 186dae9a..9034d691 100644 --- a/regolith/condition_evaluator.go +++ b/regolith/evaluator.go @@ -8,23 +8,42 @@ import ( "github.com/stirante/go-simple-eval/eval/utils" ) -func EvalCondition(condition string, ctx RunContext) (bool, error) { - Logger.Debugf("Evaluating condition: %s", condition) +func EvalCondition(expression string, ctx RunContext) (bool, error) { + Logger.Debugf("Evaluating condition: %s", expression) t := prepareScope(ctx) Logger.Debugf("Evaluation scope: %s", utils.ToString(t)) - e, err := eval.Eval(condition, t) + e, err := eval.Eval(expression, t) if err != nil { - return false, burrito.WrapErrorf(err, "Failed to evaluate condition: %s", condition) + return false, burrito.WrapErrorf(err, "Failed to evaluate condition: %s", expression) } Logger.Debugf("Condition evaluated to: %s", utils.ToString(e)) return utils.ToBoolean(e), nil } +func EvalString(expression string, ctx RunContext) (string, error) { + Logger.Debugf("Evaluating expression: %s", expression) + t := prepareScope(ctx) + Logger.Debugf("Evaluation scope: %s", utils.ToString(t)) + e, err := eval.Eval(expression, t) + if err != nil { + return "", burrito.WrapErrorf(err, "Failed to evaluate condition: %s", expression) + } + Logger.Debugf("Expression evaluated to: %s", utils.ToString(e)) + if v, ok := e.(string); ok { + return v, nil + } + return "", burrito.WrapErrorf(err, "Expression evaluated to non-string value: %s", expression) +} + func prepareScope(ctx RunContext) map[string]interface{} { semverString, err := utils.ParseSemverString(Version) if err != nil { semverString = utils.Semver{} } + projectData := map[string]interface{}{ + "name": ctx.Config.Name, + "author": ctx.Config.Author, + } return map[string]interface{}{ "os": runtime.GOOS, "arch": runtime.GOARCH, @@ -33,5 +52,6 @@ func prepareScope(ctx RunContext) map[string]interface{} { "profile": ctx.Profile, "filterLocation": ctx.AbsoluteLocation, "settings": ctx.Settings, + "project": projectData, } } diff --git a/regolith/export.go b/regolith/export.go index c19082cc..31c52d1c 100644 --- a/regolith/export.go +++ b/regolith/export.go @@ -12,98 +12,145 @@ import ( // resource pack based on exportTarget (a structure with data related to // export settings) and the name of the project. func GetExportPaths( - exportTarget ExportTarget, name string, + exportTarget ExportTarget, ctx RunContext, ) (bpPath string, rpPath string, err error) { + bpName, rpName, err := GetExportNames(exportTarget, ctx) if exportTarget.Target == "development" { comMojang, err := FindMojangDir() if err != nil { return "", "", burrito.WrapError( err, "Failed to find \"com.mojang\" directory.") } - - // TODO - I don't like the _rp and _bp suffixes. Can we get rid of that? - // I for example always name my packs "0". - bpPath = comMojang + "/development_behavior_packs/" + name + "_bp" - rpPath = comMojang + "/development_resource_packs/" + name + "_rp" + return GetDevelopmentExportPaths(bpName, rpName, comMojang) } else if exportTarget.Target == "preview" { comMojang, err := FindPreviewDir() if err != nil { return "", "", burrito.WrapError( err, "Failed to find preview \"com.mojang\" directory.") } - - // TODO - I don't like the _rp and _bp suffixes. Can we get rid of that? - // I for example always name my packs "0". - bpPath = comMojang + "/development_behavior_packs/" + name + "_bp" - rpPath = comMojang + "/development_resource_packs/" + name + "_rp" + return GetDevelopmentExportPaths(bpName, rpName, comMojang) } else if exportTarget.Target == "exact" { - bpPath, err = ResolvePath(exportTarget.BpPath) + return GetExactExportPaths(exportTarget) + } else if exportTarget.Target == "world" { + return GetWorldExportPaths(exportTarget, bpName, rpName) + } else if exportTarget.Target == "local" { + bpPath = "build/" + bpName + "/" + rpPath = "build/" + bpName + "/" + } else if exportTarget.Target == "none" { + bpPath = "" + rpPath = "" + } else { + err = burrito.WrappedErrorf( + "Export target %q is not valid", exportTarget.Target) + } + return +} + +func GetDevelopmentExportPaths(bpName, rpName, comMojang string) (bpPath string, rpPath string, err error) { + if err != nil { + return "", "", burrito.WrapError( + err, "Failed to find \"com.mojang\" directory.") + } + + bpPath = comMojang + "/development_behavior_packs/" + bpName + rpPath = comMojang + "/development_resource_packs/" + rpName + return +} + +func GetExactExportPaths(exportTarget ExportTarget) (bpPath string, rpPath string, err error) { + bpPath, err = ResolvePath(exportTarget.BpPath) + if err != nil { + return "", "", burrito.WrapError( + err, "Failed to resolve behavior pack path.") + } + rpPath, err = ResolvePath(exportTarget.RpPath) + if err != nil { + return "", "", burrito.WrapError( + err, "Failed to resolve resource pack path.") + } + return +} + +func GetWorldExportPaths(exportTarget ExportTarget, bpName, rpName string) (bpPath string, rpPath string, err error) { + if exportTarget.WorldPath != "" { + if exportTarget.WorldName != "" { + return "", "", burrito.WrappedError( + "Using both \"worldName\" and \"worldPath\" is not" + + " allowed.") + } + wPath, err := ResolvePath(exportTarget.WorldPath) if err != nil { return "", "", burrito.WrapError( - err, "Failed to resolve behavior pack path.") + err, "Failed to resolve world path.") } - rpPath, err = ResolvePath(exportTarget.RpPath) + bpPath = filepath.Join( + wPath, "behavior_packs", bpName) + rpPath = filepath.Join( + wPath, "resource_packs", rpName) + } else if exportTarget.WorldName != "" { + dir, err := FindMojangDir() if err != nil { return "", "", burrito.WrapError( - err, "Failed to resolve resource pack path.") + err, "Failed to find \"com.mojang\" directory.") } - } else if exportTarget.Target == "world" { - if exportTarget.WorldPath != "" { - if exportTarget.WorldName != "" { - return "", "", burrito.WrappedError( - "Using both \"worldName\" and \"worldPath\" is not" + - " allowed.") - } - wPath, err := ResolvePath(exportTarget.WorldPath) - if err != nil { - return "", "", burrito.WrapError( - err, "Failed to resolve world path.") - } - bpPath = filepath.Join( - wPath, "behavior_packs", name+"_bp") - rpPath = filepath.Join( - wPath, "resource_packs", name+"_rp") - } else if exportTarget.WorldName != "" { - dir, err := FindMojangDir() - if err != nil { - return "", "", burrito.WrapError( - err, "Failed to find \"com.mojang\" directory.") - } - worlds, err := ListWorlds(dir) - if err != nil { - return "", "", burrito.WrapError(err, "Failed to list worlds.") - } - for _, world := range worlds { - if world.Name == exportTarget.WorldName { - bpPath = filepath.Join( - world.Path, "behavior_packs", name+"_bp") - rpPath = filepath.Join( - world.Path, "resource_packs", name+"_rp") - } + worlds, err := ListWorlds(dir) + if err != nil { + return "", "", burrito.WrapError(err, "Failed to list worlds.") + } + for _, world := range worlds { + if world.Name == exportTarget.WorldName { + bpPath = filepath.Join( + world.Path, "behavior_packs", bpName) + rpPath = filepath.Join( + world.Path, "resource_packs", rpName) } - } else { - err = burrito.WrappedError( - "The \"world\" export target requires either a " + - "\"worldName\" or \"worldPath\" property") } - } else if exportTarget.Target == "local" { - bpPath = "build/BP/" - rpPath = "build/RP/" } else { - err = burrito.WrappedErrorf( - "Export target %q is not valid", exportTarget.Target) + err = burrito.WrappedError( + "The \"world\" export target requires either a " + + "\"worldName\" or \"worldPath\" property") + } + return +} + +func GetExportNames(exportTarget ExportTarget, ctx RunContext) (bpName string, rpName string, err error) { + if exportTarget.BpName != "" { + bpName, err = EvalString(exportTarget.BpName, ctx) + if err != nil { + return "", "", burrito.WrapError( + err, "Failed to evaluate behavior pack name.") + } + } else { + bpName = ctx.Config.Name + "_bp" + } + if exportTarget.RpName != "" { + rpName, err = EvalString(exportTarget.RpName, ctx) + if err != nil { + return "", "", burrito.WrapError( + err, "Failed to evaluate resource pack name.") + } + } else { + rpName = ctx.Config.Name + "_rp" } return } // 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, dataPath, dotRegolithPath string, -) error { +func ExportProject(ctx RunContext) error { + profile, err := ctx.GetProfile() + if err != nil { + return burrito.WrapError(err, runContextGetProfileError) + } + if profile.ExportTarget.Target == "none" { + Logger.Debugf("Export target is set to \"none\". Skipping export.") + return nil + } + dataPath := ctx.Config.DataPath + dotRegolithPath := ctx.DotRegolithPath // Get the export target paths exportTarget := profile.ExportTarget - bpPath, rpPath, err := GetExportPaths(exportTarget, name) + bpPath, rpPath, err := GetExportPaths(exportTarget, ctx) if err != nil { return burrito.WrapError( err, "Failed to get generate export paths.") diff --git a/regolith/profile.go b/regolith/profile.go index 0d2ca749..2a203075 100644 --- a/regolith/profile.go +++ b/regolith/profile.go @@ -113,11 +113,7 @@ func CheckProfileImpl( func RunProfile(context RunContext) error { start: // Prepare tmp files - profile, err := context.GetProfile() - if err != nil { - return burrito.WrapErrorf(err, runContextGetProfileError) - } - err = SetupTmpFiles(*context.Config, context.DotRegolithPath) + err := SetupTmpFiles(*context.Config, context.DotRegolithPath) if err != nil { return burrito.WrapErrorf(err, setupTmpFilesError, context.DotRegolithPath) } @@ -135,8 +131,7 @@ start: // Export files Logger.Info("Moving files to target directory.") start := time.Now() - err = ExportProject( - profile, context.Config.Name, context.Config.DataPath, context.DotRegolithPath) + err = ExportProject(context) if err != nil { return burrito.WrapError(err, exportProjectError) } @@ -260,6 +255,8 @@ type FilterCollection struct { Filters []FilterRunner `json:"filters"` } +// Profile is a collection of filters and an export target +// When editing, adjust ProfileFromObject function as well type Profile struct { FilterCollection ExportTarget ExportTarget `json:"export,omitempty"` From 0c753d2226708d77d8e4b565294b0947c9a61ac6 Mon Sep 17 00:00:00 2001 From: stirante Date: Mon, 30 Oct 2023 22:51:55 +0100 Subject: [PATCH 02/45] Implement experiments flag and size_time_check experiment, that copies and deletes files based on size and modification time of both source and target directories --- main.go | 3 +- regolith/experiments.go | 26 ++++++++++ regolith/export.go | 78 +++++++++++++++++++---------- regolith/file_system.go | 108 ++++++++++++++++++++++++++++++++++++++++ regolith/profile.go | 2 +- 5 files changed, 190 insertions(+), 27 deletions(-) create mode 100644 regolith/experiments.go diff --git a/main.go b/main.go index 21590b0b..eed6a0df 100644 --- a/main.go +++ b/main.go @@ -358,10 +358,11 @@ func main() { } subcommands = append(subcommands, cmdUpdateResolvers) - // add --debug and --timings flag to every command + // add --debug, --timings and --experiment flag to every command for _, cmd := range subcommands { cmd.Flags().BoolVarP(&burrito.PrintStackTrace, "debug", "", false, "Enables debugging") cmd.Flags().BoolVarP(®olith.EnableTimings, "timings", "", false, "Enables timing information") + cmd.Flags().StringSliceVar(®olith.EnabledExperiments, "experiments", nil, "Enables experimental features") } // Build and run CLI rootCmd.AddCommand(subcommands...) diff --git a/regolith/experiments.go b/regolith/experiments.go new file mode 100644 index 00000000..d151759d --- /dev/null +++ b/regolith/experiments.go @@ -0,0 +1,26 @@ +package regolith + +type Experiment int + +const ( + // SizeTimeCheck is an experiment that checks the size and modification time when exporting + SizeTimeCheck Experiment = iota +) + +var experimentNames = map[Experiment]string{ + SizeTimeCheck: "size_time_check", +} + +var EnabledExperiments []string + +func IsExperimentEnabled(exp Experiment) bool { + if EnabledExperiments == nil { + return false + } + for _, e := range EnabledExperiments { + if e == experimentNames[exp] { + return true + } + } + return false +} diff --git a/regolith/export.go b/regolith/export.go index c19082cc..761fbccc 100644 --- a/regolith/export.go +++ b/regolith/export.go @@ -101,6 +101,7 @@ func GetExportPaths( func ExportProject( profile Profile, name, dataPath, dotRegolithPath string, ) error { + MeasureStart("Export - GetExportPaths") // Get the export target paths exportTarget := profile.ExportTarget bpPath, rpPath, err := GetExportPaths(exportTarget, name) @@ -109,6 +110,7 @@ func ExportProject( err, "Failed to get generate export paths.") } + MeasureStart("Export - LoadEditedFiles") // Loading edited_files.json or creating empty object editedFiles := LoadEditedFiles(dotRegolithPath) err = editedFiles.CheckDeletionSafety(rpPath, bpPath) @@ -124,22 +126,28 @@ func ExportProject( rpPath, bpPath) } - // Clearing output locations - // Spooky, I hope file protection works, and it won't do any damage - err = os.RemoveAll(bpPath) - if err != nil { - return burrito.WrapErrorf( - err, "Failed to clear behavior pack from build path %q.\n"+ - "Are user permissions correct?", bpPath) - } - err = os.RemoveAll(rpPath) - if err != nil { - return burrito.WrapErrorf( - err, "Failed to clear resource pack from build path %q.\n"+ - "Are user permissions correct?", rpPath) + MeasureStart("Export - Clean") + // When comparing the size and modification time of the files, we need to + // keep the files in target paths. + if !IsExperimentEnabled(SizeTimeCheck) { + // Clearing output locations + // Spooky, I hope file protection works, and it won't do any damage + err = os.RemoveAll(bpPath) + if err != nil { + return burrito.WrapErrorf( + err, "Failed to clear behavior pack from build path %q.\n"+ + "Are user permissions correct?", bpPath) + } + err = os.RemoveAll(rpPath) + if err != nil { + return burrito.WrapErrorf( + err, "Failed to clear resource pack from build path %q.\n"+ + "Are user permissions correct?", rpPath) + } } + MeasureEnd() // List the names of the filters that opt-in to the data export process - exportedFilterNames := []string{} + var exportedFilterNames []string for filter := range profile.Filters { filter := profile.Filters[filter] usingDataPath, err := filter.IsUsingDataExport(dotRegolithPath) @@ -180,6 +188,7 @@ func ExportProject( dataPath) } } + MeasureStart("Export - RevertibleOps") // Create revertible operations object backupPath := filepath.Join(dotRegolithPath, ".dataBackup") revertibleOps, err := NewRevertibleFsOperations(backupPath) @@ -187,6 +196,7 @@ func ExportProject( return burrito.WrapErrorf(err, newRevertibleFsOperationsError, backupPath) } // Export data + MeasureStart("Export - ExportData") for _, exportedFilterName := range exportedFilterNames { // Clear export target targetPath := filepath.Join(dataPath, exportedFilterName) @@ -230,18 +240,35 @@ func ExportProject( return mainError } } - // Export BP - Logger.Infof("Exporting behavior pack to \"%s\".", bpPath) - err = MoveOrCopy(filepath.Join(dotRegolithPath, "tmp/BP"), bpPath, exportTarget.ReadOnly, true) - if err != nil { - return burrito.WrapError(err, "Failed to export behavior pack.") - } - // Export RP - Logger.Infof("Exporting project to \"%s\".", filepath.Clean(rpPath)) - err = MoveOrCopy(filepath.Join(dotRegolithPath, "tmp/RP"), rpPath, exportTarget.ReadOnly, true) - if err != nil { - return burrito.WrapError(err, "Failed to export resource pack.") + MeasureStart("Export - MoveOrCopy") + if IsExperimentEnabled(SizeTimeCheck) { + // Export BP + Logger.Infof("Exporting behavior pack to \"%s\".", bpPath) + err = SyncDirectories(filepath.Join(dotRegolithPath, "tmp/BP"), bpPath, exportTarget.ReadOnly, true) + if err != nil { + return burrito.WrapError(err, "Failed to export behavior pack.") + } + // Export RP + Logger.Infof("Exporting project to \"%s\".", filepath.Clean(rpPath)) + err = SyncDirectories(filepath.Join(dotRegolithPath, "tmp/RP"), rpPath, exportTarget.ReadOnly, true) + if err != nil { + return burrito.WrapError(err, "Failed to export resource pack.") + } + } else { + // Export BP + Logger.Infof("Exporting behavior pack to \"%s\".", bpPath) + err = MoveOrCopy(filepath.Join(dotRegolithPath, "tmp/BP"), bpPath, exportTarget.ReadOnly, true) + if err != nil { + return burrito.WrapError(err, "Failed to export behavior pack.") + } + // Export RP + Logger.Infof("Exporting project to \"%s\".", filepath.Clean(rpPath)) + err = MoveOrCopy(filepath.Join(dotRegolithPath, "tmp/RP"), rpPath, exportTarget.ReadOnly, true) + if err != nil { + return burrito.WrapError(err, "Failed to export resource pack.") + } } + MeasureStart("Export - UpdateFromPaths") // Update or create edited_files.json err = editedFiles.UpdateFromPaths(rpPath, bpPath) if err != nil { @@ -258,6 +285,7 @@ func ExportProject( if err := revertibleOps.Close(); err != nil { return burrito.PassError(err) } + MeasureEnd() return nil } diff --git a/regolith/file_system.go b/regolith/file_system.go index 1f4e61cc..67fe35eb 100644 --- a/regolith/file_system.go +++ b/regolith/file_system.go @@ -9,6 +9,7 @@ import ( "sort" "strconv" "strings" + "time" "github.com/Bedrock-OSS/go-burrito/burrito" @@ -869,3 +870,110 @@ func MoveOrCopy( } return nil } + +// SyncDirectories copies the source to destination while checking size and modification time. +func SyncDirectories( + source string, destination string, makeReadOnly bool, copyParentAcl bool, +) error { + // Make destination parent if not exists + destinationParent := filepath.Dir(destination) + if _, err := os.Stat(destinationParent); os.IsNotExist(err) { + err = os.MkdirAll(destinationParent, 0755) + if err != nil { + return burrito.WrapErrorf( + err, osMkdirError, destinationParent) + } + } + err := filepath.Walk(source, func(srcPath string, info os.FileInfo, err error) error { + if err != nil { + return err + } + relPath, err := filepath.Rel(source, srcPath) + if err != nil { + return burrito.WrapErrorf(err, filepathRelError, source, srcPath) + } + destPath := filepath.Join(destination, relPath) + + destInfo, err := os.Stat(destPath) + if err != nil && !os.IsNotExist(err) { + return burrito.WrapErrorf(err, osStatErrorAny, destPath) + } + if (err != nil && os.IsNotExist(err)) || info.ModTime() != destInfo.ModTime() || info.Size() != destInfo.Size() { + if info.IsDir() { + return os.MkdirAll(destPath, info.Mode()) + } + Logger.Debugf("SYNC: Copying file %s to %s", srcPath, destPath) + return copyFile(srcPath, destPath, info) + } else { + Logger.Debugf("SYNC: Skipping file %s", srcPath) + } + return nil + }) + if err != nil { + return burrito.WrapErrorf(err, osCopyError, source, destination) + } + + // Remove files/folders in destination that are not in source + err = filepath.Walk(destination, func(destPath string, info os.FileInfo, err error) error { + if err != nil { + return err + } + relPath, err := filepath.Rel(destination, destPath) + if err != nil { + return burrito.WrapErrorf(err, filepathRelError, destination, destPath) + } + srcPath := filepath.Join(source, relPath) + if _, err := os.Stat(srcPath); os.IsNotExist(err) { + Logger.Debugf("SYNC: Removing file %s", destPath) + return os.RemoveAll(destPath) + } + return nil + }) + + if err != nil { + return burrito.WrapErrorf(err, osRemoveError, source, destination) + } + + //TODO: copy ACL. To be honest, I have no clue why it was there in the first place + + // Make files read only if this option is selected + if makeReadOnly { + Logger.Infof("Changing the access for output path to "+ + "read-only.\n\tPath: %s", destination) + err := filepath.WalkDir(destination, + func(s string, d fs.DirEntry, e error) error { + + if e != nil { + // Error message isn't important as it's not passed further + // in the code + return e + } + if !d.IsDir() { + os.Chmod(s, 0444) + } + return nil + }) + if err != nil { + Logger.Warnf( + "Failed to change access of the output path to read-only.\n"+ + "\tPath: %s", + destination) + } + } + return nil +} + +func copyFile(src, dest string, info os.FileInfo) error { + data, err := os.ReadFile(src) + if err != nil { + return burrito.WrapErrorf(err, fileReadError, src) + } + if err = os.WriteFile(dest, data, info.Mode()); err != nil { + return burrito.WrapErrorf(err, fileWriteError, dest) + } + err = os.Chtimes(dest, time.Now(), info.ModTime()) + if err != nil { + return burrito.WrapErrorf(err, osChtimesError, dest) + } + return nil +} diff --git a/regolith/profile.go b/regolith/profile.go index 0d2ca749..74c69960 100644 --- a/regolith/profile.go +++ b/regolith/profile.go @@ -51,7 +51,7 @@ func SetupTmpFiles(config Config, dotRegolithPath string) error { err = copy.Copy( path, p, - copy.Options{PreserveTimes: false, Sync: false}) + copy.Options{PreserveTimes: IsExperimentEnabled(SizeTimeCheck), Sync: false}) if err != nil { return burrito.WrapErrorf(err, osCopyError, path, p) } From c2f86e60e938fe95b1bc888a65a8aaa071dbabb6 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Tue, 31 Oct 2023 22:57:02 +0100 Subject: [PATCH 03/45] Removed 'CreateDirectoryIfNotExists(path)' function. Use 'os.MkdirAll(path, 0755)' instead. --- regolith/install_add.go | 5 +++-- regolith/main_functions.go | 4 ++-- regolith/utils.go | 15 +-------------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/regolith/install_add.go b/regolith/install_add.go index 7fc443ab..213c1acb 100644 --- a/regolith/install_add.go +++ b/regolith/install_add.go @@ -1,6 +1,7 @@ package regolith import ( + "os" "os/exec" "path/filepath" "strings" @@ -31,12 +32,12 @@ func installFilters( dataPath, dotRegolithPath string, isInstall, refreshFilters bool, ) error { joinedPath := filepath.Join(dotRegolithPath, "cache/filters") - err := CreateDirectoryIfNotExists(joinedPath) + err := os.MkdirAll(joinedPath, 0755) if err != nil { return burrito.WrapErrorf(err, osMkdirError, "cache/filters") } joinedPath = filepath.Join(dotRegolithPath, "cache/venvs") - err = CreateDirectoryIfNotExists(joinedPath) + err = os.MkdirAll(joinedPath, 0755) if err != nil { return burrito.WrapErrorf(err, osMkdirError, "cache/venvs") } diff --git a/regolith/main_functions.go b/regolith/main_functions.go index 648b5b5f..1a22e31d 100644 --- a/regolith/main_functions.go +++ b/regolith/main_functions.go @@ -241,7 +241,7 @@ func runOrWatch(profileName string, debug, watch bool) error { return burrito.WrapError( err, "Unable to get the path to regolith cache folder.") } - err = CreateDirectoryIfNotExists(dotRegolithPath) + err = os.MkdirAll(dotRegolithPath, 0755) if err != nil { return burrito.WrapErrorf(err, osMkdirError, dotRegolithPath) } @@ -330,7 +330,7 @@ func ApplyFilter(filterName string, filterArgs []string, debug bool) error { return burrito.WrapError( err, "Unable to get the path to regolith cache folder.") } - err = CreateDirectoryIfNotExists(dotRegolithPath) + err = os.MkdirAll(dotRegolithPath, 0755) if err != nil { return burrito.WrapErrorf(err, osMkdirError, dotRegolithPath) } diff --git a/regolith/utils.go b/regolith/utils.go index 4a113111..c07fc7fd 100644 --- a/regolith/utils.go +++ b/regolith/utils.go @@ -91,19 +91,6 @@ func NotImplementedError(text string) error { return burrito.WrappedError(text) } -// CreateDirectoryIfNotExists creates a directory if it doesn't exist. If -// the directory already exists, it does nothing and returns nil. -func CreateDirectoryIfNotExists(directory string) error { - if _, err := os.Stat(directory); os.IsNotExist(err) { - err = os.MkdirAll(directory, 0755) - if err != nil { - // Error outside of this function should tell about the path - return burrito.PassError(err) - } - } - return nil -} - // GetAbsoluteWorkingDirectory returns an absolute path to [dotRegolithPath]/tmp func GetAbsoluteWorkingDirectory(dotRegolithPath string) string { absoluteWorkingDir, _ := filepath.Abs(filepath.Join(dotRegolithPath, "tmp")) @@ -239,7 +226,7 @@ func GetDotRegolith(projectRoot string) (string, error) { // The path should point to the .regolith directory. func acquireSessionLock(dotRegolithPath string) (func() error, error) { // Create dotRegolithPath if it doesn't exist - err := CreateDirectoryIfNotExists(dotRegolithPath) + err := os.MkdirAll(dotRegolithPath, 0755) if err != nil { return nil, burrito.WrapErrorf(err, osMkdirError, dotRegolithPath) } From 5f419035ffe91ebaeec1b73d6ed13b8112e0381f Mon Sep 17 00:00:00 2001 From: Nusiq Date: Tue, 31 Oct 2023 23:01:26 +0100 Subject: [PATCH 04/45] Fixed a misleading eroror message. --- regolith/errors.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regolith/errors.go b/regolith/errors.go index e9217bb0..b923da00 100644 --- a/regolith/errors.go +++ b/regolith/errors.go @@ -40,7 +40,7 @@ const ( isDirEmptyError = "Failed to check if path is an empty directory.\nPath: %s" // Error used when an empty directory is expected, but it's not - isDirEmptyNotEmptyError = "Path is an empty directory.\nPath: %s" + isDirEmptyNotEmptyError = "Path is not an empty directory.\nPath: %s" // Error used when copyFileSecurityInfo fails copyFileSecurityInfoError = "Failed to copy ACL.\nSource: %s\nTarget: %s" From 6939f5d0aecd41476349444a28ebe180954d5fa4 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Tue, 31 Oct 2023 23:10:05 +0100 Subject: [PATCH 05/45] Improved error handling for os.ReadDir function calls. Added missing error handling for some os.ReadDir function calls. --- regolith/errors.go | 3 +++ regolith/export.go | 4 +--- regolith/file_system.go | 3 +++ regolith/utils_minecraft.go | 3 +-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/regolith/errors.go b/regolith/errors.go index b923da00..d0a07e8d 100644 --- a/regolith/errors.go +++ b/regolith/errors.go @@ -11,6 +11,9 @@ const ( // Error message for filepath.Abs() function. filepathAbsError = "Failed to get absolute path.\nBase path: %s" + // Error message for os.ReadDir() failure + osReadDirError = "Failed to list files in the directory.\nPath: %s" + // Error message for os.Stat failure osStatErrorAny = "Failed to access file info.\nPath: %s" diff --git a/regolith/export.go b/regolith/export.go index c19082cc..9925b1a1 100644 --- a/regolith/export.go +++ b/regolith/export.go @@ -175,9 +175,7 @@ func ExportProject( err1 = os.MkdirAll(dataPath, 0755) } if err1 != nil { - return burrito.WrapErrorf( - err, "Failed to read the files from the data path %q", - dataPath) + return burrito.WrapErrorf(err, osReadDirError, dataPath) } } // Create revertible operations object diff --git a/regolith/file_system.go b/regolith/file_system.go index 1f4e61cc..2c962771 100644 --- a/regolith/file_system.go +++ b/regolith/file_system.go @@ -735,6 +735,9 @@ func move(source, destination string) error { } // Move all files in source to destination files, err := os.ReadDir(source) + if err != nil { + return burrito.WrapErrorf(err, osReadDirError, source) + } movedFiles := make([][2]string, 0, 100) movingFailed := false var errMoving error diff --git a/regolith/utils_minecraft.go b/regolith/utils_minecraft.go index d91f5f59..129c9ff4 100644 --- a/regolith/utils_minecraft.go +++ b/regolith/utils_minecraft.go @@ -21,8 +21,7 @@ func ListWorlds(mojangDir string) ([]*World, error) { worldsPath := path.Join(mojangDir, "minecraftWorlds") files, err := os.ReadDir(worldsPath) if err != nil { - return nil, burrito.WrapErrorf( - err, "Failed to list files in the directory.\nPath: %s", worldsPath) + return nil, burrito.WrapErrorf(err, osReadDirError, worldsPath) } for _, f := range files { if f.IsDir() { From cc28afb878b5199c466c82451c8bbf9a8ff8ee2c Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 09:43:30 +0100 Subject: [PATCH 06/45] Refactored a test utility function - listPaths: - The function is called getPathHashes now - The function takes only one argument, it previously used a root and a path but in all use cases the paths were always the same --- test/apply_filter_test.go | 4 ++-- test/common.go | 18 ++++++++++-------- test/conditional_filters_test.go | 4 ++-- test/local_filters_test.go | 13 ++++++------- test/remote_filters_test.go | 18 ++++++++---------- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/test/apply_filter_test.go b/test/apply_filter_test.go index 148403ab..f1ea0b67 100644 --- a/test/apply_filter_test.go +++ b/test/apply_filter_test.go @@ -54,12 +54,12 @@ func TestApplyFilter(t *testing.T) { t.Fatal("'regolith apply-filter' failed:", err.Error()) } // Load expected result - expectedPaths, err := listPaths(expectedResult, expectedResult) + expectedPaths, err := getPathHashes(expectedResult) if err != nil { t.Fatalf("Failed to load the expected results: %s", err) } // Load actual result - actualPaths, err := listPaths(tmpDir, tmpDir) + actualPaths, err := getPathHashes(tmpDir) if err != nil { t.Fatalf("Failed to load the actual results: %s", err) } diff --git a/test/common.go b/test/common.go index 5b0ca020..233179f0 100644 --- a/test/common.go +++ b/test/common.go @@ -82,14 +82,15 @@ func firstErr(errors ...error) error { return nil } -// listPaths returns a dictionary with paths of the files from 'path' directory -// relative to 'root' directory used as keys, and with md5 hashes paths as -// values. The directory paths use empty strings instead of MD5. The function -// ignores files called .ignoreme (they simulate empty directories -// in git repository). -func listPaths(path string, root string) (map[string]string, error) { +// getPathHashes returns a dictionary with paths starting from the 'root' +// used as keys, and with their md5 hashes as values. The directory paths use +// empty strings instead of MD5. +// The function ignores ".ignoreme" and "lockfile.txt" files. +// All paths are relative to the 'root' directory. +func getPathHashes(root string) (map[string]string, error) { result := map[string]string{} - err := filepath.WalkDir(path, + err := filepath.WalkDir( + root, func(path string, data fs.DirEntry, err error) error { if err != nil { return err @@ -115,7 +116,8 @@ func listPaths(path string, root string) (map[string]string, error) { result[relPath] = hex.EncodeToString(hashInBytes) } return nil - }) + }, + ) if err != nil { return map[string]string{}, err } diff --git a/test/conditional_filters_test.go b/test/conditional_filters_test.go index ce3c4751..5674f4ab 100644 --- a/test/conditional_filters_test.go +++ b/test/conditional_filters_test.go @@ -55,13 +55,13 @@ func TestConditionalFilter(t *testing.T) { t.Fatal("'regolith run' failed:", err.Error()) } // Load expected result - expectedPaths, err := listPaths(expectedBuildResult, expectedBuildResult) + expectedPaths, err := getPathHashes(expectedBuildResult) if err != nil { t.Fatalf("Failed to load the expected results: %s", err) } // Load actual result tmpDirBuild := filepath.Join(tmpDir, "build") - actualPaths, err := listPaths(tmpDirBuild, tmpDirBuild) + actualPaths, err := getPathHashes(tmpDirBuild) if err != nil { t.Fatalf("Failed to load the actual results: %s", err) } diff --git a/test/local_filters_test.go b/test/local_filters_test.go index 798844ba..90709d78 100644 --- a/test/local_filters_test.go +++ b/test/local_filters_test.go @@ -19,8 +19,7 @@ func TestRegolithInit(t *testing.T) { } defer os.Chdir(wd) // Get paths expected in initialized project - expectedPaths, err := listPaths( - freshProjectPath, freshProjectPath) + expectedPaths, err := getPathHashes(freshProjectPath) if err != nil { t.Fatal("Unable to get list of created paths:", err) } @@ -43,7 +42,7 @@ func TestRegolithInit(t *testing.T) { if err != nil { t.Fatal("'regolith init' failed:", err.Error()) } - createdPaths, err := listPaths(".", ".") + createdPaths, err := getPathHashes(".") if err != nil { t.Fatal("Unable to get list of created paths:", err) } @@ -178,13 +177,13 @@ func TestExeFilterRun(t *testing.T) { t.Fatal("'regolith run' failed:", err.Error()) } // Load expected result - expectedPaths, err := listPaths(expectedBuildResult, expectedBuildResult) + expectedPaths, err := getPathHashes(expectedBuildResult) if err != nil { t.Fatalf("Failed to load the expected results: %s", err) } // Load actual result tmpDirBuild := filepath.Join(tmpDir, "build") - actualPaths, err := listPaths(tmpDirBuild, tmpDirBuild) + actualPaths, err := getPathHashes(tmpDirBuild) if err != nil { t.Fatalf("Failed to load the actual results: %s", err) } @@ -250,13 +249,13 @@ func TestProfileFilterRun(t *testing.T) { t.Fatal("'regolith run' failed:", err.Error()) } // Load expected result - expectedPaths, err := listPaths(expectedBuildResult, expectedBuildResult) + expectedPaths, err := getPathHashes(expectedBuildResult) if err != nil { t.Fatalf("Failed to load the expected results: %s", err) } // Load actual result tmpDirBuild := filepath.Join(tmpDir, "build") - actualPaths, err := listPaths(tmpDirBuild, tmpDirBuild) + actualPaths, err := getPathHashes(tmpDirBuild) if err != nil { t.Fatalf("Failed to load the actual results: %s", err) } diff --git a/test/remote_filters_test.go b/test/remote_filters_test.go index 3c9e8b39..3b1e1d7d 100644 --- a/test/remote_filters_test.go +++ b/test/remote_filters_test.go @@ -22,8 +22,7 @@ func TestInstallAllAndRun(t *testing.T) { } defer os.Chdir(wd) // Load expected output - expectedPaths, err := listPaths( - versionedRemoteFilterProjectAfterRun, versionedRemoteFilterProjectAfterRun) + expectedPaths, err := getPathHashes(versionedRemoteFilterProjectAfterRun) if err != nil { t.Fatal("Unable load the expected paths:", err) } @@ -63,7 +62,7 @@ func TestInstallAllAndRun(t *testing.T) { t.Fatal("'regolith run' failed:", err) } // Load created paths for comparison with expected output - createdPaths, err := listPaths(".", ".") + createdPaths, err := getPathHashes(".") if err != nil { t.Fatal("Unable to load the created paths:", err) } @@ -84,7 +83,7 @@ func TestDataModifyRemoteFilter(t *testing.T) { defer os.Chdir(wd) // Load expected output expected := filepath.Join(dataModifyRemoteFilter, "after_run") - expectedPaths, err := listPaths(expected, expected) + expectedPaths, err := getPathHashes(expected) if err != nil { t.Fatal("Unable load the expected paths:", err) } @@ -125,7 +124,7 @@ func TestDataModifyRemoteFilter(t *testing.T) { t.Fatal("'regolith run' failed:", err) } // Load created paths for comparison with expected output - createdPaths, err := listPaths(".", ".") + createdPaths, err := getPathHashes(".") if err != nil { t.Fatal("Unable to load the created paths:", err) } @@ -178,14 +177,14 @@ func TestInstall(t *testing.T) { t.Fatal("'regolith install' failed:", err) } // Load expected result - expectedPaths, err := listPaths(expectedResultPath, expectedResultPath) + expectedPaths, err := getPathHashes(expectedResultPath) if err != nil { t.Fatalf( "Failed to load expected results for version %q: %v", version, err) } // Load created paths for comparison with expected output - createdPaths, err := listPaths(".", ".") + createdPaths, err := getPathHashes(".") if err != nil { t.Fatal("Unable to load the created paths:", err) } @@ -247,15 +246,14 @@ func TestInstallAll(t *testing.T) { t.Fatal("'regolith update' failed:", err) } // Load expected result - expectedPaths, err := listPaths( - expectedResultPath, expectedResultPath) + expectedPaths, err := getPathHashes(expectedResultPath) if err != nil { t.Fatalf( "Failed to load expected results for version %q: %v", version, err) } // Load created paths for comparison with expected output - createdPaths, err := listPaths(".", ".") + createdPaths, err := getPathHashes(".") if err != nil { t.Fatal("Unable to load the created paths:", err) } From b645fcca435e925e184a748240a5c9d87644eb07 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 12:32:00 +0100 Subject: [PATCH 07/45] Added more utility functions for testing. --- .gitignore | 1 + test/common.go | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/.gitignore b/.gitignore index 041c541e..a92811b7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ docs/scraper/__pycache__/ docs/node_modules docs/docs/.vitepress/dist test/local_test.go +test/test_results diff --git a/test/common.go b/test/common.go index 233179f0..b0de5234 100644 --- a/test/common.go +++ b/test/common.go @@ -8,6 +8,8 @@ import ( "path/filepath" "strings" "testing" + + "github.com/otiai10/copy" ) // The ".ignoreme" files inside the test directories are files used to simulate @@ -133,6 +135,7 @@ func comparePathMaps( checked := struct{}{} checklist := map[string]struct{}{} // Check if all expectedPaths are created + t.Log("Checking if all expected paths are correct...") for k, expectedHash := range expectedPaths { checklist[k] = checked createdHash, exists := createdPaths[k] @@ -151,6 +154,7 @@ func comparePathMaps( } } // Check if all createdPaths are expected + t.Log("Checking if there are no unexpected paths...") for k, createdHash := range createdPaths { if _, checked := checklist[k]; checked { continue // This is checked already (skip) @@ -168,3 +172,87 @@ func comparePathMaps( } } } + +// comparePaths compares the paths created by the test with the expected paths +// and runs t.Fatal in case of finding a difference. +func comparePaths(expectedPath, createdPath string, t *testing.T) { + t.Log("Loading the expected results...") + expectedPaths, err := getPathHashes(expectedPath) + if err != nil { + t.Fatalf( + "Failed to load expected results for version %q: %v", + expectedPath, err) + } + t.Log("Loading the created paths...") + createdPaths, err := getPathHashes(createdPath) + if err != nil { + t.Fatal("Unable to load the created paths:", err) + } + t.Log("Comparing created and expected paths...") + comparePathMaps(expectedPaths, createdPaths, t) +} + +// prepareTestDirectory prepares the test directory by removing all of its files +// or creating it if necessary and returns the path to the directory. +// Exits with t.Fatal in case of error. +func prepareTestDirectory(path string, t *testing.T) string { + const testResultsDir = "test_results" + // Create the output directory + result := filepath.Join(testResultsDir, path) + if err := os.RemoveAll(result); err != nil { + t.Fatalf( + "Failed to delete the files form the testing directory."+ + "\nPath: %q\nError: %v", + testResultsDir, err) + } + if err := os.MkdirAll(result, 0755); err != nil { + t.Fatalf( + "Failed to prepare the testing directory.\nPath: %q\nError: %v", + testResultsDir, err) + } + // Get absolute path + result, err := filepath.Abs(result) + if err != nil { + t.Fatalf( + "Failed to resolve the path of the testing directory to an absolute path."+ + "\nPath: %q\nError: %v", + testResultsDir, err) + } + return result +} + +// getWdOrFatal returns the current working directory or exits with t.Fatal in +// case of error. +func getWdOrFatal(t *testing.T) string { + wd, err := os.Getwd() + if err != nil { + t.Fatal("Unable to get current working directory") + } + return wd +} + +// copyFilesOrFatal copies files from src to dest or exits with t.Fatal in case +// of error. +func copyFilesOrFatal(src, dest string, t *testing.T) { + os.MkdirAll(dest, 0755) + err := copy.Copy( + src, dest, copy.Options{PreserveTimes: false, Sync: false}) + if err != nil { + t.Fatalf( + "Failed to copy files.\nSource: %s\nDestination: %s\nError: %v", + src, dest, err) + } +} + +// absOrFatal returns the absolute path of the given path or exits with t.Fatal +// in case of error. +func absOrFatal(path string, t *testing.T) string { + abs, err := filepath.Abs(path) + if err != nil { + t.Fatalf( + "Failed to resolve the path to an absolute path.\n"+ + "Path: %q\nError: %v", + path, err) + } + return abs +} From 1f0d04a0619e817116284b1b29a6438b69d4339a Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 12:34:34 +0100 Subject: [PATCH 08/45] Refoactored TestInstallAllAndRun test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/remote_filters_test.go | 64 ++++++++++++------------------------- 1 file changed, 21 insertions(+), 43 deletions(-) diff --git a/test/remote_filters_test.go b/test/remote_filters_test.go index 3b1e1d7d..d9649032 100644 --- a/test/remote_filters_test.go +++ b/test/remote_filters_test.go @@ -15,59 +15,37 @@ import ( // results of running the filter are compared to a project with an expected // result. func TestInstallAllAndRun(t *testing.T) { - // Switching working directories in this test, make sure to go back - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Load expected output - expectedPaths, err := getPathHashes(versionedRemoteFilterProjectAfterRun) - if err != nil { - t.Fatal("Unable load the expected paths:", err) - } - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestInstallAllAndRun", t) + t.Log("Prepared testing directory: ", tmpDir) + + t.Log("Copying the project files into the testing directory...") workingDir := filepath.Join(tmpDir, "working-dir") - os.Mkdir(workingDir, 0755) - // Copy the test project to the working directory - err = copy.Copy( - versionedRemoteFilterProject, - workingDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files %q into the working directory %q", - versionedRemoteFilterProject, workingDir, - ) - } - // Switch to the working directory + copyFilesOrFatal(versionedRemoteFilterProject, workingDir, t) + + // Load abs path of the expected result and switch to the working directory + expectedPath := absOrFatal(versionedRemoteFilterProjectAfterRun, t) + wd := getWdOrFatal(t) + defer os.Chdir(wd) os.Chdir(workingDir) + // THE TEST - // Run InstallDependencies - err = regolith.InstallAll(false, true, false) + t.Log("Testing the 'regolith install-all' command...") + err := regolith.InstallAll(false, true, false) if err != nil { t.Fatal("'regolith install-all' failed:", err) } + + t.Log("Testing the 'regolith run' command...") err = regolith.Run("dev", true) if err != nil { t.Fatal("'regolith run' failed:", err) } - // Load created paths for comparison with expected output - createdPaths, err := getPathHashes(".") - if err != nil { - t.Fatal("Unable to load the created paths:", err) - } - // Compare the installed dependencies with the expected dependencies - comparePathMaps(expectedPaths, createdPaths, t) + + // TEST EVALUATION + t.Log("Evaluating the test results...") + comparePaths(expectedPath, ".", t) // expected vs created paths } // TestDataModifyRemoteFilter installs a project with one filter using From 6f2686dc4a2bd0c474d7614f30ed9d0de2c5dae0 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 12:54:00 +0100 Subject: [PATCH 09/45] Refoactored TestDataModifyRemoteFilter test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/remote_filters_test.go | 67 +++++++++++-------------------------- 1 file changed, 19 insertions(+), 48 deletions(-) diff --git a/test/remote_filters_test.go b/test/remote_filters_test.go index d9649032..59d55563 100644 --- a/test/remote_filters_test.go +++ b/test/remote_filters_test.go @@ -18,7 +18,6 @@ func TestInstallAllAndRun(t *testing.T) { // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestInstallAllAndRun", t) - t.Log("Prepared testing directory: ", tmpDir) t.Log("Copying the project files into the testing directory...") workingDir := filepath.Join(tmpDir, "working-dir") @@ -26,8 +25,6 @@ func TestInstallAllAndRun(t *testing.T) { // Load abs path of the expected result and switch to the working directory expectedPath := absOrFatal(versionedRemoteFilterProjectAfterRun, t) - wd := getWdOrFatal(t) - defer os.Chdir(wd) os.Chdir(workingDir) // THE TEST @@ -53,61 +50,35 @@ func TestInstallAllAndRun(t *testing.T) { // property, which means that the 'data' folder that it modifies should be // copied back to the source files. func TestDataModifyRemoteFilter(t *testing.T) { - // Switching working directories in this test, make sure to go back - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Load expected output - expected := filepath.Join(dataModifyRemoteFilter, "after_run") - expectedPaths, err := getPathHashes(expected) - if err != nil { - t.Fatal("Unable load the expected paths:", err) - } - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) - workingDir := filepath.Join(tmpDir, "working-dir") - os.Mkdir(workingDir, 0755) - // Copy the test project to the working directory + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestDataModifyRemoteFilter", t) + + t.Log("Copying the project files into the testing directory...") projectPath := filepath.Join(dataModifyRemoteFilter, "project") - err = copy.Copy( - projectPath, - workingDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files %q into the working directory %q", - projectPath, workingDir, - ) - } - // Switch to the working directory + workingDir := filepath.Join(tmpDir, "working-dir") + copyFilesOrFatal(projectPath, workingDir, t) + + // Load expected output, and switch to the working directory + dataModifyRemoteFilterAfterRun := filepath.Join( + dataModifyRemoteFilter, "after_run") + expectedPath := absOrFatal(dataModifyRemoteFilterAfterRun, t) os.Chdir(workingDir) + // THE TEST - // Run InstallDependencies - err = regolith.InstallAll(false, true, false) + t.Log("Testing the 'regolith install-all' command...") + err := regolith.InstallAll(false, true, false) if err != nil { t.Fatal("'regolith install-all' failed:", err) } + + t.Log("Testing the 'regolith run' command...") err = regolith.Run("default", true) if err != nil { t.Fatal("'regolith run' failed:", err) } - // Load created paths for comparison with expected output - createdPaths, err := getPathHashes(".") - if err != nil { - t.Fatal("Unable to load the created paths:", err) - } - // Compare the installed dependencies with the expected dependencies - comparePathMaps(expectedPaths, createdPaths, t) + // TEST EVALUATION + comparePaths(expectedPath, ".", t) } // TestInstall tests the 'regolith install' command. It forcefully installs From eba50101f22950b86f031f3c86d784a10bf98d22 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 13:42:05 +0100 Subject: [PATCH 10/45] Refoactored TestInstall test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/remote_filters_test.go | 54 +++++++++++++++---------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/test/remote_filters_test.go b/test/remote_filters_test.go index 59d55563..be0c01e8 100644 --- a/test/remote_filters_test.go +++ b/test/remote_filters_test.go @@ -85,22 +85,16 @@ func TestDataModifyRemoteFilter(t *testing.T) { // a filter with various versions and compares the outputs with the expected // results. func TestInstall(t *testing.T) { - // SETUP - wd, err1 := os.Getwd() - defer os.Chdir(wd) // Go back before the test ends - tmpDir, err2 := os.MkdirTemp("", "regolith-test") - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) // 'tmpDir' can't be used when we delete it - err3 := copy.Copy( // Copy the test files - freshProjectPath, - tmpDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - err4 := os.Chdir(tmpDir) - if err := firstErr(err1, err2, err3, err4); err != nil { - t.Fatalf("Failed to setup test: %v", err) - } - t.Logf("The testing directory is in: %s", tmpDir) + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestInstall", t) + + t.Log("Copying the project files into the testing directory...") + copyFilesOrFatal(freshProjectPath, tmpDir, t) + + // Switch to the working directory + originalWd := getWdOrFatal(t) + os.Chdir(tmpDir) // THE TEST filterName := "github.com/Bedrock-OSS/regolith-test-filters/" + @@ -118,27 +112,23 @@ func TestInstall(t *testing.T) { "TEST_TAG_1": "testdata/regolith_install/tag", } for version, expectedResultPath := range regolithInstallProjects { - expectedResultPath = filepath.Join(wd, expectedResultPath) + t.Logf("Testing 'regolith install', filter version %q", version) + expectedResultPath = filepath.Join(originalWd, expectedResultPath) // Install the filter with given version err := regolith.Install( - []string{filterName + "==" + version}, true, false, false, false, []string{"default"}, true) + []string{filterName + "==" + version}, // Filters list + true, // Force + false, // Refresh resolvers + false, // Refresh filters + false, // Add to config + []string{"default"}, // Profiles + true, // Debug + ) if err != nil { t.Fatal("'regolith install' failed:", err) } - // Load expected result - expectedPaths, err := getPathHashes(expectedResultPath) - if err != nil { - t.Fatalf( - "Failed to load expected results for version %q: %v", - version, err) - } - // Load created paths for comparison with expected output - createdPaths, err := getPathHashes(".") - if err != nil { - t.Fatal("Unable to load the created paths:", err) - } - // Compare the installed dependencies with the expected dependencies - comparePathMaps(expectedPaths, createdPaths, t) + // TEST EVALUATION + comparePaths(expectedResultPath, ".", t) } } From a693070d7bc0991256db6bab97f791e052221905 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 14:18:56 +0100 Subject: [PATCH 11/45] Refoactored TestInstallAll test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/remote_filters_test.go | 58 ++++++++++++++----------------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/test/remote_filters_test.go b/test/remote_filters_test.go index be0c01e8..9c2c13d2 100644 --- a/test/remote_filters_test.go +++ b/test/remote_filters_test.go @@ -136,22 +136,17 @@ func TestInstall(t *testing.T) { // command. It switches versions of a filter in the config.json file, runs // 'regolith install-all', and compares the outputs with the expected results. func TestInstallAll(t *testing.T) { - // SETUP - wd, err1 := os.Getwd() - defer os.Chdir(wd) // Go back before the test ends - tmpDir, err2 := os.MkdirTemp("", "regolith-test") - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) // 'tmpDir' can't be used when we delete it - err3 := copy.Copy( // Copy the test files - filepath.Join(regolithUpdatePath, "fresh_project"), - tmpDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - err4 := os.Chdir(tmpDir) - if err := firstErr(err1, err2, err3, err4); err != nil { - t.Fatalf("Failed to setup test: %v", err) - } - t.Logf("The testing directory is in: %s", tmpDir) + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestInstallAll", t) + + t.Log("Copying the project files into the testing directory...") + copyFilesOrFatal( + filepath.Join(regolithUpdatePath, "fresh_project"), tmpDir, t) + + // Switch to the working directory + originalWd := getWdOrFatal(t) + os.Chdir(tmpDir) // THE TEST var regolithInstallProjects = map[string]string{ @@ -167,37 +162,26 @@ func TestInstallAll(t *testing.T) { regolithUpdatePath, "sha"), "TEST_TAG_1": filepath.Join(regolithUpdatePath, "tag"), } - t.Log("Testing 'regolith install-all'") for version, expectedResultPath := range regolithInstallProjects { - t.Logf("Testing version %q", version) - expectedResultPath = filepath.Join(wd, expectedResultPath) - // Copy the config file from expectedResultPath to tmpDir + t.Logf("Testing 'regolith install-all', filter version %q", version) + expectedResultPath = filepath.Join(originalWd, expectedResultPath) + + // User's action: change the config.json file + t.Log("Simulating user's action (changing the config)...") err := copy.Copy( filepath.Join(expectedResultPath, "config.json"), - filepath.Join(tmpDir, "config.json"), - ) + filepath.Join(tmpDir, "config.json")) if err != nil { t.Fatal("Failed to copy config file for the test setup:", err) } + // Run 'regolith update' / 'regolith update-all' + t.Log("Running 'regolith update'...") err = regolith.InstallAll(false, true, false) if err != nil { t.Fatal("'regolith update' failed:", err) } - // Load expected result - expectedPaths, err := getPathHashes(expectedResultPath) - if err != nil { - t.Fatalf( - "Failed to load expected results for version %q: %v", - version, err) - } - // Load created paths for comparison with expected output - createdPaths, err := getPathHashes(".") - if err != nil { - t.Fatal("Unable to load the created paths:", err) - } - // Compare the installed dependencies with the expected - // dependencies - comparePathMaps(expectedPaths, createdPaths, t) + // TEST EVALUATION + comparePaths(expectedResultPath, ".", t) } } From c10fc3702c6b63873d328e4fc8d2fb9c27788740 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 14:28:13 +0100 Subject: [PATCH 12/45] Added some extra logging information into the remote_filters_test.go tests. --- test/remote_filters_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/remote_filters_test.go b/test/remote_filters_test.go index 9c2c13d2..3fe8469c 100644 --- a/test/remote_filters_test.go +++ b/test/remote_filters_test.go @@ -78,6 +78,7 @@ func TestDataModifyRemoteFilter(t *testing.T) { t.Fatal("'regolith run' failed:", err) } // TEST EVALUATION + t.Log("Evaluating the test results...") comparePaths(expectedPath, ".", t) } @@ -128,6 +129,7 @@ func TestInstall(t *testing.T) { t.Fatal("'regolith install' failed:", err) } // TEST EVALUATION + t.Log("Evaluating the test results...") comparePaths(expectedResultPath, ".", t) } } @@ -182,6 +184,7 @@ func TestInstallAll(t *testing.T) { t.Fatal("'regolith update' failed:", err) } // TEST EVALUATION + t.Log("Evaluating the test results...") comparePaths(expectedResultPath, ".", t) } } From b920c4a301074b44ba4cad7703baedf436db07fe Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 14:34:30 +0100 Subject: [PATCH 13/45] Improved log messages in test/common.go -> comparePaths function. --- test/common.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/common.go b/test/common.go index b0de5234..2dc1b03c 100644 --- a/test/common.go +++ b/test/common.go @@ -180,13 +180,16 @@ func comparePaths(expectedPath, createdPath string, t *testing.T) { expectedPaths, err := getPathHashes(expectedPath) if err != nil { t.Fatalf( - "Failed to load expected results for version %q: %v", + "Failed to load expected results for test result evaluation.\n"+ + "Expected path: %v\nError: %v", expectedPath, err) } t.Log("Loading the created paths...") createdPaths, err := getPathHashes(createdPath) if err != nil { - t.Fatal("Unable to load the created paths:", err) + t.Fatalf("Failed to load created paths for test result evaluation.\n"+ + "Created path: %v\nError: %v", + createdPath, err) } t.Log("Comparing created and expected paths...") comparePathMaps(expectedPaths, createdPaths, t) From 194124aef9127a6cdec0e1d175bf4f1dcc9acd55 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 14:34:59 +0100 Subject: [PATCH 14/45] Refoactored TestRegolithInit test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/local_filters_test.go | 39 +++++++++----------------------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/test/local_filters_test.go b/test/local_filters_test.go index 90709d78..7d310b3e 100644 --- a/test/local_filters_test.go +++ b/test/local_filters_test.go @@ -12,41 +12,20 @@ import ( // TestRegolithInit tests the results of InitializeRegolithProject against // the values from test/testdata/fresh_project. func TestRegolithInit(t *testing.T) { - // Switching working directories in this test, make sure to go back - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Get paths expected in initialized project - expectedPaths, err := getPathHashes(freshProjectPath) - if err != nil { - t.Fatal("Unable to get list of created paths:", err) - } - // Create temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary path:", tmpDir) - // Before removing working dir make sure the script isn't using it anymore - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestRegolithInit", t) + + expectedPath := absOrFatal(freshProjectPath, t) + os.Chdir(tmpDir) - // Change working directory to the tmp path - if err := os.Chdir(tmpDir); err != nil { - t.Fatal("Unable to change working directory:", err.Error()) - } // THE TEST - err = regolith.Init(true, false) + t.Log("Testing the 'regolith init' command...") + err := regolith.Init(true, false) if err != nil { t.Fatal("'regolith init' failed:", err.Error()) } - createdPaths, err := getPathHashes(".") - if err != nil { - t.Fatal("Unable to get list of created paths:", err) - } - comparePathMaps(expectedPaths, createdPaths, t) + comparePaths(expectedPath, ".", t) } // TestRegolithRunMissingRp tests the behavior of RunProfile when the packs/RP From ebbb96413a64cab4347e570e5efd5089c06a4bd2 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 14:42:03 +0100 Subject: [PATCH 15/45] Refoactored TestRegolithRunMissingRp test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/local_filters_test.go | 42 +++++++++----------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/test/local_filters_test.go b/test/local_filters_test.go index 7d310b3e..aefcdadb 100644 --- a/test/local_filters_test.go +++ b/test/local_filters_test.go @@ -29,41 +29,19 @@ func TestRegolithInit(t *testing.T) { } // TestRegolithRunMissingRp tests the behavior of RunProfile when the packs/RP -// directory is missing. +// directory is missing. The test just checks if the command runs without +// errors. func TestRegolithRunMissingRp(t *testing.T) { - // SETUP - // Switching working directories in this test, make sure to go back - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) - os.Mkdir(tmpDir, 0755) - // Copy the test project to the working directory - err = copy.Copy( - runMissingRpProjectPath, - tmpDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files %q into the working directory %q", - runMissingRpProjectPath, tmpDir, - ) - } - // Switch to the working directory + // TEST PREPARATOIN + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestRegolithRunMissingRp", t) + + t.Log("Copying the project files into the testing directory...") + copyFilesOrFatal(runMissingRpProjectPath, tmpDir, t) os.Chdir(tmpDir) + // THE TEST - err = regolith.Run("dev", true) + err := regolith.Run("dev", true) if err != nil { t.Fatal("'regolith run' failed:", err) } From 283a8ba6f487ce52c5f897d73f44f0da96259cd3 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 14:52:00 +0100 Subject: [PATCH 16/45] Refoactored TestLocalRequirementsInstallAndRun test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/local_filters_test.go | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/test/local_filters_test.go b/test/local_filters_test.go index aefcdadb..c851046c 100644 --- a/test/local_filters_test.go +++ b/test/local_filters_test.go @@ -51,39 +51,21 @@ func TestRegolithRunMissingRp(t *testing.T) { // project that uses local script with requirements.txt by running // "regolith install" first and then "regolith run" on that project. func TestLocalRequirementsInstallAndRun(t *testing.T) { - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) - // Copy the test project to the working directory - err = copy.Copy( - localRequirementsPath, - tmpDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files %q into the working directory %q", - localRequirementsPath, tmpDir, - ) - } - // Switch to the working directory + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestLocalRequirementsInstallAndRun", t) + + t.Log("Copying the project files into the testing directory...") + copyFilesOrFatal(localRequirementsPath, tmpDir, t) os.Chdir(filepath.Join(tmpDir, "project")) + // THE TEST - err = regolith.InstallAll(false, true, false) + t.Log("Testing the 'regolith install-all' command...") + err := regolith.InstallAll(false, true, false) if err != nil { t.Fatal("'regolith install-all' failed", err.Error()) } + t.Log("Testing the 'regolith run' command...") if err := regolith.Run("dev", true); err != nil { t.Fatal("'regolith run' failed:", err.Error()) } From 7dd58ad37bd7fdc29fde4feb1fcecfe67958790e Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 15:08:38 +0100 Subject: [PATCH 17/45] Refoactored TestExeFilterRun test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/local_filters_test.go | 68 ++++++++++---------------------------- 1 file changed, 17 insertions(+), 51 deletions(-) diff --git a/test/local_filters_test.go b/test/local_filters_test.go index c851046c..63d25524 100644 --- a/test/local_filters_test.go +++ b/test/local_filters_test.go @@ -73,61 +73,27 @@ func TestLocalRequirementsInstallAndRun(t *testing.T) { // TextExeFilterRun tests if Regolith can properly run an Exe filter func TestExeFilterRun(t *testing.T) { - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) - // Copy the test project to the working directory - project, err := filepath.Abs(filepath.Join(exeFilterPath, "project")) - if err != nil { - t.Fatal( - "Unable to get absolute path to the test project:", err) - } - expectedBuildResult, err := filepath.Abs( - filepath.Join(exeFilterPath, "expected_build_result")) - if err != nil { - t.Fatal( - "Unable to get absolute path to the expected build result:", err) - } - err = copy.Copy( - project, - tmpDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files from %q into the working directory %q", - project, tmpDir, - ) - } - // THE TEST + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestExeFilterRun", t) + + t.Log("Copying the project files into the testing directory...") + project := absOrFatal(filepath.Join(exeFilterPath, "project"), t) + copyFilesOrFatal(project, tmpDir, t) + + // Load abs path of the expected result and switch to the working directory + expectedBuildResult := absOrFatal( + filepath.Join(exeFilterPath, "expected_build_result"), t) os.Chdir(tmpDir) + + // THE TEST + t.Log("Testing the 'regolith run' command...") if err := regolith.Run("dev", true); err != nil { t.Fatal("'regolith run' failed:", err.Error()) } - // Load expected result - expectedPaths, err := getPathHashes(expectedBuildResult) - if err != nil { - t.Fatalf("Failed to load the expected results: %s", err) - } - // Load actual result - tmpDirBuild := filepath.Join(tmpDir, "build") - actualPaths, err := getPathHashes(tmpDirBuild) - if err != nil { - t.Fatalf("Failed to load the actual results: %s", err) - } - // Compare the results - comparePathMaps(expectedPaths, actualPaths, t) + // TEST EVALUATION + t.Log("Evaluating the test results...") + comparePaths(expectedBuildResult, filepath.Join(tmpDir, "build"), t) } // TestProfileFilterRun tests valid and invalid profile filters. The invalid From 3918259d36039312383fa31a198891a54baba7f6 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 15:21:38 +0100 Subject: [PATCH 18/45] Refoactored TestProfileFilterRun test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/local_filters_test.go | 84 ++++++++++++-------------------------- 1 file changed, 25 insertions(+), 59 deletions(-) diff --git a/test/local_filters_test.go b/test/local_filters_test.go index 63d25524..2a237a71 100644 --- a/test/local_filters_test.go +++ b/test/local_filters_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/Bedrock-OSS/regolith/regolith" - "github.com/otiai10/copy" ) // TestRegolithInit tests the results of InitializeRegolithProject against @@ -100,70 +99,37 @@ func TestExeFilterRun(t *testing.T) { // profile filter has circular dependencies and should fail, the valid profile // filter runs the same exe file as the TestExeFilterRun test. func TestProfileFilterRun(t *testing.T) { - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) - // Copy the test project to the working directory - project, err := filepath.Abs(filepath.Join(profileFilterPath, "project")) - if err != nil { - t.Fatal( - "Unable to get absolute path to the test project:", err) - } - expectedBuildResult, err := filepath.Abs( - filepath.Join(exeFilterPath, "expected_build_result")) - if err != nil { - t.Fatal( - "Unable to get absolute path to the expected build result:", err) - } - err = copy.Copy( - project, - tmpDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files from %q into the working directory %q", - project, tmpDir, - ) - } - // THE TEST + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestProfileFilterRun", t) + + t.Log("Copying the project files into the testing directory...") + project := absOrFatal(filepath.Join(profileFilterPath, "project"), t) + copyFilesOrFatal(project, tmpDir, t) + + // Load abs path of the expected result and switch to the working directory + expectedBuildResult := absOrFatal( + filepath.Join(exeFilterPath, "expected_build_result"), t) os.Chdir(tmpDir) - t.Log("Running invalid profile filter with circular " + - "dependencies (this should fail)") - if err := regolith.Run( - "invalid_circular_profile_1", true); err == nil { + + // THE TEST + // Invalid profile (shoud fail) + t.Log("Running invalid profile filter with circular dependencies (this should fail).") + err := regolith.Run("invalid_circular_profile_1", true) + if err == nil { t.Fatal("'regolith run' didn't return an error after running"+ " a circular profile filter:", err.Error()) } else { t.Log("Task failed successfully") } - t.Log("Running valid profile filter ") - if err := regolith.Run( - "correct_nested_profile", true); err != nil { - t.Fatal("'regolith run' failed:", err.Error()) - } - // Load expected result - expectedPaths, err := getPathHashes(expectedBuildResult) + // Valid profile (should succeed) + t.Log("Running valid profile filter.") + err = regolith.Run("correct_nested_profile", true) if err != nil { - t.Fatalf("Failed to load the expected results: %s", err) - } - // Load actual result - tmpDirBuild := filepath.Join(tmpDir, "build") - actualPaths, err := getPathHashes(tmpDirBuild) - if err != nil { - t.Fatalf("Failed to load the actual results: %s", err) + t.Fatal("'regolith run' failed:", err.Error()) } - // Compare the results - comparePathMaps(expectedPaths, actualPaths, t) + + // TEST EVALUATION + t.Log("Evaluating the test results...") + comparePaths(expectedBuildResult, filepath.Join(tmpDir, "build"), t) } From ea9a82ab8dea69389dcded966ae6595f75ea7d66 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 15:38:09 +0100 Subject: [PATCH 19/45] Refoactored TestSwitchingExportTargets test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/file_protection_test.go | 44 ++++++++++++------------------------ 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/test/file_protection_test.go b/test/file_protection_test.go index 1ef25e1b..bc3f406d 100644 --- a/test/file_protection_test.go +++ b/test/file_protection_test.go @@ -15,49 +15,35 @@ import ( // 1. Runs Regolith with target A // 2. Runs Regolith with target B // 3. Runs Regolith with target A again +// This test only checks if the regolith run command runs successfuly. It +// doesn't check if the files are exported correctly. func TestSwitchingExportTargets(t *testing.T) { - // Switching working directories in this test, make sure to go back - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestSwitchingExportTargets", t) + + t.Log("Copying the project files into the testing directory...") workingDir := filepath.Join(tmpDir, "working-dir") - os.Mkdir(workingDir, 0755) - // Copy the test project to the working directory - err = copy.Copy( - multitargetProjectPath, - workingDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files %q into the working directory %q", - multitargetProjectPath, workingDir, - ) - } + copyFilesOrFatal(multitargetProjectPath, workingDir, t) + // Switch to the working directory os.Chdir(workingDir) + // THE TEST // Run Regolith with targets: A, B, A - err = regolith.Run("exact_export_A", true) + t.Log("Testing the 'regolith run' with changing export targets...") + t.Log("Running Regolith with target A...") + err := regolith.Run("exact_export_A", true) if err != nil { t.Fatal( "Unable RunProfile failed on first attempt to export to A:", err) } + t.Log("Running Regolith with target B...") err = regolith.Run("exact_export_B", true) if err != nil { t.Fatal("Unable RunProfile failed on attempt to export to B:", err) } + t.Log("Running Regolith with target A (2nd time)...") err = regolith.Run("exact_export_A", true) if err != nil { t.Fatal( From ffd56241951f6fb8afadb4e73a7a165e9afc7ee9 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 15:43:50 +0100 Subject: [PATCH 20/45] Refoactored TestTriggerFileProtection test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/file_protection_test.go | 53 ++++++++++++++---------------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/test/file_protection_test.go b/test/file_protection_test.go index bc3f406d..24bf25db 100644 --- a/test/file_protection_test.go +++ b/test/file_protection_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/Bedrock-OSS/regolith/regolith" - "github.com/otiai10/copy" ) // TestSwitchingExportTargets tests if the file protection system won't get @@ -57,52 +56,40 @@ func TestSwitchingExportTargets(t *testing.T) { // 1. Runs Regolith to export something to a target directory. // 2. Creates a file in the target directory. // 3. Runs Regolith to export again to the same target directory. +// This test only checks if the regolith run command runs successfuly. It +// doesn't check if the files are exported correctly. func TestTriggerFileProtection(t *testing.T) { - // Switching working directories in this test, make sure to go back - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestTriggerFileProtection", t) + + t.Log("Copying the project files into the testing directory...") workingDir := filepath.Join(tmpDir, "working-dir") - os.Mkdir(workingDir, 0755) - // Copy the test project to the working directory - err = copy.Copy( - multitargetProjectPath, - workingDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files %q into the working directory %q", - multitargetProjectPath, workingDir, - ) - } + copyFilesOrFatal(multitargetProjectPath, workingDir, t) + // Switch to the working directory os.Chdir(workingDir) + // THE TEST - // Run Regolith (export to A) - err = regolith.Run("exact_export_A", true) + // 1. Run Regolith (export to A) + t.Log("Testing the 'regolith run' with file protection...") + t.Log("Running Regolith...") + err := regolith.Run("exact_export_A", true) if err != nil { t.Fatal( "Unable RunProfile failed on first attempt to export to A:", err) } - // 2. Create a file in the target directory + + // 2. Create a file in the target directory (simulate user action). + t.Log("Creating a file in the target directory (simulating user action)...") file, err := os.Create(filepath.Join(tmpDir, "target-a/BP/test-file")) if err != nil { t.Fatal("Unable to create test file:", err) } file.Close() - // 3. Run Regolith (export to A) + + // 3. Run Regolith (export to A), expect failure. + t.Log("Running Regolith (this should be stopped by file protection system)...") err = regolith.Run("exact_export_A", true) if err == nil { t.Fatal("Expected RunProfile to fail on second attempt to export to A") From e2a7b335eade343898ff992cd21bc01dbd8b4e4d Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 16:14:36 +0100 Subject: [PATCH 21/45] Refoactored TestMoveFilesAcl test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/common.go | 10 +++++ test/export_windows_test.go | 73 +++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/test/common.go b/test/common.go index 2dc1b03c..e9fa53b5 100644 --- a/test/common.go +++ b/test/common.go @@ -259,3 +259,13 @@ func absOrFatal(path string, t *testing.T) string { } return abs } + +// assertDirExistsOrFatal asserts that the given path is a directory or exits +// with t.Fatal in case of error. +func assertDirExistsOrFatal(dir string, t *testing.T) { + if stats, err := os.Stat(dir); err != nil { + t.Fatalf("Unable to get stats of %q", dir) + } else if !stats.IsDir() { + t.Fatalf("Created path %q is not a directory", dir) + } +} diff --git a/test/export_windows_test.go b/test/export_windows_test.go index 1f9e9539..3350be00 100644 --- a/test/export_windows_test.go +++ b/test/export_windows_test.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/Bedrock-OSS/regolith/regolith" - "github.com/otiai10/copy" "golang.org/x/sys/windows" ) @@ -24,21 +23,23 @@ func TestMoveFilesAcl(t *testing.T) { if os.Getenv("CI") != "" { t.Skip("Skipping test on local machine") } + // TEST PREPARATION // Switching working directories in this test, make sure to go back - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) + originalWd := getWdOrFatal(t) + defer os.Chdir(originalWd) + // Find path to com.mojang + t.Log("Finding the path to com.mojang...") mojangDir, err := regolith.FindMojangDir() if err != nil { t.Fatal(err.Error()) } - // The project will be tested from C:/regolithtestProject (or whatever + + // The project will be tested from C:/regolithTestProject (or whatever // drive you use for Minecraft) Don't change that to ioutil.TmpDir. // Current implementation assures that the working dir will be on the // same drive as Minecraft which is crucial for this test. + t.Log("Preparing the working directory in C:/regolithTestProject...") sep := string(filepath.Separator) workingDir := filepath.Join( // https://github.com/golang/go/issues/26953 @@ -47,24 +48,22 @@ func TestMoveFilesAcl(t *testing.T) { if _, err := os.Stat(workingDir); err == nil { // The path SHOULDN'T exist t.Fatalf("Clear path %q before testing", workingDir) } - // Copy the test project to the working directory - err = copy.Copy( - minimalProjectPath, - workingDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files %q into the working directory %q", - minimalProjectPath, workingDir, - ) - } - // Before "workingDir" the working dir of this test can't be there + + t.Log("Copying the project files into the testing directory...") + copyFilesOrFatal(minimalProjectPath, workingDir, t) + + // Change to the original working directory before defered RemoveAll + // because otherwise RemoveAll will fail (beacuse of the path being + // used) defer os.RemoveAll(workingDir) - defer os.Chdir(wd) - // Switch wd to workingDir + defer os.Chdir(originalWd) + + // Switch to workingDir os.Chdir(workingDir) - // Get the name of the config from config + + // LOAD DATA FROM CONFIG + // Get the name of the project from config + t.Log("Loading the data from config, befor running the test...") configJson, err := regolith.LoadConfigAsMap() if err != nil { t.Fatal(err.Error()) @@ -73,32 +72,23 @@ func TestMoveFilesAcl(t *testing.T) { if err != nil { t.Fatal(err.Error()) } + bpPath := filepath.Join(mojangDir, "development_behavior_packs", config.Name+"_bp") + rpPath := filepath.Join(mojangDir, "development_resource_packs", config.Name+"_rp") - bpPath := filepath.Join( - mojangDir, "development_behavior_packs", config.Name+"_bp") - rpPath := filepath.Join( - mojangDir, "development_resource_packs", config.Name+"_rp") - os.Chdir(workingDir) // THE TEST + t.Log("Testing the 'regolith run' command...") err = regolith.Run("dev", true) if err != nil { t.Fatal("'regolith run' failed:", err) } - // Test if the RP and BP were created in the right paths - assertDirExists := func(dir string) { - if stats, err := os.Stat(dir); err != nil { - t.Fatalf("Unable to get stats of %q", dir) - } else if !stats.IsDir() { - t.Fatalf("Created path %q is not a directory", dir) - } - } - assertDirExists(rpPath) + + t.Log("Checking if the RP and BP have been exported...") + assertDirExistsOrFatal(rpPath, t) defer os.RemoveAll(rpPath) - assertDirExists(bpPath) + assertDirExistsOrFatal(bpPath, t) defer os.RemoveAll(bpPath) - // Compare the permissions of the mojang path with the permissions of RP - // and BP + t.Log("Checking if the permissions of the exported packs are correct...") // getSecurityString gets the string representation of the path security // info of the path getSecurityString := func(path string) string { @@ -115,6 +105,8 @@ func TestMoveFilesAcl(t *testing.T) { // dacl, defaulted, err := securityInfo.DACL() return securityInfo.String() } + + t.Log("Getting the security settings of the com.mojang directory...") mojangAcl := getSecurityString(mojangDir) assertValidAcl := func(dir string) { if acl := getSecurityString(dir); acl != mojangAcl { @@ -124,6 +116,7 @@ func TestMoveFilesAcl(t *testing.T) { dir, acl, mojangDir, mojangAcl) } } + t.Log("Comparing the security settings of com.mojang with the exported packs...") assertValidAcl(rpPath) assertValidAcl(bpPath) } From c2ed6c567c151e3e23799b14d2743873c5dafce5 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 20:21:02 +0100 Subject: [PATCH 22/45] Refoactored TestConditionalFilter test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/conditional_filters_test.go | 70 ++++++++------------------------ 1 file changed, 18 insertions(+), 52 deletions(-) diff --git a/test/conditional_filters_test.go b/test/conditional_filters_test.go index 5674f4ab..be200899 100644 --- a/test/conditional_filters_test.go +++ b/test/conditional_filters_test.go @@ -6,65 +6,31 @@ import ( "testing" "github.com/Bedrock-OSS/regolith/regolith" - "github.com/otiai10/copy" ) // TestConditionalFilter runs a test that checks whether the 'when' property // of a filter properly locks/enables the execution of the filter. func TestConditionalFilter(t *testing.T) { - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) - // Copy the test project to the working directory - project, err := filepath.Abs(filepath.Join(conditionalFilterPath, "project")) - if err != nil { - t.Fatal( - "Unable to get absolute path to the test project:", err) - } - expectedBuildResult, err := filepath.Abs( - filepath.Join(conditionalFilterPath, "expected_build_result")) - if err != nil { - t.Fatal( - "Unable to get absolute path to the expected build result:", err) - } - err = copy.Copy( - project, - tmpDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files from %q into the working directory %q", - project, tmpDir, - ) - } - // THE TEST + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestConditionalFilter", t) + + t.Log("Copying the project files into the testing directory...") + project := absOrFatal(filepath.Join(conditionalFilterPath, "project"), t) + copyFilesOrFatal(project, tmpDir, t) + + // Load abs path of the expected result and switch to the working directory + expectedBuildResult := absOrFatal( + filepath.Join(conditionalFilterPath, "expected_build_result"), t) os.Chdir(tmpDir) + + // THE TEST + t.Log("Running Regolith with a conditional filter...") if err := regolith.Run("default", true); err != nil { t.Fatal("'regolith run' failed:", err.Error()) } - // Load expected result - expectedPaths, err := getPathHashes(expectedBuildResult) - if err != nil { - t.Fatalf("Failed to load the expected results: %s", err) - } - // Load actual result - tmpDirBuild := filepath.Join(tmpDir, "build") - actualPaths, err := getPathHashes(tmpDirBuild) - if err != nil { - t.Fatalf("Failed to load the actual results: %s", err) - } - // Compare the results - comparePathMaps(expectedPaths, actualPaths, t) + + // TEST EVALUATION + t.Log("Evaluating the test results...") + comparePaths(expectedBuildResult, filepath.Join(tmpDir, "build"), t) } From d7ad4d5f8ac8d4c9f7353f13b38cb9e2dc8eab7b Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 20:27:46 +0100 Subject: [PATCH 23/45] Refoactored TestApplyFilter test: The test files are created inside the project in a .gitignored directory, which makes inspecting generated files easier. Simplified the code. --- test/apply_filter_test.go | 68 ++++++++++----------------------------- 1 file changed, 17 insertions(+), 51 deletions(-) diff --git a/test/apply_filter_test.go b/test/apply_filter_test.go index f1ea0b67..c5bafc56 100644 --- a/test/apply_filter_test.go +++ b/test/apply_filter_test.go @@ -6,63 +6,29 @@ import ( "testing" "github.com/Bedrock-OSS/regolith/regolith" - "github.com/otiai10/copy" ) // TestApplyFilter tests the 'regolith apply-filter' command func TestApplyFilter(t *testing.T) { - wd, err := os.Getwd() - if err != nil { - t.Fatal("Unable to get current working directory") - } - defer os.Chdir(wd) - // Create a temporary directory - tmpDir, err := os.MkdirTemp("", "regolith-test") - if err != nil { - t.Fatal("Unable to create temporary directory:", err) - } - t.Log("Created temporary directory:", tmpDir) - // Before deleting "workingDir" the test must stop using it - defer os.RemoveAll(tmpDir) - defer os.Chdir(wd) - // Copy the test project to the working directory - project, err := filepath.Abs(filepath.Join(applyFilterPath, "project")) - if err != nil { - t.Fatal( - "Unable to get absolute path to the test project:", err) - } - expectedResult, err := filepath.Abs( - filepath.Join(applyFilterPath, "filtered_project")) - if err != nil { - t.Fatal( - "Unable to get absolute path to the expected build result:", err) - } - err = copy.Copy( - project, - tmpDir, - copy.Options{PreserveTimes: false, Sync: false}, - ) - if err != nil { - t.Fatalf( - "Failed to copy test files from %q into the working directory %q", - project, tmpDir, - ) - } - // THE TEST + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestApplyFilter", t) + + t.Log("Copying the project files into the testing directory...") + project := absOrFatal(filepath.Join(applyFilterPath, "project"), t) + copyFilesOrFatal(project, tmpDir, t) + + // Load abs path of the expected result and switch to the working directory + expectedResult := absOrFatal( + filepath.Join(applyFilterPath, "filtered_project"), t) os.Chdir(tmpDir) + + // THE TEST + t.Log("Running 'rego apply-filter'...") if err := regolith.ApplyFilter("test_filter", []string{"Regolith"}, true); err != nil { t.Fatal("'regolith apply-filter' failed:", err.Error()) } - // Load expected result - expectedPaths, err := getPathHashes(expectedResult) - if err != nil { - t.Fatalf("Failed to load the expected results: %s", err) - } - // Load actual result - actualPaths, err := getPathHashes(tmpDir) - if err != nil { - t.Fatalf("Failed to load the actual results: %s", err) - } - // Compare the results - comparePathMaps(expectedPaths, actualPaths, t) + // TEST EVALUATION + t.Log("Evaluating the test results...") + comparePaths(expectedResult, tmpDir, t) } From c613c9e405df869326168995edff44d192eb5c38 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 21:02:08 +0100 Subject: [PATCH 24/45] All tests switch back to their original working directory when they finish to avoid breaking other tests. --- test/apply_filter_test.go | 3 +++ test/conditional_filters_test.go | 3 +++ test/export_windows_test.go | 8 +++++++- test/file_protection_test.go | 4 ++++ test/local_filters_test.go | 10 ++++++++++ test/remote_filters_test.go | 8 ++++++++ 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/test/apply_filter_test.go b/test/apply_filter_test.go index c5bafc56..59c45fb3 100644 --- a/test/apply_filter_test.go +++ b/test/apply_filter_test.go @@ -10,6 +10,9 @@ import ( // TestApplyFilter tests the 'regolith apply-filter' command func TestApplyFilter(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) + // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestApplyFilter", t) diff --git a/test/conditional_filters_test.go b/test/conditional_filters_test.go index be200899..b597d888 100644 --- a/test/conditional_filters_test.go +++ b/test/conditional_filters_test.go @@ -11,6 +11,9 @@ import ( // TestConditionalFilter runs a test that checks whether the 'when' property // of a filter properly locks/enables the execution of the filter. func TestConditionalFilter(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) + // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestConditionalFilter", t) diff --git a/test/export_windows_test.go b/test/export_windows_test.go index 3350be00..d8238036 100644 --- a/test/export_windows_test.go +++ b/test/export_windows_test.go @@ -23,6 +23,9 @@ func TestMoveFilesAcl(t *testing.T) { if os.Getenv("CI") != "" { t.Skip("Skipping test on local machine") } + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) + // TEST PREPARATION // Switching working directories in this test, make sure to go back originalWd := getWdOrFatal(t) @@ -46,7 +49,10 @@ func TestMoveFilesAcl(t *testing.T) { strings.Split(mojangDir, sep)[0]+sep, "regolithTestProject") if _, err := os.Stat(workingDir); err == nil { // The path SHOULDN'T exist - t.Fatalf("Clear path %q before testing", workingDir) + t.Fatalf( + "Clear path for this test manually before testing.\n"+ + "Path: %s", + workingDir) } t.Log("Copying the project files into the testing directory...") diff --git a/test/file_protection_test.go b/test/file_protection_test.go index 24bf25db..ad82e247 100644 --- a/test/file_protection_test.go +++ b/test/file_protection_test.go @@ -17,6 +17,8 @@ import ( // This test only checks if the regolith run command runs successfuly. It // doesn't check if the files are exported correctly. func TestSwitchingExportTargets(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestSwitchingExportTargets", t) @@ -59,6 +61,8 @@ func TestSwitchingExportTargets(t *testing.T) { // This test only checks if the regolith run command runs successfuly. It // doesn't check if the files are exported correctly. func TestTriggerFileProtection(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestTriggerFileProtection", t) diff --git a/test/local_filters_test.go b/test/local_filters_test.go index 2a237a71..d07bac8e 100644 --- a/test/local_filters_test.go +++ b/test/local_filters_test.go @@ -11,6 +11,8 @@ import ( // TestRegolithInit tests the results of InitializeRegolithProject against // the values from test/testdata/fresh_project. func TestRegolithInit(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestRegolithInit", t) @@ -31,6 +33,8 @@ func TestRegolithInit(t *testing.T) { // directory is missing. The test just checks if the command runs without // errors. func TestRegolithRunMissingRp(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATOIN t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestRegolithRunMissingRp", t) @@ -50,6 +54,8 @@ func TestRegolithRunMissingRp(t *testing.T) { // project that uses local script with requirements.txt by running // "regolith install" first and then "regolith run" on that project. func TestLocalRequirementsInstallAndRun(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestLocalRequirementsInstallAndRun", t) @@ -72,6 +78,8 @@ func TestLocalRequirementsInstallAndRun(t *testing.T) { // TextExeFilterRun tests if Regolith can properly run an Exe filter func TestExeFilterRun(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestExeFilterRun", t) @@ -99,6 +107,8 @@ func TestExeFilterRun(t *testing.T) { // profile filter has circular dependencies and should fail, the valid profile // filter runs the same exe file as the TestExeFilterRun test. func TestProfileFilterRun(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestProfileFilterRun", t) diff --git a/test/remote_filters_test.go b/test/remote_filters_test.go index 3fe8469c..ea677b8d 100644 --- a/test/remote_filters_test.go +++ b/test/remote_filters_test.go @@ -15,6 +15,8 @@ import ( // results of running the filter are compared to a project with an expected // result. func TestInstallAllAndRun(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestInstallAllAndRun", t) @@ -50,6 +52,8 @@ func TestInstallAllAndRun(t *testing.T) { // property, which means that the 'data' folder that it modifies should be // copied back to the source files. func TestDataModifyRemoteFilter(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestDataModifyRemoteFilter", t) @@ -86,6 +90,8 @@ func TestDataModifyRemoteFilter(t *testing.T) { // a filter with various versions and compares the outputs with the expected // results. func TestInstall(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestInstall", t) @@ -138,6 +144,8 @@ func TestInstall(t *testing.T) { // command. It switches versions of a filter in the config.json file, runs // 'regolith install-all', and compares the outputs with the expected results. func TestInstallAll(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) // TEST PREPARATION t.Log("Clearing the testing directory...") tmpDir := prepareTestDirectory("TestInstallAll", t) From b4335d460637fa3faa450f43806f953f2305138e Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 21:43:52 +0100 Subject: [PATCH 25/45] Fixed a typo, that in some cases prevented RP from being exported. --- regolith/export.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regolith/export.go b/regolith/export.go index 2348d0f9..e688b0a9 100644 --- a/regolith/export.go +++ b/regolith/export.go @@ -35,7 +35,7 @@ func GetExportPaths( return GetWorldExportPaths(exportTarget, bpName, rpName) } else if exportTarget.Target == "local" { bpPath = "build/" + bpName + "/" - rpPath = "build/" + bpName + "/" + rpPath = "build/" + rpName + "/" } else if exportTarget.Target == "none" { bpPath = "" rpPath = "" From 4d2ed81f1a48f1e9cf3c32bc9b51f9890601d174 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 22:05:33 +0100 Subject: [PATCH 26/45] Adjusted the testing files of TestInstallAllAndRun to match the new behavior of the new local export: Before this update the files were exported into build/RP and build/BP by default but it was inconsistent with other export target behaviors. Now regolith exports into build/_rp and build/_bp. --- .../.regolith/cache/edited_files.json | 4 ++-- .../build/{BP => regolith_test_project_bp}/hello_version.txt | 0 .../build/{BP => regolith_test_project_bp}/manifest.json | 0 .../build/{RP => regolith_test_project_rp}/manifest.json | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename test/testdata/versioned_remote_filter_project_after_run/build/{BP => regolith_test_project_bp}/hello_version.txt (100%) rename test/testdata/versioned_remote_filter_project_after_run/build/{BP => regolith_test_project_bp}/manifest.json (100%) rename test/testdata/versioned_remote_filter_project_after_run/build/{RP => regolith_test_project_rp}/manifest.json (100%) diff --git a/test/testdata/versioned_remote_filter_project_after_run/.regolith/cache/edited_files.json b/test/testdata/versioned_remote_filter_project_after_run/.regolith/cache/edited_files.json index a21b2719..efcc62ff 100644 --- a/test/testdata/versioned_remote_filter_project_after_run/.regolith/cache/edited_files.json +++ b/test/testdata/versioned_remote_filter_project_after_run/.regolith/cache/edited_files.json @@ -1,11 +1,11 @@ { "rp": { - "build/RP/": [ + "build/regolith_test_project_rp/": [ "manifest.json" ] }, "bp": { - "build/BP/": [ + "build/regolith_test_project_bp/": [ "hello_version.txt", "manifest.json" ] diff --git a/test/testdata/versioned_remote_filter_project_after_run/build/BP/hello_version.txt b/test/testdata/versioned_remote_filter_project_after_run/build/regolith_test_project_bp/hello_version.txt similarity index 100% rename from test/testdata/versioned_remote_filter_project_after_run/build/BP/hello_version.txt rename to test/testdata/versioned_remote_filter_project_after_run/build/regolith_test_project_bp/hello_version.txt diff --git a/test/testdata/versioned_remote_filter_project_after_run/build/BP/manifest.json b/test/testdata/versioned_remote_filter_project_after_run/build/regolith_test_project_bp/manifest.json similarity index 100% rename from test/testdata/versioned_remote_filter_project_after_run/build/BP/manifest.json rename to test/testdata/versioned_remote_filter_project_after_run/build/regolith_test_project_bp/manifest.json diff --git a/test/testdata/versioned_remote_filter_project_after_run/build/RP/manifest.json b/test/testdata/versioned_remote_filter_project_after_run/build/regolith_test_project_rp/manifest.json similarity index 100% rename from test/testdata/versioned_remote_filter_project_after_run/build/RP/manifest.json rename to test/testdata/versioned_remote_filter_project_after_run/build/regolith_test_project_rp/manifest.json From c9c658a021124626c41636029e4cbd53c1d7a30b Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 22:14:44 +0100 Subject: [PATCH 27/45] Adjusted the testing files of TestDataModifyRemoteFilter to match the new behavior of the new local export. --- .../after_run/.regolith/cache/edited_files.json | 4 ++-- .../after_run/build/{BP => Project name_bp}/.ignoreme | 0 .../after_run/build/{RP => Project name_rp}/.ignoreme | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename test/testdata/data_modify_remote_filter/after_run/build/{BP => Project name_bp}/.ignoreme (100%) rename test/testdata/data_modify_remote_filter/after_run/build/{RP => Project name_rp}/.ignoreme (100%) diff --git a/test/testdata/data_modify_remote_filter/after_run/.regolith/cache/edited_files.json b/test/testdata/data_modify_remote_filter/after_run/.regolith/cache/edited_files.json index adb9ebfd..bca28767 100644 --- a/test/testdata/data_modify_remote_filter/after_run/.regolith/cache/edited_files.json +++ b/test/testdata/data_modify_remote_filter/after_run/.regolith/cache/edited_files.json @@ -1,11 +1,11 @@ { "rp": { - "build/RP/": [ + "build/Project name_rp/": [ ".ignoreme" ] }, "bp": { - "build/BP/": [ + "build/Project name_bp/": [ ".ignoreme" ] } diff --git a/test/testdata/data_modify_remote_filter/after_run/build/BP/.ignoreme b/test/testdata/data_modify_remote_filter/after_run/build/Project name_bp/.ignoreme similarity index 100% rename from test/testdata/data_modify_remote_filter/after_run/build/BP/.ignoreme rename to test/testdata/data_modify_remote_filter/after_run/build/Project name_bp/.ignoreme diff --git a/test/testdata/data_modify_remote_filter/after_run/build/RP/.ignoreme b/test/testdata/data_modify_remote_filter/after_run/build/Project name_rp/.ignoreme similarity index 100% rename from test/testdata/data_modify_remote_filter/after_run/build/RP/.ignoreme rename to test/testdata/data_modify_remote_filter/after_run/build/Project name_rp/.ignoreme From a631c330a8010b7de0b6c42b98ff20ac5ea73207 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 22:14:44 +0100 Subject: [PATCH 28/45] Adjusted the testing files of TestProfileFilterRun to match the new behavior of the new local export. --- test/local_filters_test.go | 2 +- .../after_run/.regolith/cache/edited_files.json | 4 ++-- .../after_run/build/{BP => Project name_bp}/.ignoreme | 0 .../after_run/build/{RP => Project name_rp}/.ignoreme | 0 .../{BP => nested_filter_test_project_bp}/.ignoreme | 0 .../{BP => nested_filter_test_project_bp}/hello.txt | 0 .../{RP => nested_filter_test_project_rp}/.ignoreme | 0 7 files changed, 3 insertions(+), 3 deletions(-) rename test/testdata/data_modify_remote_filter/after_run/build/{BP => Project name_bp}/.ignoreme (100%) rename test/testdata/data_modify_remote_filter/after_run/build/{RP => Project name_rp}/.ignoreme (100%) rename test/testdata/profile_filter/expected_build_result/{BP => nested_filter_test_project_bp}/.ignoreme (100%) rename test/testdata/profile_filter/expected_build_result/{BP => nested_filter_test_project_bp}/hello.txt (100%) rename test/testdata/profile_filter/expected_build_result/{RP => nested_filter_test_project_rp}/.ignoreme (100%) diff --git a/test/local_filters_test.go b/test/local_filters_test.go index d07bac8e..8be38f22 100644 --- a/test/local_filters_test.go +++ b/test/local_filters_test.go @@ -119,7 +119,7 @@ func TestProfileFilterRun(t *testing.T) { // Load abs path of the expected result and switch to the working directory expectedBuildResult := absOrFatal( - filepath.Join(exeFilterPath, "expected_build_result"), t) + filepath.Join(profileFilterPath, "expected_build_result"), t) os.Chdir(tmpDir) // THE TEST diff --git a/test/testdata/data_modify_remote_filter/after_run/.regolith/cache/edited_files.json b/test/testdata/data_modify_remote_filter/after_run/.regolith/cache/edited_files.json index adb9ebfd..bca28767 100644 --- a/test/testdata/data_modify_remote_filter/after_run/.regolith/cache/edited_files.json +++ b/test/testdata/data_modify_remote_filter/after_run/.regolith/cache/edited_files.json @@ -1,11 +1,11 @@ { "rp": { - "build/RP/": [ + "build/Project name_rp/": [ ".ignoreme" ] }, "bp": { - "build/BP/": [ + "build/Project name_bp/": [ ".ignoreme" ] } diff --git a/test/testdata/data_modify_remote_filter/after_run/build/BP/.ignoreme b/test/testdata/data_modify_remote_filter/after_run/build/Project name_bp/.ignoreme similarity index 100% rename from test/testdata/data_modify_remote_filter/after_run/build/BP/.ignoreme rename to test/testdata/data_modify_remote_filter/after_run/build/Project name_bp/.ignoreme diff --git a/test/testdata/data_modify_remote_filter/after_run/build/RP/.ignoreme b/test/testdata/data_modify_remote_filter/after_run/build/Project name_rp/.ignoreme similarity index 100% rename from test/testdata/data_modify_remote_filter/after_run/build/RP/.ignoreme rename to test/testdata/data_modify_remote_filter/after_run/build/Project name_rp/.ignoreme diff --git a/test/testdata/profile_filter/expected_build_result/BP/.ignoreme b/test/testdata/profile_filter/expected_build_result/nested_filter_test_project_bp/.ignoreme similarity index 100% rename from test/testdata/profile_filter/expected_build_result/BP/.ignoreme rename to test/testdata/profile_filter/expected_build_result/nested_filter_test_project_bp/.ignoreme diff --git a/test/testdata/profile_filter/expected_build_result/BP/hello.txt b/test/testdata/profile_filter/expected_build_result/nested_filter_test_project_bp/hello.txt similarity index 100% rename from test/testdata/profile_filter/expected_build_result/BP/hello.txt rename to test/testdata/profile_filter/expected_build_result/nested_filter_test_project_bp/hello.txt diff --git a/test/testdata/profile_filter/expected_build_result/RP/.ignoreme b/test/testdata/profile_filter/expected_build_result/nested_filter_test_project_rp/.ignoreme similarity index 100% rename from test/testdata/profile_filter/expected_build_result/RP/.ignoreme rename to test/testdata/profile_filter/expected_build_result/nested_filter_test_project_rp/.ignoreme From ad81ac723df1d1063ca9c7d90d2888c20259c03b Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 22:42:52 +0100 Subject: [PATCH 29/45] Adjusted the testing files of TestExeFilterRun to match the new behavior of the new local export. --- .../{BP => exe_filter_test_project_bp}/.ignoreme | 0 .../{BP => exe_filter_test_project_bp}/hello.txt | 0 .../{RP => exe_filter_test_project_rp}/.ignoreme | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/testdata/exe_filter/expected_build_result/{BP => exe_filter_test_project_bp}/.ignoreme (100%) rename test/testdata/exe_filter/expected_build_result/{BP => exe_filter_test_project_bp}/hello.txt (100%) rename test/testdata/exe_filter/expected_build_result/{RP => exe_filter_test_project_rp}/.ignoreme (100%) diff --git a/test/testdata/exe_filter/expected_build_result/BP/.ignoreme b/test/testdata/exe_filter/expected_build_result/exe_filter_test_project_bp/.ignoreme similarity index 100% rename from test/testdata/exe_filter/expected_build_result/BP/.ignoreme rename to test/testdata/exe_filter/expected_build_result/exe_filter_test_project_bp/.ignoreme diff --git a/test/testdata/exe_filter/expected_build_result/BP/hello.txt b/test/testdata/exe_filter/expected_build_result/exe_filter_test_project_bp/hello.txt similarity index 100% rename from test/testdata/exe_filter/expected_build_result/BP/hello.txt rename to test/testdata/exe_filter/expected_build_result/exe_filter_test_project_bp/hello.txt diff --git a/test/testdata/exe_filter/expected_build_result/RP/.ignoreme b/test/testdata/exe_filter/expected_build_result/exe_filter_test_project_rp/.ignoreme similarity index 100% rename from test/testdata/exe_filter/expected_build_result/RP/.ignoreme rename to test/testdata/exe_filter/expected_build_result/exe_filter_test_project_rp/.ignoreme From a174976d9caadde7c005d9c531e77b822c0d126c Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 4 Nov 2023 22:48:56 +0100 Subject: [PATCH 30/45] Adjusted the testing files of TestConditionalFilter to match the new behavior of the new local export. --- .../{BP => regolith_test_project_bp}/manifest.json | 0 .../{BP => regolith_test_project_bp}/out.txt | 0 .../{RP => regolith_test_project_rp}/manifest.json | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/testdata/conditional_filter/expected_build_result/{BP => regolith_test_project_bp}/manifest.json (100%) rename test/testdata/conditional_filter/expected_build_result/{BP => regolith_test_project_bp}/out.txt (100%) rename test/testdata/conditional_filter/expected_build_result/{RP => regolith_test_project_rp}/manifest.json (100%) diff --git a/test/testdata/conditional_filter/expected_build_result/BP/manifest.json b/test/testdata/conditional_filter/expected_build_result/regolith_test_project_bp/manifest.json similarity index 100% rename from test/testdata/conditional_filter/expected_build_result/BP/manifest.json rename to test/testdata/conditional_filter/expected_build_result/regolith_test_project_bp/manifest.json diff --git a/test/testdata/conditional_filter/expected_build_result/BP/out.txt b/test/testdata/conditional_filter/expected_build_result/regolith_test_project_bp/out.txt similarity index 100% rename from test/testdata/conditional_filter/expected_build_result/BP/out.txt rename to test/testdata/conditional_filter/expected_build_result/regolith_test_project_bp/out.txt diff --git a/test/testdata/conditional_filter/expected_build_result/RP/manifest.json b/test/testdata/conditional_filter/expected_build_result/regolith_test_project_rp/manifest.json similarity index 100% rename from test/testdata/conditional_filter/expected_build_result/RP/manifest.json rename to test/testdata/conditional_filter/expected_build_result/regolith_test_project_rp/manifest.json From 8bd72797f3266157609e9a20b97fc05ae0edac52 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sun, 5 Nov 2023 12:41:33 +0100 Subject: [PATCH 31/45] Small update to the SyncDirectories() function. --- regolith/file_system.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/regolith/file_system.go b/regolith/file_system.go index 856debea..fb518d52 100644 --- a/regolith/file_system.go +++ b/regolith/file_system.go @@ -880,12 +880,8 @@ func SyncDirectories( ) error { // Make destination parent if not exists destinationParent := filepath.Dir(destination) - if _, err := os.Stat(destinationParent); os.IsNotExist(err) { - err = os.MkdirAll(destinationParent, 0755) - if err != nil { - return burrito.WrapErrorf( - err, osMkdirError, destinationParent) - } + if err := os.MkdirAll(destinationParent, 0755); err != nil { + return burrito.WrapErrorf(err, osMkdirError, destinationParent) } err := filepath.Walk(source, func(srcPath string, info os.FileInfo, err error) error { if err != nil { From 37f31120f96aa5523130404f8c300b664e7a1a87 Mon Sep 17 00:00:00 2001 From: Lauren Hinchcliffe Date: Fri, 10 Nov 2023 16:25:52 -0800 Subject: [PATCH 32/45] Add env variable com.mojang support for non-Windows OS --- regolith/compatibility_other_os.go | 17 ++++++++++++++--- regolith/errors.go | 6 ++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/regolith/compatibility_other_os.go b/regolith/compatibility_other_os.go index 2504a884..7fd9d3da 100644 --- a/regolith/compatibility_other_os.go +++ b/regolith/compatibility_other_os.go @@ -3,7 +3,10 @@ package regolith -import "github.com/Bedrock-OSS/go-burrito/burrito" +import ( + "os" + "github.com/Bedrock-OSS/go-burrito/burrito" +) // pythonExeNames is the list of strings with possible names of the Python // executable. The order of the names determines the order in which they are @@ -48,11 +51,19 @@ func (d *DirWatcher) Close() error { } func FindMojangDir() (string, error) { - return "", burrito.WrappedError(notImplementedOnThisSystemError) + comMojang := os.Getenv("COM_MOJANG") + if comMojang == "" { + return "", burrito.WrappedError(comMojangEnvUnsetError) + } + return comMojang, nil } func FindPreviewDir() (string, error) { - return "", burrito.WrappedError(notImplementedOnThisSystemError) + comMojangPreview := os.Getenv("COM_MOJANG_PREVIEW") + if comMojangPreview == "" { + return "", burrito.WrappedError(comMojangPreviewEnvUnsetError) + } + return comMojangPreview, nil } func CheckSuspiciousLocation() error { diff --git a/regolith/errors.go b/regolith/errors.go index d0a07e8d..6f954b5a 100644 --- a/regolith/errors.go +++ b/regolith/errors.go @@ -143,6 +143,12 @@ const ( // Error used when certain function is not implemented on this system notImplementedOnThisSystemError = "Not implemented for this system." + // Error used when env variable COM_MOJANG is not set on non Windows system + comMojangEnvUnsetError = "COM_MOJANG environment variable is not set." + + // Error used when env variable COM_MOJANG_PREVIEW is not set on non Windows system + comMojangPreviewEnvUnsetError = "COM_MOJANG_PREVIEW environment variable is not set." + // Error used when SetupTmpFiles function fails setupTmpFilesError = "Failed to setup temporary files.\n" + "Regolith files path: %s" // .regolith From 03dd528cee2e8c0ff15e3543aa7a809854d847e8 Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 11 Nov 2023 20:11:11 +0100 Subject: [PATCH 33/45] Added list of available flags to the --experimetns flag. --- main.go | 13 ++++++++++++- regolith/experiments.go | 20 +++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index eed6a0df..254ed3f0 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os" + "strings" "github.com/Bedrock-OSS/go-burrito/burrito" "github.com/stirante/go-simple-eval/eval" @@ -358,12 +359,22 @@ func main() { } subcommands = append(subcommands, cmdUpdateResolvers) + // Generate the description for the experiments + experimentDescs := make([]string, len(regolith.AvailableExperiments)) + for i, experiment := range regolith.AvailableExperiments { + experimentDescs[i] = "- " + experiment.Name + " - " + strings.Trim(experiment.Description, "\n") + } + // add --debug, --timings and --experiment flag to every command for _, cmd := range subcommands { cmd.Flags().BoolVarP(&burrito.PrintStackTrace, "debug", "", false, "Enables debugging") cmd.Flags().BoolVarP(®olith.EnableTimings, "timings", "", false, "Enables timing information") - cmd.Flags().StringSliceVar(®olith.EnabledExperiments, "experiments", nil, "Enables experimental features") + cmd.Flags().StringSliceVar( + ®olith.EnabledExperiments, "experiments", nil, + "Enables experimental features. Currently supported experiments:\n"+ + strings.Join(experimentDescs, "\n")) } + // Build and run CLI rootCmd.AddCommand(subcommands...) rootCmd.Execute() diff --git a/regolith/experiments.go b/regolith/experiments.go index d151759d..5384ff84 100644 --- a/regolith/experiments.go +++ b/regolith/experiments.go @@ -7,8 +7,22 @@ const ( SizeTimeCheck Experiment = iota ) -var experimentNames = map[Experiment]string{ - SizeTimeCheck: "size_time_check", +// The descriptions shouldn't be too wide, the text with their description is +// indented a lot. +const sizeTimeCheckDesc = ` +Activates optimization for file exporting by checking the size and +modification time of files before exporting, and only exporting if +the file has changed. This experiment applies to 'run' and 'watch' +commands. +` + +type ExperimentInfo struct { + Name string + Description string +} + +var AvailableExperiments = map[Experiment]ExperimentInfo{ + SizeTimeCheck: {"size_time_check", sizeTimeCheckDesc}, } var EnabledExperiments []string @@ -18,7 +32,7 @@ func IsExperimentEnabled(exp Experiment) bool { return false } for _, e := range EnabledExperiments { - if e == experimentNames[exp] { + if e == AvailableExperiments[exp].Name { return true } } From 86b64a219686062cf127473f8c29ca8a040b825c Mon Sep 17 00:00:00 2001 From: Nusiq Date: Sat, 11 Nov 2023 20:35:30 +0100 Subject: [PATCH 34/45] Documented the COM_MOJANG and COM_MOJANG_PREVIEW environment varialbes, used on non-Windows systems to simulate the Minecraft paths. --- docs/docs/guide/export-targets.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/docs/guide/export-targets.md b/docs/docs/guide/export-targets.md index 55fe2678..a2e0b7b1 100644 --- a/docs/docs/guide/export-targets.md +++ b/docs/docs/guide/export-targets.md @@ -16,6 +16,13 @@ Some configuration properties may be used with all export targets. `readOnly` changes the permissions of exported files to read-only. The default value is `false`. This property can be used to protect against accidental editing of files that should only be edited by Regolith! +## Additional Configuration for Non-Windows Users + +Some of the export targets listed below wouldn't make sense on systems other than Windows with Minecraft installed. They often rely on finding the `com.mojang` path first, and then placing the files in a path relative to that. This problem can be solved by setting environment variables that Regolith will use instead of the `com.mojang` path. + +- `COM_MOJANG_PREVIEW` - A fake path to the `com.mojang` folder in Minecraft preview releases. This is used by the `preview` export target. +- `COM_MOJANG` - A fake path to the `com.mojang` folder in regular Minecraft releases. + # Export Targets These are the export targets that Regolith offers. From 92ea648a0ea7b9c2c4eb23e2e6c11502043b961c Mon Sep 17 00:00:00 2001 From: stirante Date: Thu, 23 Nov 2023 10:42:34 +0100 Subject: [PATCH 35/45] Add documentation for `EvalCondition`, `EvalString` and `GetExportNames` --- regolith/evaluator.go | 3 +++ regolith/export.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/regolith/evaluator.go b/regolith/evaluator.go index 9034d691..b22c958c 100644 --- a/regolith/evaluator.go +++ b/regolith/evaluator.go @@ -8,6 +8,7 @@ import ( "github.com/stirante/go-simple-eval/eval/utils" ) +// EvalCondition evaluates a condition expression with the given context. func EvalCondition(expression string, ctx RunContext) (bool, error) { Logger.Debugf("Evaluating condition: %s", expression) t := prepareScope(ctx) @@ -20,6 +21,8 @@ func EvalCondition(expression string, ctx RunContext) (bool, error) { return utils.ToBoolean(e), nil } +// EvalString evaluates an expression with the given context and returns the +// result as a string. func EvalString(expression string, ctx RunContext) (string, error) { Logger.Debugf("Evaluating expression: %s", expression) t := prepareScope(ctx) diff --git a/regolith/export.go b/regolith/export.go index e688b0a9..36cdc5f8 100644 --- a/regolith/export.go +++ b/regolith/export.go @@ -113,6 +113,9 @@ func GetWorldExportPaths(exportTarget ExportTarget, bpName, rpName string) (bpPa return } +// GetExportNames returns the names for the behavior pack and resource pack +// based on the evaluated values of the "bpName" and "rpName" from the +// exportTarget object. func GetExportNames(exportTarget ExportTarget, ctx RunContext) (bpName string, rpName string, err error) { if exportTarget.BpName != "" { bpName, err = EvalString(exportTarget.BpName, ctx) From b84f6527676a9e2505c5f497903ae094661b98c2 Mon Sep 17 00:00:00 2001 From: stirante Date: Thu, 23 Nov 2023 12:26:35 +0100 Subject: [PATCH 36/45] Add SliceAny utility function and refine file removal process --- regolith/file_system.go | 22 +++++++++++++++++++--- regolith/utils.go | 9 +++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/regolith/file_system.go b/regolith/file_system.go index fb518d52..dcfa8ace 100644 --- a/regolith/file_system.go +++ b/regolith/file_system.go @@ -913,6 +913,7 @@ func SyncDirectories( } // Remove files/folders in destination that are not in source + toRemoveList := make([]string, 0) err = filepath.Walk(destination, func(destPath string, info os.FileInfo, err error) error { if err != nil { return err @@ -923,14 +924,29 @@ func SyncDirectories( } srcPath := filepath.Join(source, relPath) if _, err := os.Stat(srcPath); os.IsNotExist(err) { - Logger.Debugf("SYNC: Removing file %s", destPath) - return os.RemoveAll(destPath) + // TODO: Not sure if this is the best way to do this + // The toRemoveList might get pretty big + if !SliceAny[string](toRemoveList, func(s string) bool { + return strings.HasPrefix(destPath, s) + }) { + Logger.Debugf("SYNC: Removing file %s", destPath) + // Add to list of files to remove, because otherwise walk function might fail + // when trying to walk a directory that doesn't exist anymore + toRemoveList = append(toRemoveList, destPath) + } } return nil }) if err != nil { - return burrito.WrapErrorf(err, osRemoveError, source, destination) + return burrito.PassError(err) + } + + for _, path := range toRemoveList { + err = os.RemoveAll(path) + if err != nil { + return burrito.WrapErrorf(err, osRemoveError, path) + } } //TODO: copy ACL. To be honest, I have no clue why it was there in the first place diff --git a/regolith/utils.go b/regolith/utils.go index c07fc7fd..f8372247 100644 --- a/regolith/utils.go +++ b/regolith/utils.go @@ -430,3 +430,12 @@ func EscapePathPart(s string) string { } return sb.String() } + +func SliceAny[T interface{}](slice []T, predicate func(T) bool) bool { + for _, item := range slice { + if predicate(item) { + return true + } + } + return false +} From eeb54a5b39acf8d33db53ee4dc0bb2e733fa7bf5 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 11 Feb 2024 17:58:09 +0100 Subject: [PATCH 37/45] Updated the schema version used in config.json file to v1.2. --- regolith/main_functions.go | 2 +- test/testdata/apply_filter/filtered_project/config.json | 2 +- test/testdata/apply_filter/project/config.json | 2 +- test/testdata/conditional_filter/project/config.json | 2 +- test/testdata/data_modify_remote_filter/after_run/config.json | 2 +- test/testdata/data_modify_remote_filter/project/config.json | 2 +- test/testdata/double_remote_project/config.json | 2 +- test/testdata/double_remote_project_installed/config.json | 2 +- test/testdata/exe_filter/project/config.json | 2 +- test/testdata/fresh_project/config.json | 2 +- test/testdata/local_requirements/project/config.json | 2 +- test/testdata/minimal_project/config.json | 2 +- test/testdata/multitarget_project/config.json | 2 +- test/testdata/profile_filter/project/config.json | 2 +- test/testdata/regolith_install/1.0.0/config.json | 2 +- test/testdata/regolith_install/1.0.1/config.json | 2 +- test/testdata/regolith_install/HEAD/config.json | 2 +- test/testdata/regolith_install/latest/config.json | 2 +- test/testdata/regolith_install/sha/config.json | 2 +- test/testdata/regolith_install/tag/config.json | 2 +- test/testdata/regolith_update/1.0.0/config.json | 2 +- test/testdata/regolith_update/1.0.1/config.json | 2 +- test/testdata/regolith_update/HEAD/config.json | 2 +- test/testdata/regolith_update/fresh_project/config.json | 2 +- test/testdata/regolith_update/latest/config.json | 2 +- test/testdata/regolith_update/sha/config.json | 2 +- test/testdata/regolith_update/tag/config.json | 2 +- test/testdata/run_missing_rp_project/config.json | 2 +- test/testdata/versioned_remote_filter_project/config.json | 2 +- .../versioned_remote_filter_project_after_run/config.json | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/regolith/main_functions.go b/regolith/main_functions.go index 1a22e31d..10922899 100644 --- a/regolith/main_functions.go +++ b/regolith/main_functions.go @@ -452,7 +452,7 @@ func Init(debug, force bool) error { // Add the schema property, this is a little hacky rawJsonData := make(map[string]interface{}, 0) json.Unmarshal(jsonBytes, &rawJsonData) - rawJsonData["$schema"] = "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json" + rawJsonData["$schema"] = "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json" jsonBytes, _ = json.MarshalIndent(rawJsonData, "", "\t") err = os.WriteFile(ConfigFilePath, jsonBytes, 0644) diff --git a/test/testdata/apply_filter/filtered_project/config.json b/test/testdata/apply_filter/filtered_project/config.json index ad8fa269..4444ec8b 100644 --- a/test/testdata/apply_filter/filtered_project/config.json +++ b/test/testdata/apply_filter/filtered_project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/apply_filter/project/config.json b/test/testdata/apply_filter/project/config.json index ad8fa269..4444ec8b 100644 --- a/test/testdata/apply_filter/project/config.json +++ b/test/testdata/apply_filter/project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/conditional_filter/project/config.json b/test/testdata/conditional_filter/project/config.json index 02fbd594..6a915909 100644 --- a/test/testdata/conditional_filter/project/config.json +++ b/test/testdata/conditional_filter/project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "regolith_test_project", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/data_modify_remote_filter/after_run/config.json b/test/testdata/data_modify_remote_filter/after_run/config.json index ffdfc919..2937da2a 100644 --- a/test/testdata/data_modify_remote_filter/after_run/config.json +++ b/test/testdata/data_modify_remote_filter/after_run/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/data_modify_remote_filter/project/config.json b/test/testdata/data_modify_remote_filter/project/config.json index ffdfc919..2937da2a 100644 --- a/test/testdata/data_modify_remote_filter/project/config.json +++ b/test/testdata/data_modify_remote_filter/project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/double_remote_project/config.json b/test/testdata/double_remote_project/config.json index 226bce18..3e0802ae 100644 --- a/test/testdata/double_remote_project/config.json +++ b/test/testdata/double_remote_project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "regolith_test_project", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/double_remote_project_installed/config.json b/test/testdata/double_remote_project_installed/config.json index 226bce18..3e0802ae 100644 --- a/test/testdata/double_remote_project_installed/config.json +++ b/test/testdata/double_remote_project_installed/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "regolith_test_project", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/exe_filter/project/config.json b/test/testdata/exe_filter/project/config.json index 77e70500..72c52796 100644 --- a/test/testdata/exe_filter/project/config.json +++ b/test/testdata/exe_filter/project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "exe_filter_test_project", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/fresh_project/config.json b/test/testdata/fresh_project/config.json index 6d424a70..522add5d 100644 --- a/test/testdata/fresh_project/config.json +++ b/test/testdata/fresh_project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/local_requirements/project/config.json b/test/testdata/local_requirements/project/config.json index 99c389f5..c6df94ac 100644 --- a/test/testdata/local_requirements/project/config.json +++ b/test/testdata/local_requirements/project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "Local Requirements Test Project", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/minimal_project/config.json b/test/testdata/minimal_project/config.json index 7564eb0a..ce5bd8f8 100644 --- a/test/testdata/minimal_project/config.json +++ b/test/testdata/minimal_project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "regolith_test_project", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/multitarget_project/config.json b/test/testdata/multitarget_project/config.json index 51e9e380..02388da0 100644 --- a/test/testdata/multitarget_project/config.json +++ b/test/testdata/multitarget_project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "regolith_test_project", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/profile_filter/project/config.json b/test/testdata/profile_filter/project/config.json index 242df18e..d8bd551b 100644 --- a/test/testdata/profile_filter/project/config.json +++ b/test/testdata/profile_filter/project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "nested_filter_test_project", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/regolith_install/1.0.0/config.json b/test/testdata/regolith_install/1.0.0/config.json index e2efe87c..220bb8ae 100644 --- a/test/testdata/regolith_install/1.0.0/config.json +++ b/test/testdata/regolith_install/1.0.0/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_install/1.0.1/config.json b/test/testdata/regolith_install/1.0.1/config.json index 68d0859c..82aef93b 100644 --- a/test/testdata/regolith_install/1.0.1/config.json +++ b/test/testdata/regolith_install/1.0.1/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_install/HEAD/config.json b/test/testdata/regolith_install/HEAD/config.json index 84a67c90..883cc0ce 100644 --- a/test/testdata/regolith_install/HEAD/config.json +++ b/test/testdata/regolith_install/HEAD/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_install/latest/config.json b/test/testdata/regolith_install/latest/config.json index 4ceead87..2ab3fc35 100644 --- a/test/testdata/regolith_install/latest/config.json +++ b/test/testdata/regolith_install/latest/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_install/sha/config.json b/test/testdata/regolith_install/sha/config.json index b52d0ac0..f0f92b75 100644 --- a/test/testdata/regolith_install/sha/config.json +++ b/test/testdata/regolith_install/sha/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_install/tag/config.json b/test/testdata/regolith_install/tag/config.json index cab80677..260d7c40 100644 --- a/test/testdata/regolith_install/tag/config.json +++ b/test/testdata/regolith_install/tag/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_update/1.0.0/config.json b/test/testdata/regolith_update/1.0.0/config.json index 2913ce23..8e8840c5 100644 --- a/test/testdata/regolith_update/1.0.0/config.json +++ b/test/testdata/regolith_update/1.0.0/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_update/1.0.1/config.json b/test/testdata/regolith_update/1.0.1/config.json index b90139ce..f35ac642 100644 --- a/test/testdata/regolith_update/1.0.1/config.json +++ b/test/testdata/regolith_update/1.0.1/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_update/HEAD/config.json b/test/testdata/regolith_update/HEAD/config.json index 527595ed..91705a3d 100644 --- a/test/testdata/regolith_update/HEAD/config.json +++ b/test/testdata/regolith_update/HEAD/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_update/fresh_project/config.json b/test/testdata/regolith_update/fresh_project/config.json index 59bdcf69..522add5d 100644 --- a/test/testdata/regolith_update/fresh_project/config.json +++ b/test/testdata/regolith_update/fresh_project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_update/latest/config.json b/test/testdata/regolith_update/latest/config.json index 17510b4c..558923fd 100644 --- a/test/testdata/regolith_update/latest/config.json +++ b/test/testdata/regolith_update/latest/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_update/sha/config.json b/test/testdata/regolith_update/sha/config.json index a7d25048..a3b51b04 100644 --- a/test/testdata/regolith_update/sha/config.json +++ b/test/testdata/regolith_update/sha/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/regolith_update/tag/config.json b/test/testdata/regolith_update/tag/config.json index a7ce9660..4b2236d9 100644 --- a/test/testdata/regolith_update/tag/config.json +++ b/test/testdata/regolith_update/tag/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "author": "Your name", "name": "Project name", "packs": { diff --git a/test/testdata/run_missing_rp_project/config.json b/test/testdata/run_missing_rp_project/config.json index 9ab9c9e8..5ca5dd6a 100644 --- a/test/testdata/run_missing_rp_project/config.json +++ b/test/testdata/run_missing_rp_project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "filter_tester example", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/versioned_remote_filter_project/config.json b/test/testdata/versioned_remote_filter_project/config.json index e4c693b2..d0e7e9a6 100644 --- a/test/testdata/versioned_remote_filter_project/config.json +++ b/test/testdata/versioned_remote_filter_project/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "regolith_test_project", "author": "Bedrock-OSS", "packs": { diff --git a/test/testdata/versioned_remote_filter_project_after_run/config.json b/test/testdata/versioned_remote_filter_project_after_run/config.json index e4c693b2..d0e7e9a6 100644 --- a/test/testdata/versioned_remote_filter_project_after_run/config.json +++ b/test/testdata/versioned_remote_filter_project_after_run/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.json", + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", "name": "regolith_test_project", "author": "Bedrock-OSS", "packs": { From 23c269695fcfa2dad802d8690bc90c3af7c7c5c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 11 Feb 2024 19:30:30 +0100 Subject: [PATCH 38/45] Updated the documentation about export targets to mention new 'rpName' and 'bpName' properties. --- docs/docs/guide/export-targets.md | 69 +++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/docs/docs/guide/export-targets.md b/docs/docs/guide/export-targets.md index 55fe2678..16fbabe4 100644 --- a/docs/docs/guide/export-targets.md +++ b/docs/docs/guide/export-targets.md @@ -22,7 +22,7 @@ These are the export targets that Regolith offers. ## Development -The development export target will place the compiled packs into your `com.mojang` `development_*_packs` folder, in a new folder called `_BP` or `_RP`. +The development export target will place the compiled packs into your `com.mojang` `development_*_packs` folders. ```json "export": { @@ -30,6 +30,16 @@ The development export target will place the compiled packs into your `com.mojan } ``` +Optionally, you can use `rpName` and `bpName` to specify the names of the folders that will be created in the `development_*_packs` folders. You can read more about these options at the end of this page of the documentation. + +```json +"export": { + "target": "development", + "rpName": "'my_rp'", + "bpName": "'my_bp'" +} +``` + ## Local This export target will place the compiled packs into a folder called `build`, created in your regolith project. This export target is mostly useful for quick testing. @@ -40,6 +50,18 @@ This export target will place the compiled packs into a folder called `build`, c } ``` +Local export optionally accepts `rpName` and `bpName` to specify the names of the folders that will be created in the `build` folders. You can read more about these options at the end of this page of the documentation. + +```json +"export": { + "target": "local", + "rpName": "'my_rp'", + "bpName": "'my_bp'" +} +``` + + + ## Exact The Exact export target will place the files to specific, user specified locations. This is useful when you need absolute control over Regoliths export functionality. @@ -56,6 +78,8 @@ Example: } ``` +The exact export target doesn't support using `rpName` and `bpName`. The `rpPath` and `bpPath` should provide full paths to the desired locations. + ## World The World export target will place the compiled files into a specific world. This is useful for teams that prefer working in-world, as opposed to in the development pack folders. @@ -67,17 +91,54 @@ Example: ```json "export": { "target": "world", - "worldName": "...", // This - "worldPath": "..." // OR this + "worldName": "..." // This + // "worldPath": "..." // OR this } ``` +Optionally, you can use `rpName` and `bpName` to specify the names of the folders that will be created in the world. You can read more about these options at the end of this page of the documentation. + +```json +"export": { + "target": "world", + "worldPath": "...", + "rpName": "'my_rp'", + "bpName": "'my_bp'" +} +``` + + ## Preview -The development export target will place the compiled packs into your (minecraft preview) `com.mojang` `development_*_packs` folder, in a new folder called `_bp` or `_rp`. +The development export target will place the compiled packs into your **(minecraft preview)** `com.mojang` `development_*_packs` folder. ```json "export": { "target": "preview" } ``` + +Optionally, you can use `rpName` and `bpName` to specify the names of the folders that will be created in the `development_*_packs` folders. You can read more about these options at the end of this page of the documentation. +```json +"export": { + "target": "preview", + "rpName": "'my_rp'", + "bpName": "'my_bp'" +} +``` + +# The `rpName` and `bpName` expressions + +The `rpName` and `bpName` are expressions evaulated using the [go-simple-eval](https://github.com/stirante/go-simple-eval/) library. They let you specify the names of the folders of the exported packs in some of the export targets. + +The go-simple-eval library allows you to use simple expressions to generate the names of the folders. The expressions can use the following variables: + +- `project.name` - The name of the project. +- `project.author` - The author of the project. +- `os` - The host operating system. +- `arch` - The host architecture. +- `debug` - whether regolith is running in debug mode or not. +- `version` - The version of regolith. +- `profile` - The name of the profile being run. + +Go-simple-eval can concatenate strings using the `+` operator. The strings must be enclosed in single quotes. From 178c483829ac6398a9cf8f02ba83388636365188 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 11 Feb 2024 21:46:09 +0100 Subject: [PATCH 39/45] Added test for exporting files into a customized path that uses rpName and bpName properties. --- test/common.go | 6 +++ test/custom_pack_name_test.go | 40 +++++++++++++++++++ .../some_bp_file.txt | 1 + .../some_rp_file.txt | 1 + .../custom_pack_name/project/.gitignore | 2 + .../custom_pack_name/project/config.json | 24 +++++++++++ .../project/packs/BP/some_bp_file.txt | 1 + .../project/packs/RP/some_rp_file.txt | 1 + .../project/packs/data/.ignoreme | 1 + 9 files changed, 77 insertions(+) create mode 100644 test/custom_pack_name_test.go create mode 100644 test/testdata/custom_pack_name/expected_build_result/CustomExportPackName_by_Bedrock-OSS_BP/some_bp_file.txt create mode 100644 test/testdata/custom_pack_name/expected_build_result/CustomExportPackName_by_Bedrock-OSS_RP/some_rp_file.txt create mode 100644 test/testdata/custom_pack_name/project/.gitignore create mode 100644 test/testdata/custom_pack_name/project/config.json create mode 100644 test/testdata/custom_pack_name/project/packs/BP/some_bp_file.txt create mode 100644 test/testdata/custom_pack_name/project/packs/RP/some_rp_file.txt create mode 100644 test/testdata/custom_pack_name/project/packs/data/.ignoreme diff --git a/test/common.go b/test/common.go index e9fa53b5..af250bab 100644 --- a/test/common.go +++ b/test/common.go @@ -70,6 +70,12 @@ const ( // the execution. conditionalFilterPath = "testdata/conditional_filter" + // customPackNamePath contains two subdirectories 'project' and + // 'expected_build_result'. The project is a Regolith project with custom + // rpName and bpName properties in the filter. The 'expected_build_result' + // contains the expected content of the build directory. + customPackNamePath = "testdata/custom_pack_name" + dataModifyRemoteFilter = "testdata/data_modify_remote_filter" ) diff --git a/test/custom_pack_name_test.go b/test/custom_pack_name_test.go new file mode 100644 index 00000000..ac0434ee --- /dev/null +++ b/test/custom_pack_name_test.go @@ -0,0 +1,40 @@ +package test + +import ( + "os" + "path/filepath" + "testing" + + "github.com/Bedrock-OSS/regolith/regolith" +) + +// TestCustomPackName runs a test that checks whether the rpName and bpName +// properties of a filter properly change the name of the directories created +// for resource pack and behavior pack in the "local" export mode. +func TestCustomPackName(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) + + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestCustomPackName", t) + + t.Log("Copying the project files into the testing directory...") + project := absOrFatal(filepath.Join(customPackNamePath, "project"), t) + copyFilesOrFatal(project, tmpDir, t) + + // Load abs path of the expected result and switch to the working directory + expectedBuildResult := absOrFatal( + filepath.Join(customPackNamePath, "expected_build_result"), t) + os.Chdir(tmpDir) + + // THE TEST + t.Log("Running Regolith with a conditional filter...") + if err := regolith.Run("default", true); err != nil { + t.Fatal("'regolith run' failed:", err.Error()) + } + + // TEST EVALUATION + t.Log("Evaluating the test results...") + comparePaths(expectedBuildResult, filepath.Join(tmpDir, "build"), t) +} diff --git a/test/testdata/custom_pack_name/expected_build_result/CustomExportPackName_by_Bedrock-OSS_BP/some_bp_file.txt b/test/testdata/custom_pack_name/expected_build_result/CustomExportPackName_by_Bedrock-OSS_BP/some_bp_file.txt new file mode 100644 index 00000000..b97a0d79 --- /dev/null +++ b/test/testdata/custom_pack_name/expected_build_result/CustomExportPackName_by_Bedrock-OSS_BP/some_bp_file.txt @@ -0,0 +1 @@ +This is an example behavior pack file to test if exporting works as exected. \ No newline at end of file diff --git a/test/testdata/custom_pack_name/expected_build_result/CustomExportPackName_by_Bedrock-OSS_RP/some_rp_file.txt b/test/testdata/custom_pack_name/expected_build_result/CustomExportPackName_by_Bedrock-OSS_RP/some_rp_file.txt new file mode 100644 index 00000000..55a60ff6 --- /dev/null +++ b/test/testdata/custom_pack_name/expected_build_result/CustomExportPackName_by_Bedrock-OSS_RP/some_rp_file.txt @@ -0,0 +1 @@ +This is an example resource pack file to test if exporting works as exected. \ No newline at end of file diff --git a/test/testdata/custom_pack_name/project/.gitignore b/test/testdata/custom_pack_name/project/.gitignore new file mode 100644 index 00000000..3f195ca9 --- /dev/null +++ b/test/testdata/custom_pack_name/project/.gitignore @@ -0,0 +1,2 @@ +/build +/.regolith \ No newline at end of file diff --git a/test/testdata/custom_pack_name/project/config.json b/test/testdata/custom_pack_name/project/config.json new file mode 100644 index 00000000..c1bb592e --- /dev/null +++ b/test/testdata/custom_pack_name/project/config.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", + "author": "Bedrock-OSS", + "name": "CustomExportPackName", + "packs": { + "behaviorPack": "./packs/BP", + "resourcePack": "./packs/RP" + }, + "regolith": { + "dataPath": "./packs/data", + "filterDefinitions": {}, + "profiles": { + "default": { + "export": { + "readOnly": false, + "target": "local", + "bpName": "project.name + '_by_' + project.author + '_BP'", + "rpName": "project.name + '_by_' + project.author + '_RP'" + }, + "filters": [] + } + } + } +} \ No newline at end of file diff --git a/test/testdata/custom_pack_name/project/packs/BP/some_bp_file.txt b/test/testdata/custom_pack_name/project/packs/BP/some_bp_file.txt new file mode 100644 index 00000000..b97a0d79 --- /dev/null +++ b/test/testdata/custom_pack_name/project/packs/BP/some_bp_file.txt @@ -0,0 +1 @@ +This is an example behavior pack file to test if exporting works as exected. \ No newline at end of file diff --git a/test/testdata/custom_pack_name/project/packs/RP/some_rp_file.txt b/test/testdata/custom_pack_name/project/packs/RP/some_rp_file.txt new file mode 100644 index 00000000..55a60ff6 --- /dev/null +++ b/test/testdata/custom_pack_name/project/packs/RP/some_rp_file.txt @@ -0,0 +1 @@ +This is an example resource pack file to test if exporting works as exected. \ No newline at end of file diff --git a/test/testdata/custom_pack_name/project/packs/data/.ignoreme b/test/testdata/custom_pack_name/project/packs/data/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/custom_pack_name/project/packs/data/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file From fa0c2954e85f369e523f06f4d0ea13c0445bebff Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Mar 2024 17:30:19 +0100 Subject: [PATCH 40/45] Added some doc comments. --- regolith/file_system.go | 2 ++ regolith/utils.go | 1 + 2 files changed, 3 insertions(+) diff --git a/regolith/file_system.go b/regolith/file_system.go index dcfa8ace..2891371a 100644 --- a/regolith/file_system.go +++ b/regolith/file_system.go @@ -875,6 +875,8 @@ func MoveOrCopy( } // SyncDirectories copies the source to destination while checking size and modification time. +// If the file in the destination is different than the one in the source, it's overwritten, +// otherwise it's skipped (the destination file is not modified). func SyncDirectories( source string, destination string, makeReadOnly bool, copyParentAcl bool, ) error { diff --git a/regolith/utils.go b/regolith/utils.go index f8372247..24a5dd11 100644 --- a/regolith/utils.go +++ b/regolith/utils.go @@ -431,6 +431,7 @@ func EscapePathPart(s string) string { return sb.String() } +// SliceAny returns true if any of the elements in the slice satisfy the predicate. func SliceAny[T interface{}](slice []T, predicate func(T) bool) bool { for _, item := range slice { if predicate(item) { From 65b2cf43d5734e8b1dbc5b505367d1ca6936c31a Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Mar 2024 17:33:52 +0100 Subject: [PATCH 41/45] Removed the unused 'copyParentAcl' argument from the 'SyncDirectories' function: I don't think it's needed for this function because it copies files and the ACL problems are most likely only related to moving them. See https://github.com/Bedrock-OSS/regolith/pull/272#discussion_r1378230282 for more details. --- regolith/export.go | 6 +++--- regolith/file_system.go | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/regolith/export.go b/regolith/export.go index b8b4fa88..593f0d61 100644 --- a/regolith/export.go +++ b/regolith/export.go @@ -141,7 +141,7 @@ func GetExportNames(exportTarget ExportTarget, ctx RunContext) (bpName string, r // 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(ctx RunContext) error { - MeasureStart("Export - GetExportPaths") + MeasureStart("Export - GetExportPaths") profile, err := ctx.GetProfile() if err != nil { return burrito.WrapError(err, runContextGetProfileError) @@ -292,13 +292,13 @@ func ExportProject(ctx RunContext) error { if IsExperimentEnabled(SizeTimeCheck) { // Export BP Logger.Infof("Exporting behavior pack to \"%s\".", bpPath) - err = SyncDirectories(filepath.Join(dotRegolithPath, "tmp/BP"), bpPath, exportTarget.ReadOnly, true) + err = SyncDirectories(filepath.Join(dotRegolithPath, "tmp/BP"), bpPath, exportTarget.ReadOnly) if err != nil { return burrito.WrapError(err, "Failed to export behavior pack.") } // Export RP Logger.Infof("Exporting project to \"%s\".", filepath.Clean(rpPath)) - err = SyncDirectories(filepath.Join(dotRegolithPath, "tmp/RP"), rpPath, exportTarget.ReadOnly, true) + err = SyncDirectories(filepath.Join(dotRegolithPath, "tmp/RP"), rpPath, exportTarget.ReadOnly) if err != nil { return burrito.WrapError(err, "Failed to export resource pack.") } diff --git a/regolith/file_system.go b/regolith/file_system.go index 2891371a..9f4d2c22 100644 --- a/regolith/file_system.go +++ b/regolith/file_system.go @@ -878,7 +878,7 @@ func MoveOrCopy( // If the file in the destination is different than the one in the source, it's overwritten, // otherwise it's skipped (the destination file is not modified). func SyncDirectories( - source string, destination string, makeReadOnly bool, copyParentAcl bool, + source string, destination string, makeReadOnly bool, ) error { // Make destination parent if not exists destinationParent := filepath.Dir(destination) @@ -951,8 +951,6 @@ func SyncDirectories( } } - //TODO: copy ACL. To be honest, I have no clue why it was there in the first place - // Make files read only if this option is selected if makeReadOnly { Logger.Infof("Changing the access for output path to "+ From 1cf53bb457cff2b9e2fdcaec1d3128e46412feca Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Mar 2024 19:39:24 +0100 Subject: [PATCH 42/45] Fixed regolith crushing when the 'size_time_check' is combined with the read-only export. --- regolith/file_system.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/regolith/file_system.go b/regolith/file_system.go index 9f4d2c22..765b5fca 100644 --- a/regolith/file_system.go +++ b/regolith/file_system.go @@ -904,6 +904,14 @@ func SyncDirectories( return os.MkdirAll(destPath, info.Mode()) } Logger.Debugf("SYNC: Copying file %s to %s", srcPath, destPath) + // If file exists, we need to remove it first to avoid permission issues when it's + // read-only + if destInfo != nil { + err = os.Remove(destPath) + if err != nil { + return burrito.WrapErrorf(err, osRemoveError, destPath) + } + } return copyFile(srcPath, destPath, info) } else { Logger.Debugf("SYNC: Skipping file %s", srcPath) From beb8b4a6fae55fe77783c01a8bf0d3fffe1b9e3a Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Mar 2024 22:36:19 +0100 Subject: [PATCH 43/45] The 'size_time_check' experimental flag also affects moving files from source to tmp to speed up the process even more. --- regolith/profile.go | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/regolith/profile.go b/regolith/profile.go index bcf4b6e5..d22b00f8 100644 --- a/regolith/profile.go +++ b/regolith/profile.go @@ -15,15 +15,18 @@ import ( // SetupTmpFiles set up the workspace for the filters. func SetupTmpFiles(config Config, dotRegolithPath string) error { start := time.Now() + useSizeTimeCheck := IsExperimentEnabled(SizeTimeCheck) // Setup Directories tmpPath := filepath.Join(dotRegolithPath, "tmp") - Logger.Debugf("Cleaning \"%s\"", tmpPath) - err := os.RemoveAll(tmpPath) - if err != nil { - return burrito.WrapErrorf(err, osRemoveError, tmpPath) + if !useSizeTimeCheck { + Logger.Debugf("Cleaning \"%s\"", tmpPath) + err := os.RemoveAll(tmpPath) + if err != nil { + return burrito.WrapErrorf(err, osRemoveError, tmpPath) + } } - err = os.MkdirAll(tmpPath, 0755) + err := os.MkdirAll(tmpPath, 0755) if err != nil { return burrito.WrapErrorf(err, osMkdirError, tmpPath) } @@ -36,6 +39,7 @@ func SetupTmpFiles(config Config, dotRegolithPath string) error { path, shortName, descriptiveName string, ) error { p := filepath.Join(tmpPath, shortName) + // A project don't have to have a RP or BP so path can be "" if path != "" { stats, err := os.Stat(path) if err != nil { @@ -48,12 +52,19 @@ func SetupTmpFiles(config Config, dotRegolithPath string) error { } } } else if stats.IsDir() { - err = copy.Copy( - path, - p, - copy.Options{PreserveTimes: IsExperimentEnabled(SizeTimeCheck), Sync: false}) - if err != nil { - return burrito.WrapErrorf(err, osCopyError, path, p) + if useSizeTimeCheck { + err = SyncDirectories(path, p, false) + if err != nil { + return burrito.WrapError(err, "Failed to export behavior pack.") + } + } else { + err = copy.Copy( + path, + p, + copy.Options{PreserveTimes: false, Sync: false}) + if err != nil { + return burrito.WrapErrorf(err, osCopyError, path, p) + } } } else { // The folder paths leads to a file return burrito.WrappedErrorf(isDirNotADirError, path) From 0b267f88d9bf5cecb44556ac089a17be9eba70c4 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Mar 2024 10:32:22 +0100 Subject: [PATCH 44/45] Added tests for 'size_time_check' experimental flag. --- test/common.go | 7 ++ ...ize_time_check_optimization_method_test.go | 112 ++++++++++++++++++ .../project/.gitignore | 2 + .../project/.regolith/cache/venvs/.ignoreme | 1 + .../project/config.json | 33 ++++++ .../project/local_filters/fill_with_data.py | 16 +++ .../project/packs/BP/bp_file_1.txt | 1 + .../project/packs/BP/bp_file_2.txt | 1 + .../project/packs/BP/bp_file_3.txt | 1 + .../project/packs/BP/bp_file_4.txt | 1 + .../project/packs/BP/bp_file_5.txt | 1 + .../project/packs/RP/.ignoreme | 1 + .../project/packs/data/.ignoreme | 1 + .../project_after_run/.gitignore | 2 + .../.regolith/cache/edited_files.json | 21 ++++ .../.regolith/cache/venvs/.ignoreme | 1 + .../.regolith/tmp/BP/bp_file_1.txt | 1 + .../.regolith/tmp/BP/bp_file_2.txt | 1 + .../.regolith/tmp/BP/bp_file_3.txt | 1 + .../.regolith/tmp/BP/bp_file_4.txt | 1 + .../.regolith/tmp/BP/bp_file_5.txt | 1 + .../tmp/BP/filter_generated_data_1.txt | 1 + .../tmp/BP/filter_generated_data_2.txt | 1 + .../tmp/BP/filter_generated_data_3.txt | 1 + .../tmp/BP/filter_generated_data_4.txt | 1 + .../tmp/BP/filter_generated_data_5.txt | 1 + .../.regolith/tmp/RP/.ignoreme | 1 + .../.regolith/tmp/data/.ignoreme | 1 + .../project_after_run/build/BP/bp_file_1.txt | 1 + .../project_after_run/build/BP/bp_file_2.txt | 1 + .../project_after_run/build/BP/bp_file_3.txt | 1 + .../project_after_run/build/BP/bp_file_4.txt | 1 + .../project_after_run/build/BP/bp_file_5.txt | 1 + .../build/BP/filter_generated_data_1.txt | 1 + .../build/BP/filter_generated_data_2.txt | 1 + .../build/BP/filter_generated_data_3.txt | 1 + .../build/BP/filter_generated_data_4.txt | 1 + .../build/BP/filter_generated_data_5.txt | 1 + .../project_after_run/build/RP/.ignoreme | 1 + .../project_after_run/config.json | 33 ++++++ .../local_filters/fill_with_data.py | 16 +++ .../project_after_run/packs/BP/bp_file_1.txt | 1 + .../project_after_run/packs/BP/bp_file_2.txt | 1 + .../project_after_run/packs/BP/bp_file_3.txt | 1 + .../project_after_run/packs/BP/bp_file_4.txt | 1 + .../project_after_run/packs/BP/bp_file_5.txt | 1 + .../project_after_run/packs/RP/.ignoreme | 1 + .../project_after_run/packs/data/.ignoreme | 1 + 48 files changed, 281 insertions(+) create mode 100644 test/size_time_check_optimization_method_test.go create mode 100644 test/testdata/size_time_check_optimization/project/.gitignore create mode 100644 test/testdata/size_time_check_optimization/project/.regolith/cache/venvs/.ignoreme create mode 100644 test/testdata/size_time_check_optimization/project/config.json create mode 100644 test/testdata/size_time_check_optimization/project/local_filters/fill_with_data.py create mode 100644 test/testdata/size_time_check_optimization/project/packs/BP/bp_file_1.txt create mode 100644 test/testdata/size_time_check_optimization/project/packs/BP/bp_file_2.txt create mode 100644 test/testdata/size_time_check_optimization/project/packs/BP/bp_file_3.txt create mode 100644 test/testdata/size_time_check_optimization/project/packs/BP/bp_file_4.txt create mode 100644 test/testdata/size_time_check_optimization/project/packs/BP/bp_file_5.txt create mode 100644 test/testdata/size_time_check_optimization/project/packs/RP/.ignoreme create mode 100644 test/testdata/size_time_check_optimization/project/packs/data/.ignoreme create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.gitignore create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/cache/edited_files.json create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/cache/venvs/.ignoreme create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_1.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_2.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_3.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_4.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_5.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_1.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_2.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_3.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_4.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_5.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/RP/.ignoreme create mode 100644 test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/data/.ignoreme create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_1.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_2.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_3.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_4.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_5.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_1.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_2.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_3.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_4.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_5.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/build/RP/.ignoreme create mode 100644 test/testdata/size_time_check_optimization/project_after_run/config.json create mode 100644 test/testdata/size_time_check_optimization/project_after_run/local_filters/fill_with_data.py create mode 100644 test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_1.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_2.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_3.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_4.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_5.txt create mode 100644 test/testdata/size_time_check_optimization/project_after_run/packs/RP/.ignoreme create mode 100644 test/testdata/size_time_check_optimization/project_after_run/packs/data/.ignoreme diff --git a/test/common.go b/test/common.go index af250bab..a83b44ff 100644 --- a/test/common.go +++ b/test/common.go @@ -77,6 +77,13 @@ const ( customPackNamePath = "testdata/custom_pack_name" dataModifyRemoteFilter = "testdata/data_modify_remote_filter" + + // sizeTimeCheckOptimizationPath contains two subdirectories 'project' and + // 'project_after_run'. The project is a Regolith project with a simple + // Python filter that generates some additional files.The + // 'project_after_run' is the same project but after running Regolith with + // the size_time_check experiment enabled. + sizeTimeCheckOptimizationPath = "testdata/size_time_check_optimization" ) // firstErr returns the first error in a list of errors. If the list is empty diff --git a/test/size_time_check_optimization_method_test.go b/test/size_time_check_optimization_method_test.go new file mode 100644 index 00000000..f5a74be8 --- /dev/null +++ b/test/size_time_check_optimization_method_test.go @@ -0,0 +1,112 @@ +package test + +import ( + "bytes" + "os" + "path/filepath" + "testing" + "time" + + "github.com/Bedrock-OSS/regolith/regolith" +) + +// createBigFile creates a text file filled with a's with the given size in MB. +func createBigFile(sizeMB int, path string) error { + // Create the file + f, err := os.Create(path) + if err != nil { + return err + } + defer f.Close() + _, err = f.Write(bytes.Repeat([]byte("a"), sizeMB*1024*1024)) + if err != nil { + return err + } + return nil +} + +// TestSizeTimeCheckOptimizationCorectness tests if running Regolith with the +// size_time_check experiment enabled exports the files correctly. +func TestSizeTimeCheckOptimizationCorectness(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) + + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestSizeTimeCheckOptimizationCorectness", t) + + t.Log("Copying the project files into the testing directory...") + project := absOrFatal(filepath.Join(sizeTimeCheckOptimizationPath, "project"), t) + copyFilesOrFatal(project, tmpDir, t) + + // Load abs path of the expected result and switch to the working directory + expectedBuildResult := absOrFatal( + filepath.Join(sizeTimeCheckOptimizationPath, "project_after_run"), t) + os.Chdir(tmpDir) + + // THE TEST + // Enable the experiment + regolith.EnabledExperiments = append(regolith.EnabledExperiments, "size_time_check") + + // Run the project + t.Log("Running Regolith...") + + if err := regolith.Run("default", true); err != nil { + t.Fatal("'regolith run' failed:", err.Error()) + } + // TEST EVALUATION + t.Log("Evaluating the result...") + comparePaths(expectedBuildResult, tmpDir, t) +} + +// TestSizeTimeCheckOptimizationSpeed tests if running Regolith with the +// size_time_check experiment enabled is faster on the second run (when the +// files are not changed in relation to the first run). +func TestSizeTimeCheckOptimizationSpeed(t *testing.T) { + // Switch to current working directory at the end of the test + defer os.Chdir(getWdOrFatal(t)) + + // TEST PREPARATION + t.Log("Clearing the testing directory...") + tmpDir := prepareTestDirectory("TestSizeTimeCheckOptimizationSpeed", t) + + t.Log("Copying the project files into the testing directory...") + project := absOrFatal(filepath.Join(sizeTimeCheckOptimizationPath, "project"), t) + copyFilesOrFatal(project, tmpDir, t) + + // Add a big file to the project 10 MB + t.Log("Creating a big file in the test project...") + bigFilePath := filepath.Join(tmpDir, "packs/BP/big_file.txt") + if err := createBigFile(10, bigFilePath); err != nil { + t.Fatalf("Creating a big file failed: %v", err) + } + os.Chdir(tmpDir) + + // THE TEST + // Enable the experiment + regolith.EnabledExperiments = append(regolith.EnabledExperiments, "size_time_check") + + // Run the project twice, the second run should be faster + runtimes := make([]time.Duration, 0) + for i := 0; i < 2; i++ { + // Run the project + t.Logf("Running Regolith for the %d. time...", i+1) + + // Start the timer + start := time.Now() + if err := regolith.Run("default", true); err != nil { + t.Fatal("'regolith run' failed:", err.Error()) + } + // Stop the timer + runtimes = append(runtimes, time.Since(start)) + } + // Check if the second run was faster. It should be because in the second + // run files are not copied (because they don't change). + if runtimes[0] < runtimes[1] { + t.Fatalf("The second run was slower than the first one: %v < %v", + runtimes[0], runtimes[1]) + } else { + t.Logf("The second run was faster than the first one: %v > %v", + runtimes[0], runtimes[1]) + } +} diff --git a/test/testdata/size_time_check_optimization/project/.gitignore b/test/testdata/size_time_check_optimization/project/.gitignore new file mode 100644 index 00000000..3f195ca9 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/.gitignore @@ -0,0 +1,2 @@ +/build +/.regolith \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project/.regolith/cache/venvs/.ignoreme b/test/testdata/size_time_check_optimization/project/.regolith/cache/venvs/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/.regolith/cache/venvs/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project/config.json b/test/testdata/size_time_check_optimization/project/config.json new file mode 100644 index 00000000..5ed12edc --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/config.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", + "author": "Your name", + "name": "Project name", + "packs": { + "behaviorPack": "./packs/BP", + "resourcePack": "./packs/RP" + }, + "regolith": { + "dataPath": "./packs/data", + "filterDefinitions": { + "fill_with_data": { + "runWith": "python", + "script": "local_filters/fill_with_data.py" + } + }, + "profiles": { + "default": { + "export": { + "readOnly": true, + "target": "local", + "bpName": "'BP'", + "rpName": "'RP'" + }, + "filters": [ + { + "filter": "fill_with_data" + } + ] + } + } + } +} diff --git a/test/testdata/size_time_check_optimization/project/local_filters/fill_with_data.py b/test/testdata/size_time_check_optimization/project/local_filters/fill_with_data.py new file mode 100644 index 00000000..52774f24 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/local_filters/fill_with_data.py @@ -0,0 +1,16 @@ +''' +Fills the BP with data for testing. +''' + +def main(): + for i in range(1, 6): + with open( + f'BP/filter_generated_data_{i}.txt', + 'w', + encoding='utf8' + ) as f: + f.write( + f'This is file number {i} generated by fill_with_data.py\n') + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_1.txt b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_1.txt new file mode 100644 index 00000000..1938d622 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_1.txt @@ -0,0 +1 @@ +This is file number 1 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_2.txt b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_2.txt new file mode 100644 index 00000000..e380e385 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_2.txt @@ -0,0 +1 @@ +This is file number 2 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_3.txt b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_3.txt new file mode 100644 index 00000000..610d3d57 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_3.txt @@ -0,0 +1 @@ +This is file number 3 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_4.txt b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_4.txt new file mode 100644 index 00000000..2a4e1aeb --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_4.txt @@ -0,0 +1 @@ +This is file number 4 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_5.txt b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_5.txt new file mode 100644 index 00000000..837f1449 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/packs/BP/bp_file_5.txt @@ -0,0 +1 @@ +This is file number 5 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project/packs/RP/.ignoreme b/test/testdata/size_time_check_optimization/project/packs/RP/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/packs/RP/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project/packs/data/.ignoreme b/test/testdata/size_time_check_optimization/project/packs/data/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/size_time_check_optimization/project/packs/data/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project_after_run/.gitignore b/test/testdata/size_time_check_optimization/project_after_run/.gitignore new file mode 100644 index 00000000..3f195ca9 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.gitignore @@ -0,0 +1,2 @@ +/build +/.regolith \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/cache/edited_files.json b/test/testdata/size_time_check_optimization/project_after_run/.regolith/cache/edited_files.json new file mode 100644 index 00000000..7ab7ba53 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/cache/edited_files.json @@ -0,0 +1,21 @@ +{ + "rp": { + "build/RP/": [ + ".ignoreme" + ] + }, + "bp": { + "build/BP/": [ + "bp_file_1.txt", + "bp_file_2.txt", + "bp_file_3.txt", + "bp_file_4.txt", + "bp_file_5.txt", + "filter_generated_data_1.txt", + "filter_generated_data_2.txt", + "filter_generated_data_3.txt", + "filter_generated_data_4.txt", + "filter_generated_data_5.txt" + ] + } +} \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/cache/venvs/.ignoreme b/test/testdata/size_time_check_optimization/project_after_run/.regolith/cache/venvs/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/cache/venvs/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_1.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_1.txt new file mode 100644 index 00000000..1938d622 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_1.txt @@ -0,0 +1 @@ +This is file number 1 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_2.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_2.txt new file mode 100644 index 00000000..e380e385 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_2.txt @@ -0,0 +1 @@ +This is file number 2 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_3.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_3.txt new file mode 100644 index 00000000..610d3d57 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_3.txt @@ -0,0 +1 @@ +This is file number 3 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_4.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_4.txt new file mode 100644 index 00000000..2a4e1aeb --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_4.txt @@ -0,0 +1 @@ +This is file number 4 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_5.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_5.txt new file mode 100644 index 00000000..837f1449 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/bp_file_5.txt @@ -0,0 +1 @@ +This is file number 5 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_1.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_1.txt new file mode 100644 index 00000000..faa9f477 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_1.txt @@ -0,0 +1 @@ +This is file number 1 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_2.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_2.txt new file mode 100644 index 00000000..24a4b495 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_2.txt @@ -0,0 +1 @@ +This is file number 2 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_3.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_3.txt new file mode 100644 index 00000000..be2d60dc --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_3.txt @@ -0,0 +1 @@ +This is file number 3 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_4.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_4.txt new file mode 100644 index 00000000..0862fd62 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_4.txt @@ -0,0 +1 @@ +This is file number 4 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_5.txt b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_5.txt new file mode 100644 index 00000000..0c584edc --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/BP/filter_generated_data_5.txt @@ -0,0 +1 @@ +This is file number 5 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/RP/.ignoreme b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/RP/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/RP/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/data/.ignoreme b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/data/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/.regolith/tmp/data/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_1.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_1.txt new file mode 100644 index 00000000..1938d622 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_1.txt @@ -0,0 +1 @@ +This is file number 1 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_2.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_2.txt new file mode 100644 index 00000000..e380e385 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_2.txt @@ -0,0 +1 @@ +This is file number 2 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_3.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_3.txt new file mode 100644 index 00000000..610d3d57 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_3.txt @@ -0,0 +1 @@ +This is file number 3 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_4.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_4.txt new file mode 100644 index 00000000..2a4e1aeb --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_4.txt @@ -0,0 +1 @@ +This is file number 4 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_5.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_5.txt new file mode 100644 index 00000000..837f1449 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/bp_file_5.txt @@ -0,0 +1 @@ +This is file number 5 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_1.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_1.txt new file mode 100644 index 00000000..faa9f477 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_1.txt @@ -0,0 +1 @@ +This is file number 1 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_2.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_2.txt new file mode 100644 index 00000000..24a4b495 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_2.txt @@ -0,0 +1 @@ +This is file number 2 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_3.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_3.txt new file mode 100644 index 00000000..be2d60dc --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_3.txt @@ -0,0 +1 @@ +This is file number 3 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_4.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_4.txt new file mode 100644 index 00000000..0862fd62 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_4.txt @@ -0,0 +1 @@ +This is file number 4 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_5.txt b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_5.txt new file mode 100644 index 00000000..0c584edc --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/BP/filter_generated_data_5.txt @@ -0,0 +1 @@ +This is file number 5 generated by fill_with_data.py diff --git a/test/testdata/size_time_check_optimization/project_after_run/build/RP/.ignoreme b/test/testdata/size_time_check_optimization/project_after_run/build/RP/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/build/RP/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project_after_run/config.json b/test/testdata/size_time_check_optimization/project_after_run/config.json new file mode 100644 index 00000000..5ed12edc --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/config.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.2.json", + "author": "Your name", + "name": "Project name", + "packs": { + "behaviorPack": "./packs/BP", + "resourcePack": "./packs/RP" + }, + "regolith": { + "dataPath": "./packs/data", + "filterDefinitions": { + "fill_with_data": { + "runWith": "python", + "script": "local_filters/fill_with_data.py" + } + }, + "profiles": { + "default": { + "export": { + "readOnly": true, + "target": "local", + "bpName": "'BP'", + "rpName": "'RP'" + }, + "filters": [ + { + "filter": "fill_with_data" + } + ] + } + } + } +} diff --git a/test/testdata/size_time_check_optimization/project_after_run/local_filters/fill_with_data.py b/test/testdata/size_time_check_optimization/project_after_run/local_filters/fill_with_data.py new file mode 100644 index 00000000..52774f24 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/local_filters/fill_with_data.py @@ -0,0 +1,16 @@ +''' +Fills the BP with data for testing. +''' + +def main(): + for i in range(1, 6): + with open( + f'BP/filter_generated_data_{i}.txt', + 'w', + encoding='utf8' + ) as f: + f.write( + f'This is file number {i} generated by fill_with_data.py\n') + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_1.txt b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_1.txt new file mode 100644 index 00000000..1938d622 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_1.txt @@ -0,0 +1 @@ +This is file number 1 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_2.txt b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_2.txt new file mode 100644 index 00000000..e380e385 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_2.txt @@ -0,0 +1 @@ +This is file number 2 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_3.txt b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_3.txt new file mode 100644 index 00000000..610d3d57 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_3.txt @@ -0,0 +1 @@ +This is file number 3 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_4.txt b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_4.txt new file mode 100644 index 00000000..2a4e1aeb --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_4.txt @@ -0,0 +1 @@ +This is file number 4 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_5.txt b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_5.txt new file mode 100644 index 00000000..837f1449 --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/packs/BP/bp_file_5.txt @@ -0,0 +1 @@ +This is file number 5 from the source BP. diff --git a/test/testdata/size_time_check_optimization/project_after_run/packs/RP/.ignoreme b/test/testdata/size_time_check_optimization/project_after_run/packs/RP/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/packs/RP/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file diff --git a/test/testdata/size_time_check_optimization/project_after_run/packs/data/.ignoreme b/test/testdata/size_time_check_optimization/project_after_run/packs/data/.ignoreme new file mode 100644 index 00000000..de58919d --- /dev/null +++ b/test/testdata/size_time_check_optimization/project_after_run/packs/data/.ignoreme @@ -0,0 +1 @@ +This file is used for testing to simulate an empty directory because git doesn't allow saving empty directories. \ No newline at end of file From 01209f4d263c6038dfd727a28bd0374bcff2271a Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Mar 2024 10:52:19 +0100 Subject: [PATCH 45/45] Added a documentation page about '--experiments' and 'size_time_check'. --- docs/docs/.vitepress/config.ts | 4 ++++ docs/docs/guide/experiments.md | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 docs/docs/guide/experiments.md diff --git a/docs/docs/.vitepress/config.ts b/docs/docs/.vitepress/config.ts index 8b90eeb1..5005a50b 100644 --- a/docs/docs/.vitepress/config.ts +++ b/docs/docs/.vitepress/config.ts @@ -126,6 +126,10 @@ export default defineConfig({ text: 'Profiles', link: '/guide/profiles' }, + { + text: 'Experiments', + link: '/guide/experiments' + }, { text: 'Safety', link: '/guide/safety' diff --git a/docs/docs/guide/experiments.md b/docs/docs/guide/experiments.md new file mode 100644 index 00000000..237271ea --- /dev/null +++ b/docs/docs/guide/experiments.md @@ -0,0 +1,23 @@ +--- +title: Experiments +--- + +# Experiments + +Experiments are new experimental features of Regolith to be released in the future versions, once proven to be stable and useful. The experiments can be enabled with the `--experiments` flag. + +## Currently Available Experiments + +### `size_time_check` + +The `size_time_check` is an experiment that aims to speed up `regolith run` and `regolith watch` commands. It achieves this by checking the size and modification time of the files before moving them between working and output directories. If the source file is the same size and has the same modification time as the destination file, the target file will remain untouched (Regolith assumes that the files are the same). + +The `size_time_check` should greatly speed up the exports of large projects. + +The downside of this approach is that on the first run, the export will be slower, but on subsequent runs, the export will be much faster. This means that the `size_time_check` is not recommended for CI where Regolith is run only once. + +Usage: +``` +regolith run --experiments size_time_check +regolith watch --experiments size_time_check +``` \ No newline at end of file