This codelab isn't exhaustive however it should give you an idea of the sort of things the Please CLI is capable of:
For this codelab we will be using the Please codelabs repo:
$ git clone https://github.com/thought-machine/please-codelabs
Cloning into 'please-examples'...
remote: Enumerating objects: 228, done.
remote: Total 228 (delta 0), reused 0 (delta 0), pack-reused 228
Receiving objects: 100% (228/228), 38.23 KiB | 543.00 KiB/s, done.
Resolving deltas: 100% (79/79), done.
We'll be using the getting started with go codelab for these examples:
cd please-codelabs/getting_started_go
Please has a strict build graph representing each build target and their dependencies on each other. Among many things, this graph can be interrogated to determine the dependencies of a target:
$ plz query deps //src/greetings:greetings_test
//src/greetings:greetings_test
//src/greetings:greetings
///go//tools:please_go
//plugins:go
//_please:arcat
//third_party/go:toolchain
//third_party/go:testify
///third_party/go/github.com_stretchr_testify//:installs
///third_party/go/github.com_stretchr_testify//assert:assert
///third_party/go/github.com_davecgh_go-spew//spew:spew
//third_party/go:github.com_davecgh_go-spew
///third_party/go/github.com_pmezard_go-difflib//difflib:difflib
//third_party/go:github.com_pmezard_go-difflib
///third_party/go/gopkg.in_yaml.v3//:yaml.v3
//third_party/go:gopkg.in_yaml.v3
///third_party/go/github.com_stretchr_testify//require:require
This can be especially useful when trying to improve build performance. Unnecessary dependencies between targets can cause certain rules to be rebuilt when they don't need to be.
Woah, what are these ///third_party/go/foo//:bar
targets? Targets that begin with a ///
are subrepo targets. In this case, the third-party dependency testify has been defined using a go_repo()
rule, which downloads the go module into plz-out, generates Please BUILD files for each of its packages, and then builds it like any other Please project. So ///third_party/go/github.com_stretchr_testify//assert:assert
is saying "look in the subrepo called third_party/go/github.com_stretchr_testify, and retrieve for me the build target //assert:assert
.
You can plz query print
these targets just like you would any other target:
plz query print ///third_party/go/github.com_stretchr_testify//assert:assert
This will show you the underlying build rule for that target. Or, if you prefer, you could have a look in the plz-out directory at the generated build rule:
$ cat plz-out/subrepos/third_party/go/github.com_stretchr_testify/assert/BUILD
subinclude("///go//build_defs:go")
go_library(
name = "assert",
srcs = [
"assertion_compare.go",
"assertion_compare_can_convert.go",
"assertion_format.go",
"assertion_forward.go",
"assertion_order.go",
"assertions.go",
"doc.go",
"errors.go",
"forward_assertions.go",
"http_assertions.go",
],
visibility = ["PUBLIC"],
deps = [
"///third_party/go/github.com_davecgh_go-spew//spew",
"///third_party/go/github.com_pmezard_go-difflib//difflib",
"///third_party/go/gopkg.in_yaml.v3//:yaml.v3",
],
)
If you pass the --hidden
flag to a plz query
command, you'll come across internal targets as well. These can be identified by the leading _
in their name. E.g.
$ plz query deps //src/greetings:greetings --hidden
//src/greetings:greetings
//src/greetings:_greetings#import_config
//src/greetings:_greetings#pkg_info
///go//tools:please_go
//plugins:go
//_please:arcat
//plugins:_go#download
//src/greetings:_greetings#srcs
//third_party/go:toolchain
//third_party/go:_toolchain#download
As always, we can inspect these with plz query print
, e.g.
$ plz query print //src/greetings:_greetings#srcs
# //src/greetings:_greetings#srcs:
filegroup(
name = '_greetings#srcs',
srcs = ['greetings.go'],
labels = [
'link:plz-out/go/src/${PKG}',
'go_src',
'go',
],
visibility = ['//src/...'],
build_timeout = 600,
requires = ['go'],
)
This particular internal rule is a filegroup that was generated by go_library()
and is used to expose the Go source files that make up that library. You shouldn't depend on these types of rules directly as they may change between minor releases of Please.
If you're changing a build rule that you know has a wide-reaching effect, it might be good to run all the tests that will be affected by that change. Let's find the reverse dependencies of our subrepo rules:
$ plz query revdeps ///third_party/go/github.com_stretchr_testify//require:require
///third_party/go/github.com_stretchr_testify//:installs
Well that doesn't look quite right... We should see //src/greetings:greetings_test
too.
Turns out finding reverse dependencies is quite a slow operation. Please limits this to just one level so you don't accidentally lock up your terminal trying to walk the whole build graph. You can set the level with --level=2
or if you want to get all reverse dependencies, you can set it to -1
:
$ plz query revdeps ///third_party/go/github.com_stretchr_testify//require:require --level -1
//src/greetings:greetings_test
//third_party/go:testify
///third_party/go/github.com_stretchr_testify//:installs
Be careful, this can be slow on larger build graphs. You can use --include=//src/foo/...
to limit the search to a slice of your repository. More on this later in this codelab!
So we've managed to determine which targets will be affected by our change. How do we run these tests? Please can be instructed to listen for targets on standard input:
$ plz query revdeps ///third_party/go/github.com_stretchr_testify//require:require --level -1 | plz test -
//src/greetings:greetings_test 1 test run in 8ms; 1 passed
1 test target and 1 test run; 1 passed.
Total time: 6.62s real, 10ms compute.
The -
at the end of plz test -
indicates to Please that we will be supplying the targets to build over standard input.
Almost all Please commands can take in the --include
and --exclude
arguments. These can be used to specifically exclude targets:
$ plz query revdeps --exclude //src/greetings:greetings_test --level=-1 ///third_party/go/github.com_stretchr_testify//require:require | plz test -
0 test targets and 0 tests run; 0 passed.
Total time: 40ms real, 0s compute.
As you can see, we excluded the test from earlier so plz test
didn't run it. We can also exclude this on the test command:
$ plz query revdeps --level=-1 ///third_party/go/github.com_stretchr_testify//require:require | plz test --exclude //src/greetings:greetings_test -
0 test targets and 0 tests run; 0 passed.
Total time: 40ms real, 0s compute.
Targets can be labeled in Please. Most of the built-in rules apply some basic labels, e.g. the Go rules apply the go
label to their targets. These can be very useful to run all tests for a given language:
plz build --include go --exclude //third_party/go/...
This will build all Go targets but will only build targets under //third_party/go/...
if they're a dependency of a target that needs to be built.
You may also add custom labels to your targets. Update srcs/greetings/BUILD
as such:
src/greetings/BUILD
go_library(
name = "greetings",
srcs = ["greetings.go"],
visibility = ["//src/..."],
labels = ["my_label"], # Add a label to the library rule
)
go_test(
name = "greetings_test",
srcs = ["greetings_test.go"],
deps = [
":greetings",
"//third_party/go:assert",
],
external = True,
)
$ plz query alltargets --include=my_label
//src/greetings:greetings
$ plz build --include=my_label
Build finished; total time 300ms, incrementality 100.0%. Outputs:
//src/greetings:greetings:
plz-out/gen/src/greetings/greetings.a
This can be especially useful for separating out slow running tests:
plz test --exclude e2e
Hopefully this has given you a taster for what is possible with plz query
, however there's so much more. See the cli for an idea of what's possible!