Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 10 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ jobs:
build-alpine:
working_directory: ~/please
docker:
- image: ghcr.io/thought-machine/please_alpine:20250318
- image: ghcr.io/thought-machine/please_alpine:20260318
resource_class: large
environment:
PLZ_ARGS: "--profile ci --profile alpine --exclude no-musl"
Expand Down Expand Up @@ -43,7 +43,7 @@ jobs:
build-linux:
working_directory: ~/please
docker:
- image: ghcr.io/thought-machine/please_ubuntu:20250318
- image: ghcr.io/thought-machine/please_ubuntu:20260318
resource_class: large
environment:
PLZ_ARGS: "--profile ci"
Expand Down Expand Up @@ -91,7 +91,7 @@ jobs:
build-linux-alt:
working_directory: ~/please
docker:
- image: ghcr.io/thought-machine/please_ubuntu_alt:20250318
- image: ghcr.io/thought-machine/please_ubuntu_alt:20260318
resource_class: large
environment:
PLZ_ARGS: "-c cover --profile ci-alt"
Expand Down Expand Up @@ -154,7 +154,7 @@ jobs:
build-freebsd:
working_directory: ~/please
docker:
- image: ghcr.io/thought-machine/please_freebsd_builder:20250318
- image: ghcr.io/thought-machine/please_freebsd_builder:20260318
resource_class: large
steps:
- checkout
Expand All @@ -180,7 +180,7 @@ jobs:
build-linux-arm64:
working_directory: ~/please
docker:
- image: ghcr.io/thought-machine/please_ubuntu:20250318
- image: ghcr.io/thought-machine/please_ubuntu:20260318
resource_class: large
steps:
- checkout
Expand Down Expand Up @@ -250,7 +250,7 @@ jobs:
test-rex:
working_directory: ~/please
docker:
- image: ghcr.io/thought-machine/please_ubuntu:20250318
- image: ghcr.io/thought-machine/please_ubuntu:20260318
resource_class: xlarge
steps:
- checkout
Expand All @@ -267,7 +267,7 @@ jobs:
test-http-cache:
working_directory: ~/please
docker:
- image: ghcr.io/thought-machine/please_ubuntu:20250318
- image: ghcr.io/thought-machine/please_ubuntu:20260318
resource_class: large
steps:
- checkout
Expand All @@ -283,7 +283,7 @@ jobs:
# Releases to github and homebrew
release:
docker:
- image: ghcr.io/thought-machine/please_ubuntu:20250318
- image: ghcr.io/thought-machine/please_ubuntu:20260318
environment:
GOOGLE_APPLICATION_CREDENTIALS=/tmp/service_account.json
steps:
Expand All @@ -298,7 +298,7 @@ jobs:
# Releases the docs and the binaries to gs for please.build and get.please.build
release-gs:
docker:
- image: ghcr.io/thought-machine/please_ubuntu:20250318
- image: ghcr.io/thought-machine/please_ubuntu:20260318
environment:
GOOGLE_APPLICATION_CREDENTIALS=/tmp/service_account.json
steps:
Expand All @@ -310,7 +310,7 @@ jobs:
# Runs a benchmarking test and records some performance results.
perf-test:
docker:
- image: ghcr.io/thought-machine/please_ubuntu:20250318
- image: ghcr.io/thought-machine/please_ubuntu:20260318
environment:
GOOGLE_APPLICATION_CREDENTIALS=/tmp/service_account.json
resource_class: xlarge # Want to run these tests with a significant amount of parallelism
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '^1.24'
go-version: '^1.26'
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: v2.2
version: v2.11
2 changes: 1 addition & 1 deletion docs/codelabs/using_plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ help [language]`.
```python
plugin_repo(
name = "go",
revision = "v1.17.2",
revision = "v1.29.0",
plugin = "go-rules",
owner = "please-build",
)
Expand Down
3 changes: 2 additions & 1 deletion docs/tools/plugin_config_tool/plugin_config_tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ func getRules(buildDefsDirs []string) *rules.Rules {
}
}

args := []string{"--noupdate", "query", "rules"}
args := make([]string, 0, 3+len(defs))
args = append(args, []string{"--noupdate", "query", "rules"}...)
cmd := exec.Command(opts.Please, append(args, defs...)...)
var outb, errb bytes.Buffer
cmd.Stdout = &outb
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/thought-machine/please

go 1.24.0
go 1.26.1

require (
cloud.google.com/go/longrunning v0.5.5
Expand Down
6 changes: 3 additions & 3 deletions plugins/BUILD
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugin_repo(
name = "go",
plugin = "go-rules",
revision = "v1.21.5",
revision = "v1.29.0",
)

plugin_repo(
Expand All @@ -13,11 +13,11 @@ plugin_repo(
plugin_repo(
name = "shell",
plugin = "shell-rules",
revision = "v0.1.1",
revision = "v0.2.1",
)

plugin_repo(
name = "python",
plugin = "python-rules",
revision = "v1.7.4",
revision = "v1.14.0",
)
13 changes: 8 additions & 5 deletions src/cli/suggest.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cli

import (
"sort"
"strings"

"github.com/texttheater/golang-levenshtein/levenshtein"
)
Expand Down Expand Up @@ -32,18 +33,20 @@ func PrettyPrintSuggestion(needle string, haystack []string, maxSuggestionDistan
return ""
}
// Obviously there's now more code to pretty-print the suggestions than to do the calculation...
msg := "\nMaybe you meant "
var msgBuilder strings.Builder
msgBuilder.WriteString("\nMaybe you meant ")
for i, o := range options {
if i > 0 {
if i < len(options)-1 {
msg += " , " // Leave a space before the comma so you can select them without getting the question mark
msgBuilder.WriteString(" , ") // Leave a space before the comma so you can select them without getting the question mark
} else {
msg += " or "
msgBuilder.WriteString(" or ")
}
}
msg += o
msgBuilder.WriteString(o)
}
return msg + " ?" // Leave a space so you can select them without getting the question mark
msgBuilder.WriteString(" ?") // Leave a space so you can select them without getting the question mark
return msgBuilder.String()
}

type suggestion struct {
Expand Down
2 changes: 1 addition & 1 deletion src/core/build_target.go
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ func (target *BuildTarget) SourcePaths(graph *BuildGraph, sources []BuildInput)
// sourcePaths returns the source paths for a single source.
func (target *BuildTarget) sourcePaths(graph *BuildGraph, source BuildInput, f buildPathsFunc) []string {
if label, ok := source.nonOutputLabel(); ok {
ret := []string{}
var ret []string // nolint:prealloc
for _, providedLabel := range graph.TargetOrDie(label).ProvideFor(target) {
ret = append(ret, f(providedLabel, graph)...)
}
Expand Down
21 changes: 10 additions & 11 deletions src/core/command_replacements.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ func checkAndReplaceSequence(state *BuildState, target, dep *BuildTarget, ep, in
}
return base64.RawURLEncoding.EncodeToString(h)
}
output := ""
var outputBuilder strings.Builder
if ep == "" {
for _, out := range dep.Outputs() {
if allOutputs || out == in {
Expand All @@ -266,24 +266,23 @@ func checkAndReplaceSequence(state *BuildState, target, dep *BuildTarget, ep, in
if err != nil {
log.Fatalf("Couldn't calculate relative path: %s", err)
}
output += quote(abs) + " "
outputBuilder.WriteString(quote(abs))
} else {
output += quote(fileDestination(target, dep, out, dir, outPrefix, test)) + " "
outputBuilder.WriteString(quote(fileDestination(target, dep, out, dir, outPrefix, test)))
}
outputBuilder.WriteString(" ")
if dir {
break
}
}
}
} else {
out, ok := dep.EntryPoints[ep]
if !ok {
log.Fatalf("%v has no entry point %s", dep, ep)
}
output = quote(fileDestination(target, dep, out, dir, outPrefix, test))
return strings.TrimRight(outputBuilder.String(), " ")
}

return strings.TrimRight(output, " ")
out, ok := dep.EntryPoints[ep]
if !ok {
log.Fatalf("%v has no entry point %s", dep, ep)
}
return quote(fileDestination(target, dep, out, dir, outPrefix, test))
}

func fileDestination(target, dep *BuildTarget, out string, dir, outPrefix, test bool) string {
Expand Down
4 changes: 2 additions & 2 deletions src/core/cycle_detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ type errCycle struct {
}

func (err *errCycle) Error() string {
labels := make([]string, len(err.Cycle))
labels := make([]string, len(err.Cycle)+1)
for i, t := range err.Cycle {
labels[i] = t.Label.String()
}
labels = append(labels, labels[0])
labels[len(labels)-1] = labels[0]
return fmt.Sprintf("Dependency cycle found:\n%s\nSorry, but you'll have to refactor your build files to avoid this cycle", strings.Join(labels, "\n -> "))
}
26 changes: 14 additions & 12 deletions src/help/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func formatPluginHelpMessage(message, description, docSite string, options map[s
if docSite != "" {
message += "\n" + docSite + "\n"
}
configOptions := ""
var configOptionsBuilder strings.Builder
for k, v := range options {
valueType := v.Type
if v.Type == "" {
Expand Down Expand Up @@ -210,31 +210,33 @@ func formatPluginHelpMessage(message, description, docSite string, options map[s
if def != "" {
def = " (" + def + ")"
}
configOptions += fmt.Sprintf("${BLUE} %s${RESET} ${GREEN}(%s)${RESET}${WHITE}%s${RESET} %s\n",
_, _ = fmt.Fprintf(&configOptionsBuilder, "${BLUE} %s${RESET} ${GREEN}(%s)${RESET}${WHITE}%s${RESET} %s\n",
key,
valueType,
def,
v.Help)
}
if configOptions != "" {
message += "\n${BOLD_YELLOW}This plugin has the following options:${RESET}\n" + configOptions
if configOptionsBuilder.Len() != 0 {
message += "\n${BOLD_YELLOW}This plugin has the following options:${RESET}\n" + configOptionsBuilder.String()
}

buildDefs := ""
var buildDefsBuilder strings.Builder
for k, v := range buildRulesMap {
buildDefs += fmt.Sprintf("${BLUE} %v${RESET}", strings.ToLower(k))
arglist := "("
_, _ = fmt.Fprintf(&buildDefsBuilder, "${BLUE} %v${RESET}", strings.ToLower(k))
var argListBuilder strings.Builder
argListBuilder.WriteString("(")
for i, arg := range v.FuncDef.Arguments {
argListBuilder.WriteString(arg.Name)
if i != len(v.FuncDef.Arguments)-1 {
arglist += arg.Name + ", "
argListBuilder.WriteString(", ")
} else {
arglist += arg.Name + ")"
argListBuilder.WriteString(")")
}
}
buildDefs += fmt.Sprintf("${GREEN}%v${RESET}\n", arglist)
_, _ = fmt.Fprintf(&buildDefsBuilder, "${GREEN}%v${RESET}\n", argListBuilder.String())
}
if buildDefs != "" {
message += "\n${BOLD_YELLOW}And provides the following build defs:${RESET}\n" + buildDefs
if buildDefsBuilder.Len() != 0 {
message += "\n${BOLD_YELLOW}And provides the following build defs:${RESET}\n" + buildDefsBuilder.String()
}

return message
Expand Down
10 changes: 5 additions & 5 deletions src/output/shell_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,16 +630,16 @@ var errorMessageRe = deferredregex.DeferredRegex{Re: `^([^ ]+\.[^: /]+):([0-9]+)

// unbuiltTargetsMessage returns a message for any targets that are supposed to build but haven't yet.
func unbuiltTargetsMessage(graph *core.BuildGraph) string {
msg := ""
var msgBuilder strings.Builder
for _, target := range graph.AllTargets() {
if target.State() == core.Active {
msg += fmt.Sprintf(" %s", target.Label)
_, _ = fmt.Fprintf(&msgBuilder, " %s", target.Label)
} else if target.State() == core.Pending {
msg += fmt.Sprintf(" %s (pending build)\n", target.Label)
_, _ = fmt.Fprintf(&msgBuilder, " %s (pending build)\n", target.Label)
}
}
if msg != "" {
return "\nThe following targets have not yet built:\n" + msg
if msgBuilder.Len() == 0 {
return "\nThe following targets have not yet built:\n" + msgBuilder.String()
}
return ""
}
Expand Down
6 changes: 3 additions & 3 deletions src/parse/asp/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -881,14 +881,14 @@ func mapFunc(s *scope, args []pyObject) pyObject {
s.Assert(isFunc, "Argument mapper must be callable, not %s", args[0].Type())
s.Assert(isList, "Argument seq must be a list, not %s", args[1].Type())

var ret pyList
for _, li := range l {
ret := make(pyList, len(l))
for i, li := range l {
c := &Call{
Arguments: []CallArgument{{
Value: Expression{optimised: &optimisedExpression{Constant: li}},
}},
}
ret = append(ret, mapper.Call(s, c))
ret[i] = mapper.Call(s, c)
}
return ret
}
Expand Down
9 changes: 5 additions & 4 deletions src/remote/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ func (c *Client) buildCommand(target *core.BuildTarget, inputRoot *pb.Directory,
}
// We can't predict what variables like this should be so we sneakily bung something on
// the front of the command. It'd be nicer if there were a better way though...
var commandPrefix = "export TMP_DIR=\"`pwd`\" && export HOME=$TMP_DIR && "
var commandPrefixBuilder strings.Builder
commandPrefixBuilder.WriteString("export TMP_DIR=\"`pwd`\" && export HOME=$TMP_DIR && ")

// Similarly, we need to export these so that things like $TMP_DIR get expanded correctly.
if len(target.Env) > 0 {
Expand All @@ -100,13 +101,13 @@ func (c *Client) buildCommand(target *core.BuildTarget, inputRoot *pb.Directory,
}
sort.Strings(keys)
for _, k := range keys {
commandPrefix += fmt.Sprintf("export %s=%s && ", k, shellescape.Quote(target.Env[k]))
_, _ = fmt.Fprintf(&commandPrefixBuilder, "export %s=%s && ", k, shellescape.Quote(target.Env[k]))
}
}

outs := target.AllOutputs()
if len(target.Outputs()) == 1 { // $OUT is relative when running remotely; make it absolute
commandPrefix += `export OUT="$TMP_DIR/$OUT" && `
commandPrefixBuilder.WriteString(`export OUT="$TMP_DIR/$OUT" && `)
}
if target.IsRemoteFile {
// Synthesize something for the Command proto. We never execute this, but it does get hashed for caching
Expand All @@ -127,7 +128,7 @@ func (c *Client) buildCommand(target *core.BuildTarget, inputRoot *pb.Directory,
cmd, err := core.ReplaceSequences(state, target, cmd)
return &pb.Command{
Platform: c.targetPlatformProperties(target),
Arguments: process.BashCommand(c.shellPath, commandPrefix+cmd, state.Config.Build.ExitOnError),
Arguments: process.BashCommand(c.shellPath, commandPrefixBuilder.String()+cmd, state.Config.Build.ExitOnError),
EnvironmentVariables: c.buildEnv(target, c.stampedBuildEnvironment(state, target, inputRoot, stamp, isTest || isRun), target.Sandbox),
OutputPaths: outs,
}, err
Expand Down
Loading
Loading