diff --git a/docs/config.html b/docs/config.html
index 021d0798f..d1d86f38e 100644
--- a/docs/config.html
+++ b/docs/config.html
@@ -1211,6 +1211,24 @@
TimeoutName
+
+
+
+
+ -
+
+
+
+
+ Shortens absolute labels to relative when running plz format if the label is in the same package as the associated target.
+
+
+
+
+
+
[Test]
diff --git a/src/core/config.go b/src/core/config.go
index b6fc6e260..0e035a53f 100644
--- a/src/core/config.go
+++ b/src/core/config.go
@@ -546,6 +546,9 @@ type Configuration struct {
StoreCommand string `help:"Use a custom command to store cache entries."`
RetrieveCommand string `help:"Use a custom command to retrieve cache entries."`
} `help:"Please has several built-in caches that can be configured in its config file.\n\nThe simplest one is the directory cache which by default is written into the .plz-cache directory. This allows for fast retrieval of code that has been built before (for example, when swapping Git branches).\n\nThere is also a remote RPC cache which allows using a centralised server to store artifacts. A typical pattern here is to have your CI system write artifacts into it and give developers read-only access so they can reuse its work.\n\nFinally there's a HTTP cache which is very similar, but a little obsolete now since the RPC cache outperforms it and has some extra features. Otherwise the two have similar semantics and share quite a bit of implementation.\n\nPlease has server implementations for both the RPC and HTTP caches."`
+ Format struct {
+ ShortenAbsoluteLabelsToRelative bool `help:"Shortens absolute labels to relative if the label is in the same package as the associated target."`
+ } `help:"A config section describing settings related to the 'format' sub command."`
Test struct {
Timeout cli.Duration `help:"Default timeout applied to all tests. Can be overridden on a per-rule basis."`
DisableCoverage []string `help:"Disables coverage for tests that have any of these labels spcified."`
diff --git a/src/format/BUILD b/src/format/BUILD
index 1a6fbed01..919ff2b03 100644
--- a/src/format/BUILD
+++ b/src/format/BUILD
@@ -5,6 +5,7 @@ go_library(
visibility = ["//src/..."],
deps = [
"///third_party/go/github.com_please-build_buildtools//build",
+ "///third_party/go/github.com_please-build_buildtools//tables",
"///third_party/go/golang.org_x_sync//errgroup",
"//src/cli/logging",
"//src/core",
diff --git a/src/format/fmt.go b/src/format/fmt.go
index 3f4d43856..8ea466bb4 100644
--- a/src/format/fmt.go
+++ b/src/format/fmt.go
@@ -11,6 +11,7 @@ import (
"sync/atomic"
"github.com/please-build/buildtools/build"
+ "github.com/please-build/buildtools/tables"
"golang.org/x/sync/errgroup"
"github.com/thought-machine/please/src/cli/logging"
@@ -27,7 +28,7 @@ var log = logging.Log
// The returned bool is true if any changes were needed.
func Format(config *core.Configuration, filenames []string, rewrite, quiet bool) (bool, error) {
if len(filenames) == 0 {
- return formatAll(plz.FindAllBuildFiles(config, core.RepoRoot, ""), config.Please.NumThreads, rewrite, quiet)
+ return formatAll(config, plz.FindAllBuildFiles(config, core.RepoRoot, ""), rewrite, quiet)
}
ch := make(chan string)
go func() {
@@ -36,17 +37,17 @@ func Format(config *core.Configuration, filenames []string, rewrite, quiet bool)
}
close(ch)
}()
- return formatAll(ch, config.Please.NumThreads, rewrite, quiet)
+ return formatAll(config, ch, rewrite, quiet)
}
-func formatAll(filenames <-chan string, parallelism int, rewrite, quiet bool) (bool, error) {
+func formatAll(config *core.Configuration, filenames <-chan string, rewrite, quiet bool) (bool, error) {
var changed int64
var g errgroup.Group
- g.SetLimit(parallelism)
+ g.SetLimit(config.Please.NumThreads)
for filename := range filenames {
filename := filename
g.Go(func() error {
- c, err := format(filename, rewrite, quiet)
+ c, err := format(config, filename, rewrite, quiet)
if c {
atomic.AddInt64(&changed, 1)
}
@@ -57,7 +58,7 @@ func formatAll(filenames <-chan string, parallelism int, rewrite, quiet bool) (b
return changed > 0, err
}
-func format(filename string, rewrite, quiet bool) (bool, error) {
+func format(config *core.Configuration, filename string, rewrite, quiet bool) (bool, error) {
before, err := os.ReadFile(filename)
if err != nil {
return true, err
@@ -67,7 +68,19 @@ func format(filename string, rewrite, quiet bool) (bool, error) {
return true, err
}
simplify(f)
- after := build.Format(f)
+ after := build.FormatWithRewriter(
+ &build.Rewriter{
+ IsLabelArg: tables.IsLabelArg,
+ LabelDenyList: tables.LabelDenylist,
+ IsSortableListArg: tables.IsSortableListArg,
+ SortableDenylist: tables.SortableDenylist,
+ SortableAllowlist: tables.SortableAllowlist,
+ NamePriority: tables.NamePriority,
+ StripLabelLeadingSlashes: tables.StripLabelLeadingSlashes,
+ ShortenAbsoluteLabelsToRelative: config.Format.ShortenAbsoluteLabelsToRelative,
+ },
+ f,
+ )
if bytes.Equal(before, after) {
log.Debug("%s is already in canonical format", filename)
return false, nil
diff --git a/src/format/fmt_test.go b/src/format/fmt_test.go
index dc120b40d..c327cbcfc 100644
--- a/src/format/fmt_test.go
+++ b/src/format/fmt_test.go
@@ -17,18 +17,30 @@ const testDir = "src/format/test_data"
func TestFormat(t *testing.T) {
files, err := os.ReadDir(testDir)
assert.NoError(t, err)
+
+ patchConfigByFile := map[string]func(*core.Configuration) {
+ "shorten_labels": func(c *core.Configuration) {
+ c.Format.ShortenAbsoluteLabelsToRelative = true
+ },
+ }
+
for _, file := range files {
if test, isBefore := strings.CutSuffix(file.Name(), ".before.build"); isBefore {
t.Run(test, func(t *testing.T) {
before := filepath.Join(testDir, test+".before.build")
after := filepath.Join(testDir, test+".after.build")
- changed, err := Format(core.DefaultConfiguration(), []string{before}, false, true)
+ config := core.DefaultConfiguration()
+ if patchConfig := patchConfigByFile[test]; patchConfig != nil {
+ patchConfig(config)
+ }
+
+ changed, err := Format(config, []string{before}, false, true)
assert.NoError(t, err)
assert.True(t, changed)
// N.B. this rewrites the file; be careful if you're adding more tests here.
- changed, err = Format(core.DefaultConfiguration(), []string{before}, true, false)
+ changed, err = Format(config, []string{before}, true, false)
assert.NoError(t, err)
assert.True(t, changed)
diff --git a/src/format/test_data/shorten_labels.after.build b/src/format/test_data/shorten_labels.after.build
new file mode 100644
index 000000000..e1895664d
--- /dev/null
+++ b/src/format/test_data/shorten_labels.after.build
@@ -0,0 +1,7 @@
+go_library(
+ name = "name",
+ srcs = [
+ "src.go",
+ ],
+ deps = [":test_data"],
+)
diff --git a/src/format/test_data/shorten_labels.before.build b/src/format/test_data/shorten_labels.before.build
new file mode 100644
index 000000000..8ad091dfd
--- /dev/null
+++ b/src/format/test_data/shorten_labels.before.build
@@ -0,0 +1,14 @@
+go_library(
+ name = "name",
+ srcs = [
+ "src.go",
+ ],
+ deps = [
+ "//src/format/test_data:test_data",
+ "//src/format/test_data:test_data",
+ "//src/format/test_data",
+ "//src/format/test_data",
+ ":test_data",
+ ":test_data",
+ ],
+)
diff --git a/src/format/test_data/shorten_labels_no_config.after.build b/src/format/test_data/shorten_labels_no_config.after.build
new file mode 100644
index 000000000..c0c218cb9
--- /dev/null
+++ b/src/format/test_data/shorten_labels_no_config.after.build
@@ -0,0 +1,10 @@
+go_library(
+ name = "name",
+ srcs = [
+ "src.go",
+ ],
+ deps = [
+ ":test_data",
+ "//src/format/test_data",
+ ],
+)
diff --git a/src/format/test_data/shorten_labels_no_config.before.build b/src/format/test_data/shorten_labels_no_config.before.build
new file mode 100644
index 000000000..8ad091dfd
--- /dev/null
+++ b/src/format/test_data/shorten_labels_no_config.before.build
@@ -0,0 +1,14 @@
+go_library(
+ name = "name",
+ srcs = [
+ "src.go",
+ ],
+ deps = [
+ "//src/format/test_data:test_data",
+ "//src/format/test_data:test_data",
+ "//src/format/test_data",
+ "//src/format/test_data",
+ ":test_data",
+ ":test_data",
+ ],
+)