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 built 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 //third_party/go:assert //third_party/go:_assert-assert#download
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's that
//third_party/go:_assert-assert#download target we just saw? That's an internal rule that was generated by the
//third_party/go:assert. Internal rules can be identified by their leading
_ in their name. We can view more information about this one with
plz query print:
$ plz query print //third_party/go:_assert-assert#download # //third_party/go:_assert-assert#download: remote_file( name = '_assert-assert#download', srcs = ['https://github.com/go-playground/assert/archive/v1.2.1.zip'], outs = ['assert-assert.zip'], building_description = 'Fetching...', timeout = 600, config = 'None', visibility = ['PUBLIC'], )
As we can see,
go_get() has generated a remote file rule to download the github archive of the sources for that go module! You shouldn't depend on these rules directly as they may change between minor releases of Please.
Most of the
plz query sub-commands have a
--hidden flag that can be used to include hidden targets:
$ plz query alltargets --hidden //src:_main#lib //src:_main#lib_srcs //src:main //src/greetings:_greetings#import_config //src/greetings:_greetings#srcs //src/greetings:_greetings_test#lib //src/greetings:_greetings_test#lib_srcs //src/greetings:_greetings_test#main //src/greetings:_greetings_test#main_lib //src/greetings:_greetings_test#main_lib_srcs //src/greetings:greetings //src/greetings:greetings_test //third_party/go:_assert#a_rule //third_party/go:_assert#get //third_party/go:_assert#import_config //third_party/go:_assert-assert#download //third_party/go:assert
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 internal download rule:
$ plz query revdeps //third_party/go:_assert-assert#download //third_party/go:assert
Well that doesn't look quite right... We should see
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
$ plz query revdeps --level=-1 //third_party/go:_assert-assert#download //src/greetings:greetings_test //third_party/go:assert
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 that targets that might be effected by our change. How do we run these tests? Please can be instructed to listen for targets on standard input:
$ plz query revdeps --level=-1 //third_party/go:_assert-assert#download | plz test - //src/greetings:greetings_test 1 test run in 0s; 1 passed [cached] 1 test target and 1 test run; 1 passed. Total time: 110ms real, 0s compute.
- 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
--exclude arguments. These can be used to specifically exclude targets:
$ plz query revdeps --exclude //src/greetings:greetings_test --level=-1 //third_party/go:_assert-assert#download | 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:_assert-assert#download | 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:
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 --unclude=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!