Skip to content
Merged

1.8.0 #353

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
aa456ba
Implemented new user config setting for specifying Regolith's 'tmp' d…
Nusiq Feb 26, 2026
b3a51f7
feat: add Bun filter runner support
PaoeniDev Apr 14, 2026
8bbd392
feat: add install filter dependencies using Bun
PaoeniDev Apr 15, 2026
4134fc9
When the tmpDir user setting is used with an absolute path, Regolith …
Nusiq Apr 16, 2026
6eea3c9
Merge pull request #350 from Bedrock-OSS/user-config-tmp-dir
Nusiq Apr 16, 2026
285ebe8
Merge pull request #351 from PaoeniDev/feature/filter_bun
Nusiq Apr 16, 2026
046bca9
Fixed bun filter after creating compilation errors from merging branc…
Nusiq Apr 16, 2026
c4e7ee2
Added userSettingIncorrectIndexUseError.
Nusiq Apr 17, 2026
f0e4a45
Fixed a typo in a comment.
Nusiq Apr 17, 2026
dbfa60b
Added user settings for specifying the path to the runners for execut…
Nusiq Apr 18, 2026
5a7e869
Added node_runner_override user config option, to let users force Reg…
Nusiq Apr 20, 2026
5de8c59
Added getRunner function.
Nusiq Apr 20, 2026
1e229f6
Merge pull request #355 from Bedrock-OSS/runner-path-2
stirante Apr 25, 2026
d85e434
Merge branch 'develop' into node-runner-override
Nusiq Apr 26, 2026
2e2cf1e
The 'node_runner_override' settings can be set per-filter:
Nusiq Apr 26, 2026
9138f34
Merge pull request #356 from Bedrock-OSS/node-runner-override
stirante Apr 27, 2026
367634c
--unsafe + handle junctions + parallel sync directories
FrederoxDev Apr 27, 2026
f197c57
fix isSymlinkTo
FrederoxDev Apr 27, 2026
375cf4b
fix: syncLink
FrederoxDev Apr 27, 2026
806cbf9
junctions fixes
FrederoxDev Apr 27, 2026
b39d581
multiple export targets
dev-hydrogen Apr 30, 2026
bd4aa05
Moved the doc-comment of SyncDirectories() back to the function it be…
Nusiq Apr 30, 2026
dc2119b
Added some doc-comments.
Nusiq May 1, 2026
8d07d44
requested changes
FrederoxDev May 1, 2026
d1b2243
move getting the flag
FrederoxDev May 1, 2026
da620a5
Fixed tests.
Nusiq May 1, 2026
135aacd
Merge pull request #357 from FrederoxDev/improved-perf
Nusiq May 1, 2026
cff13a7
Generated CREDITS.csv
invalid-email-address May 1, 2026
dc1700b
Merge branch 'develop' into feature/multi-export-targets
dev-hydrogen May 1, 2026
2ad2741
export path collision check, use ExportTarget instead of ExportTarget…
dev-hydrogen May 11, 2026
5bb3169
Merge pull request #358 from dev-hydrogen/feature/multi-export-targets
Nusiq May 12, 2026
00f42c5
AI commit: Move experimental features out of experiments, make size_t…
Nusiq May 13, 2026
cb5fec9
AI commit: Use 'unified' version of the $schema instaead of a specifi…
Nusiq May 13, 2026
04a9848
Disabled the symlink_export feature in the TestInstallAndRun() test t…
Nusiq May 14, 2026
5692eb4
Moved repeated of the messages in --help into variables.
Nusiq May 14, 2026
f1c1247
Instead of removing the code related to experiments, leave it as a co…
Nusiq May 14, 2026
54b9512
Removed unnecessary special case for copying files into the tmp direc…
Nusiq May 14, 2026
72a088b
Merge pull request #360 from Bedrock-OSS/experiments-to-stable-2
Nusiq May 14, 2026
1138df3
Merge pull request #361 from Bedrock-OSS/unified-schema
Nusiq May 14, 2026
8d1df6e
Updated the data of tests failing due to the changes made to the conf…
Nusiq May 14, 2026
0feb26b
Fixed the node_runner_override selecting incorrect runner for the rem…
Nusiq May 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CREDITS.csv
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ go.uber.org/zap,https://github.com/uber-go/zap/blob/v1.23.0/LICENSE.txt,MIT
golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/v0.1.0:LICENSE,BSD-3-Clause
golang.org/x/exp,https://cs.opensource.google/go/x/exp/+/aae9b4e6:LICENSE,BSD-3-Clause
golang.org/x/mod/semver,https://cs.opensource.google/go/x/mod/+/v0.6.0:LICENSE,BSD-3-Clause
golang.org/x/sync,https://cs.opensource.google/go/x/sync/+/v0.8.0:LICENSE,BSD-3-Clause
golang.org/x/sync,https://cs.opensource.google/go/x/sync/+/v0.20.0:LICENSE,BSD-3-Clause
golang.org/x/sys/unix,https://cs.opensource.google/go/x/sys/+/v0.24.0:LICENSE,BSD-3-Clause
golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.6.0:LICENSE,BSD-3-Clause
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ require (
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/exp v0.0.0-20230131013936-aae9b4e6329d // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/text v0.6.0 // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down
69 changes: 46 additions & 23 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"fmt"
"os"
"strings"

"github.com/Bedrock-OSS/go-burrito/burrito"
"github.com/stirante/go-simple-eval/eval"
Expand Down Expand Up @@ -148,12 +147,14 @@ The behavior of the command changes based on the used flags and the number of pr
The cheatsheet below shows the possible combinations of flags and arguments and what they do:

Printing all properties: regolith config
Printing specified property: regolith config <key>
Setting property value: regolith config <key> <value>
Deleting a property: regolith config <key> --delete
Appending to a list property: regolith config <key> <value> --append
Replacing item in a list property: regolith config <key> <value> --index <index>
Deleting item in a list property: regolith config <key> --index <index> --delete
Printing specified property: regolith config <setting>
Setting property value: regolith config <setting> <value>
Deleting a property: regolith config <setting> --delete
Appending to a list property: regolith config <setting> <value> --append
Replacing item in a list property: regolith config <setting> <value> --index <index>
Deleting item in a list property: regolith config <setting> --index <index> --delete
Setting a value in a map property: regolith config <setting> <key> <value>
Deleting a value in a map property: regolith config <setting> <key> --delete

The printing commands can take the --full flag to print configuration with the default values
included (if they're not defined in the config file). Without the flag, the undefined properties
Expand Down Expand Up @@ -226,6 +227,7 @@ func main() {
rootCmd.PersistentFlags().StringVar(&envFile, "env", "", "Path to a custom .env file to load")

var force bool
forceDesc := "Force the operation, overriding potential safeguards."
// regolith init
cmdInit := &cobra.Command{
Use: "init",
Expand All @@ -237,10 +239,13 @@ func main() {
},
}
cmdInit.Flags().BoolVarP(
&force, "force", "f", false, "Force the operation, overriding potential safeguards.")
&force, "force", "f", false, forceDesc)
subcommands = append(subcommands, cmdInit)

profiles := []string{}
// Messages for common flags in 'regolith install' and 'regolith install-all'
forceFilterRefreshDesc := "Force filter cache refresh."

// regolith install
var update, resolverRefresh, filterRefresh bool
cmdInstall := &cobra.Command{
Expand All @@ -260,11 +265,11 @@ func main() {
},
}
cmdInstall.Flags().BoolVarP(
&force, "force", "f", false, "Force the operation, overriding potential safeguards.")
&force, "force", "f", false, forceDesc)
cmdInstall.Flags().BoolVar(
&resolverRefresh, "force-resolver-refresh", false, "Force resolvers refresh.")
cmdInstall.Flags().BoolVar(
&filterRefresh, "force-filter-refresh", false, "Force filter cache refresh.")
&filterRefresh, "force-filter-refresh", false, forceFilterRefreshDesc)
cmdInstall.Flags().BoolVarP(
&force, "update", "u", false, "An alias for --force flag. Use this flag to update filters.")
cmdInstall.Flags().StringSliceVarP(&profiles, "profile", "p", profiles, "Adds installed filters to the specified profiles. If no profile is provided, the filter will be added to the default profile.")
Expand All @@ -282,14 +287,20 @@ func main() {
},
}
cmdInstallAll.Flags().BoolVarP(
&force, "force", "f", false, "Force the operation, overriding potential safeguards.")
&force, "force", "f", false, forceDesc)
cmdInstallAll.Flags().BoolVarP(
&update, "update", "u", false, "Updates the remote filters to the latest stable version available.")
cmdInstallAll.Flags().BoolVar(
&filterRefresh, "force-filter-refresh", false, "Force filter cache refresh.")
&filterRefresh, "force-filter-refresh", false, forceFilterRefreshDesc)
subcommands = append(subcommands, cmdInstallAll)

// Messages for common flags in 'regolith run' and 'regolith watch'
unsafeDesc := "Disables file protection safety checks for faster exports."
symlinkExportDesc := "Creates links from the tmp directory to the export target so that files written to tmp are immediately reflected in the export location."
disableSizeTimeCheckDesc := "Disables the size and modification time check optimization for file exporting."

// regolith run
var symlinkExport, disableSizeTimeCheck bool
cmdRun := &cobra.Command{
Use: "run [profile_name]",
Short: "Runs Regolith using specified profile",
Expand All @@ -302,9 +313,15 @@ func main() {
extraFilterArgs = args[1:]
}
env, _ := cmd.Flags().GetString("env")
err = regolith.Run(profile, extraFilterArgs, burrito.PrintStackTrace, env)
unsafe, _ := cmd.Flags().GetBool("unsafe")
symlink, _ := cmd.Flags().GetBool("symlink-export")
disableStc, _ := cmd.Flags().GetBool("disable-size-time-check")
err = regolith.Run(profile, extraFilterArgs, burrito.PrintStackTrace, env, unsafe, symlink, disableStc)
},
}
cmdRun.Flags().Bool("unsafe", false, unsafeDesc)
cmdRun.Flags().BoolVar(&symlinkExport, "symlink-export", false, symlinkExportDesc)
cmdRun.Flags().BoolVar(&disableSizeTimeCheck, "disable-size-time-check", false, disableSizeTimeCheckDesc)
subcommands = append(subcommands, cmdRun)

// regolith watch
Expand All @@ -320,9 +337,15 @@ func main() {
extraFilterArgs = args[1:]
}
env, _ := cmd.Flags().GetString("env")
err = regolith.Watch(profile, extraFilterArgs, burrito.PrintStackTrace, env)
unsafe, _ := cmd.Flags().GetBool("unsafe")
symlink, _ := cmd.Flags().GetBool("symlink-export")
disableStc, _ := cmd.Flags().GetBool("disable-size-time-check")
err = regolith.Watch(profile, extraFilterArgs, burrito.PrintStackTrace, env, unsafe, symlink, disableStc)
},
}
cmdWatch.Flags().Bool("unsafe", false, unsafeDesc)
cmdWatch.Flags().BoolVar(&symlinkExport, "symlink-export", false, symlinkExportDesc)
cmdWatch.Flags().BoolVar(&disableSizeTimeCheck, "disable-size-time-check", false, disableSizeTimeCheckDesc)
subcommands = append(subcommands, cmdWatch)

// regolith apply-filter
Expand Down Expand Up @@ -394,20 +417,20 @@ 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")
}
// // 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(&regolith.EnableTimings, "timings", "", false, "Enables timing information")
cmd.Flags().StringSliceVar(
&regolith.EnabledExperiments, "experiments", nil,
"Enables experimental features. Currently supported experiments:\n"+
strings.Join(experimentDescs, "\n"))
// cmd.Flags().StringSliceVar(
// &regolith.EnabledExperiments, "experiments", nil,
// "Enables experimental features. Currently supported experiments:\n"+
// strings.Join(experimentDescs, "\n"))
}

// Build and run CLI
Expand Down
72 changes: 70 additions & 2 deletions regolith/config.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package regolith

import (
"encoding/json"
"fmt"

"github.com/Bedrock-OSS/go-burrito/burrito"
"golang.org/x/mod/semver"
)

const latestCompatibleVersion = "1.7.0"
const latestCompatibleVersion = "1.8.0"

const StandardLibraryUrl = "github.com/Bedrock-OSS/regolith-filters"
const ConfigFilePath = "config.json"
Expand Down Expand Up @@ -37,6 +38,37 @@ type ExportTarget struct {
Build string `json:"build,omitempty"` // The type of Minecraft build for the 'develop'
}

// ExportTargets is the config representation of a profile's "export" value.
// It accepts both the single-object form and the multi-target array
// form. When marshaling, a single target is written as an object to keep newly
// generated configs backward compatible with older Regolith versions.
type ExportTargets []ExportTarget

// IsZero lets json:",omitzero" omit an unset target list.
func (et ExportTargets) IsZero() bool {
return len(et) == 0
}

func (et ExportTargets) MarshalJSON() ([]byte, error) {
if len(et) == 1 {
return json.Marshal(et[0])
}
return json.Marshal([]ExportTarget(et))
}

func (et *ExportTargets) UnmarshalJSON(data []byte) error {
var raw any
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
targets, err := ExportTargetsFromObject(raw)
if err != nil {
return err
}
*et = targets
return nil
}

// Packs is a part of "config.json" that points to the source behavior and
// resource packs.
type Packs struct {
Expand Down Expand Up @@ -176,7 +208,7 @@ func RegolithProjectFromObject(
"object")
}
filterInstaller, err := FilterInstallerFromObject(
filterDefinitionName, filterDefinitionMap)
filterDefinitionName, filterDefinitionName, filterDefinitionMap)
if err != nil {
return result, burrito.WrapErrorf(
err, jsonPropertyParseError, "filterDefinitions")
Expand Down Expand Up @@ -207,6 +239,42 @@ func RegolithProjectFromObject(
return result, nil
}

// ExportTargetsFromObject parses the "export" value which can be either a
// single object (backward compatible) or an array of objects.
func ExportTargetsFromObject(exportValue any) (ExportTargets, error) {
switch v := exportValue.(type) {
case map[string]any:
et, err := ExportTargetFromObject(v)
if err != nil {
return nil, burrito.WrapErrorf(err, jsonPropertyParseError, "export")
}
return ExportTargets{et}, nil
case []any:
if len(v) == 0 {
return nil, burrito.WrappedErrorf(
"The \"export\" array must contain at least one entry")
}
targets := make(ExportTargets, 0, len(v))
for i, item := range v {
obj, ok := item.(map[string]any)
if !ok {
return nil, burrito.WrappedErrorf(
jsonPathTypeError, fmt.Sprintf("export->%d", i), "object")
}
et, err := ExportTargetFromObject(obj)
if err != nil {
return nil, burrito.WrapErrorf(
err, jsonPropertyParseError, fmt.Sprintf("export->%d", i))
}
targets = append(targets, et)
}
return targets, nil
default:
return nil, burrito.WrappedErrorf(
jsonPropertyTypeError, "export", "object or array")
}
}

// ExportTargetFromObject creates a "ExportTarget" object from
// map[string]interface{}
func ExportTargetFromObject(obj map[string]any) (ExportTarget, error) {
Expand Down
16 changes: 15 additions & 1 deletion regolith/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ const (
// Error used on attempt to access user config property that is not known
// to Regolith.
invalidUserConfigPropertyError = "Invalid user configuration property:\n" +
"Property name: %s\n"
"Property name: %s"

// Error used when the getGlobalUserConfigPath function fails
getGlobalUserConfigPathError = "Failed to get global user_config.json path"
Expand Down Expand Up @@ -259,6 +259,8 @@ const (
"Resource pack export path: %s\n" +
"Behavior pack export path: %s"

updatedFilesUpdateError = "Failed to create a list of files edited by Regolith."

updatedFilesDumpError = "Failed to update the list of the files edited by Regolith." +
"This may cause the next run to fail."

Expand All @@ -268,4 +270,16 @@ const (

loadEnvFileFromArgError = "Failed to the file with environment variables:\n" +
"File path: %s"

getAbsoluteWorkingDirectoryError = "Failed to get the absolute path of the working directory for filter execution."

// userSettingIncorrectIndexUseError is used when the user tries to use the --index flag with a non-array property
// when changing the user settings.
userSettingIncorrectIndexUseError = "Cannot use --index with non-array property."

// userSettingIncorrectKeyUseError is used when the user tries to use the --key flag with a non-map property
// when changing the user settings.
userSettingIncorrectKeyUseError = "Cannot use <key> with non-map property."

getRunnerError = "Failed to get the path to filter runner."
)
26 changes: 1 addition & 25 deletions regolith/experiments.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,12 @@ import "slices"

type Experiment int

const (
// SizeTimeCheck is an experiment that checks the size and modification time when exporting
SizeTimeCheck Experiment = iota
// SymlinkExport links the temporary build directory with the export
// target using hard links when possible.
SymlinkExport
)

// 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.
`

const symlinkExportDesc = `
Creates links from the tmp directory to the export target so that files
written to tmp are immediately reflected in the export location.`

type ExperimentInfo struct {
Name string
Description string
}

var AvailableExperiments = map[Experiment]ExperimentInfo{
SizeTimeCheck: {"size_time_check", sizeTimeCheckDesc},
SymlinkExport: {"symlink_export", symlinkExportDesc},
}
var AvailableExperiments = map[Experiment]ExperimentInfo{}

var EnabledExperiments []string

Expand Down
Loading
Loading