Lệnh aquery
cho phép bạn truy vấn các hành động trong biểu đồ bản dựng.
Hoạt động trên Biểu đồ mục tiêu được định cấu hình sau khi phân tích và hiển thị
thông tin về Hành động, Cấu phần phần mềm và mối quan hệ của chúng.
aquery
rất hữu ích khi bạn quan tâm đến các thuộc tính của Thao tác/Cấu phần phần mềm
được tạo từ Biểu đồ mục tiêu đã định cấu hình. Ví dụ: các lệnh thực tế chạy
và đầu vào/đầu ra/bộ nhớ của chúng.
Công cụ này chấp nhận một số tuỳ chọn dòng lệnh. Đáng chú ý là lệnh aquery chạy trên bản dựng Bazel thông thường và kế thừa tập hợp các tuỳ chọn có sẵn trong quá trình tạo bản dựng.
API này hỗ trợ cùng một tập hợp chức năng cũng có sẵn cho các dịch vụ truyền thống
query
nhưng siblings
, buildfiles
và
tests
.
Ví dụ về kết quả aquery
(không có thông tin chi tiết cụ thể):
$ bazel aquery 'deps(//some:label)' action 'Writing file some_file_name' Mnemonic: ... Target: ... Configuration: ... ActionKey: ... Inputs: [...] Outputs: [...]
Cú pháp cơ bản
Sau đây là ví dụ đơn giản về cú pháp cho aquery
:
bazel aquery "aquery_function(function(//target))"
Biểu thức truy vấn (trong dấu ngoặc kép) bao gồm:
aquery_function(...)
: các hàm dành riêng choaquery
. Hãy xem thêm thông tin chi tiết bên dưới.function(...)
: các hàm chuẩnquery
truyền thống.//target
là nhãn cho mục tiêu quan tâm.
# aquery examples: # Get the action graph generated while building //src/target_a $ bazel aquery '//src/target_a' # Get the action graph generated while building all dependencies of //src/target_a $ bazel aquery 'deps(//src/target_a)' # Get the action graph generated while building all dependencies of //src/target_a # whose inputs filenames match the regex ".*cpp". $ bazel aquery 'inputs(".*cpp", deps(//src/target_a))'
Sử dụng các hàm truy vấn
Có 3 hàm aquery
:
inputs
: lọc các hành động theo dữ liệu đầu vào.outputs
: lọc các hành động theo kết quảmnemonic
: lọc hành động theo ghi nhớ
expr ::= inputs(word, expr)
Toán tử inputs
trả về các thao tác được tạo từ bản dựng expr
,
có tên tệp đầu vào khớp với biểu thức chính quy do word
cung cấp.
$ bazel aquery 'inputs(".*cpp", deps(//src/target_a))'
Hàm outputs
và mnemonic
có cú pháp tương tự nhau.
Bạn cũng có thể kết hợp các hàm để thực hiện phép toán AND. Ví dụ:
$ bazel aquery 'mnemonic("Cpp.*", (inputs(".*cpp", inputs("foo.*", //src/target_a))))'
Lệnh ở trên sẽ tìm thấy tất cả các hành động liên quan đến việc tạo //src/target_a
,
có bộ nhớ khớp với "Cpp.*"
và dữ liệu đầu vào khớp với các mẫu
".*cpp"
và "foo.*"
.
Ví dụ về lỗi cú pháp gặp phải:
$ bazel aquery 'deps(inputs(".*cpp", //src/target_a))' ERROR: aquery filter functions (inputs, outputs, mnemonic) produce actions, and therefore can't be the input of other function types: deps deps(inputs(".*cpp", //src/target_a))
Tùy chọn
Tuỳ chọn tạo bản dựng
aquery
chạy trên bản dựng Bazel thông thường và do đó kế thừa tập hợp
tuỳ chọn
trong quá trình tạo bản dựng.
Tùy chọn truy vấn
--output=(text|summary|proto|jsonproto|textproto), default=text
Định dạng đầu ra mặc định (text
) mà con người có thể đọc được,
sử dụng proto
, textproto
hoặc jsonproto
cho định dạng mà máy có thể đọc được.
Thông báo proto là analysis.ActionGraphContainer
.
--include_commandline, default=true
Bao gồm nội dung của các dòng lệnh hành động trong đầu ra (có thể lớn).
--include_artifacts, default=true
Bao gồm tên của các đầu vào và đầu ra hành động ở đầu ra (có thể lớn).
--include_aspects, default=true
Liệu có đưa các thao tác do Aspect tạo vào kết quả hay không.
--include_param_files, default=false
Bao gồm nội dung của các tệp thông số được dùng trong lệnh (có thể lớn).
--include_file_write_contents, default=false
Bao gồm nội dung tệp cho thao tác actions.write()
và nội dung của
tệp kê khai cho hành động SourceSymlinkManifest
. Nội dung tệp là
trả về trong trường file_contents
với --output=
xxxproto
.
Với --output=text
, dữ liệu đầu ra có
FileWriteContents: [<base64-encoded file contents>]
đường kẻ
--skyframe_state, default=false
Nếu không phân tích thêm, hãy kết xuất Biểu đồ hành động từ Skyframe.
Các công cụ và tính năng khác
Truy vấn dựa trên trạng thái Skyframe
Skyframe là phần đánh giá và mô hình mức độ gia tăng của Bazel. Trên mỗi thực thể của máy chủ Bazel, Skyframe lưu trữ biểu đồ phần phụ thuộc được tạo từ các lần chạy trước đó của giai đoạn Phân tích.
Trong một số trường hợp, bạn nên truy vấn Biểu đồ hành động trên Skyframe. Ví dụ về trường hợp sử dụng:
- Chạy
bazel build //target_a
- Chạy
bazel build //target_b
- Đã tạo tệp
foo.out
.
Là người dùng Bazel, tôi muốn xác định xem foo.out
có được tạo từ hoạt động xây dựng
//target_a
hoặc //target_b
.
Một có thể chạy bazel aquery 'outputs("foo.out", //target_a)'
và
bazel aquery 'outputs("foo.out", //target_b)'
để tìm ra hành động chịu trách nhiệm
để tạo foo.out
, rồi đến mục tiêu. Tuy nhiên, số lượng người dùng khác nhau
các mục tiêu đã tạo trước đó có thể lớn hơn 2, nên việc chạy nhiều aquery
rất phức tạp.
Thay vào đó, bạn có thể sử dụng cờ --skyframe_state
:
# List all actions on Skyframe's action graph $ bazel aquery --output=proto --skyframe_state # or # List all actions on Skyframe's action graph, whose output matches "foo.out" $ bazel aquery --output=proto --skyframe_state 'outputs("foo.out")'
Ở chế độ --skyframe_state
, aquery
sẽ lấy nội dung của Biểu đồ hành động
Skyframe tiếp tục sử dụng thực thể Bazel, (không bắt buộc) thực hiện lọc trên thực thể này và
xuất ra nội dung mà không cần chạy lại giai đoạn phân tích.
Các điểm cần cân nhắc đặc biệt
Định dạng đầu ra
--skyframe_state
hiện chỉ dành cho --output=proto
và --output=textproto
Không bao gồm nhãn mục tiêu trong biểu thức truy vấn
Hiện tại, --skyframe_state
truy vấn toàn bộ biểu đồ hành động có trên Skyframe,
bất kể mục tiêu là gì. Có nhãn mục tiêu được chỉ định trong truy vấn cùng với
--skyframe_state
bị coi là lỗi cú pháp:
# WRONG: Target Included $ bazel aquery --output=proto --skyframe_state **//target_a** ERROR: Error while parsing '//target_a)': Specifying build target(s) [//target_a] with --skyframe_state is currently not supported. # WRONG: Target Included $ bazel aquery --output=proto --skyframe_state 'inputs(".*.java", **//target_a**)' ERROR: Error while parsing '//target_a)': Specifying build target(s) [//target_a] with --skyframe_state is currently not supported. # CORRECT: Without Target $ bazel aquery --output=proto --skyframe_state $ bazel aquery --output=proto --skyframe_state 'inputs(".*.java")'
So sánh kết quả của một truy vấn
Bạn có thể so sánh kết quả của 2 lệnh gọi aquery khác nhau bằng công cụ aquery_differ
.
Ví dụ: khi bạn thực hiện một số thay đổi đối với định nghĩa quy tắc và muốn xác minh rằng
các dòng lệnh đang chạy không thay đổi. aquery_differ
chính là công cụ giúp bạn làm việc đó.
Công cụ này có trong kho lưu trữ bazelbuild/bazel. Để sử dụng, hãy sao chép kho lưu trữ vào máy cục bộ. Ví dụ về cách sử dụng:
$ bazel run //tools/aquery_differ -- \ --before=/path/to/before.proto \ --after=/path/to/after.proto \ --input_type=proto \ --attrs=cmdline \ --attrs=inputs
Lệnh trên trả về sự khác biệt giữa kết quả truy vấn before
và after
:
hành động nào có mặt trong một nhưng không có trong hành động kia, những hành động nào có các hành động khác nhau
dòng lệnh/dữ liệu đầu vào trong mỗi đầu ra của truy vấn, ...). Kết quả của việc chạy lệnh trên sẽ là:
Aquery output 'after' change contains an action that generates the following outputs that aquery output 'before' change doesn't: ... /list of output files/ ... [cmdline] Difference in the action that generates the following output(s): /path/to/abc.out --- /path/to/before.proto +++ /path/to/after.proto @@ -1,3 +1,3 @@ ... /cmdline diff, in unified diff format/ ...
Tuỳ chọn lệnh
--before, --after
: Các tệp đầu ra của truy vấn cần so sánh
--input_type=(proto|text_proto), default=proto
: định dạng của đầu vào
tệp. Hỗ trợ đầu ra truy vấn proto
và textproto
.
--attrs=(cmdline|inputs), default=cmdline
: thuộc tính của hành động
để so sánh.
Góc nhìn
Có thể dùng Các khía cạnh để áp dụng chồng lên nhau. Kết quả truy vấn của hành động được tạo bởi các Aspect này sau đó sẽ bao gồm Đường dẫn Aspect, là trình tự của Các khía cạnh áp dụng cho mục tiêu đã tạo ra hành động.
Ví dụ về chế độ Aspect-on-Aspect:
t0 ^ | <- a1 t1 ^ | <- a2 t2
Đặt ti là mục tiêu của quy tắc ri, quy tắc này áp dụng Aspect ai vào các phần phụ thuộc.
Giả sử rằng a2 tạo ra một hành động X khi được áp dụng cho mục tiêu t0. Đầu ra văn bản của
bazel aquery --include_aspects 'deps(//t2)'
cho hành động X sẽ là:
action ... Mnemonic: ... Target: //my_pkg:t0 Configuration: ... AspectDescriptors: [//my_pkg:rule.bzl%**a2**(foo=...) -> //my_pkg:rule.bzl%**a1**(bar=...)] ...
Tức là thao tác X
do Aspect a2
tạo ra trên
a1(t0)
, trong đó a1(t0)
là kết quả của Aspect a1
được áp dụng
vào mục tiêu t0
.
Mỗi AspectDescriptor
đều có định dạng sau:
AspectClass([param=value,...])
AspectClass
có thể là tên của lớp Aspect (đối với các Aspect gốc) hoặc
bzl_file%aspect_name
(đối với các khía cạnh Starlark). AspectDescriptor
là
được sắp xếp theo thứ tự tôpô
biểu đồ phần phụ thuộc.
Liên kết với hồ sơ JSON
Mặc dù truy vấn cung cấp thông tin về các hành động đang được chạy trong một bản dựng (lý do chúng được chạy, đầu vào/đầu ra), hồ sơ JSON cho chúng tôi biết thời gian và thời lượng thực thi các URL đó. Có thể kết hợp 2 tập thông tin này thông qua một mẫu số chung: đầu ra chính của một hành động.
Để bao gồm hành động đầu ra trong hồ sơ JSON, hãy tạo hồ sơ bằng
--experimental_include_primary_output --noexperimental_slim_json_profile
.
Hồ sơ mỏng không tương thích với việc thêm dữ liệu đầu ra chính. Kết quả chính của một hành động
được đưa vào theo mặc định bởi một truy vấn.
Chúng tôi hiện không cung cấp công cụ chuẩn để kết hợp 2 nguồn dữ liệu này, nhưng bạn nên tạo tập lệnh của riêng bạn với thông tin trên.
Vấn đề đã biết
Xử lý hành động được chia sẻ
Đôi khi, các hành động được chia sẻ giữa các mục tiêu đã định cấu hình.
Trong giai đoạn thực thi, những hành động chung đó
chỉ được coi là một và chỉ được thực thi một lần.
Tuy nhiên, truy vấn hoạt động trên biểu đồ hành động trước khi thực thi, sau khi phân tích và do đó xử lý những hành động này
chẳng hạn như các thao tác riêng biệt có Cấu phần phần mềm đầu ra có cùng execPath
. Do đó,
cấu phần phần mềm tương đương có vẻ bị trùng lặp.
Bạn có thể xem danh sách các vấn đề về truy vấn/tính năng theo kế hoạch GitHub.
Câu hỏi thường gặp
ActionKey vẫn giữ nguyên ngay cả khi nội dung của tệp nhập đã thay đổi.
Trong ngữ cảnh của truy vấn, ActionKey
đề cập đến String
nhận được từ
ActionAnalysisMetadata#getKey:
Returns a string encoding all of the significant behaviour of this Action that might affect the output. The general contract of `getKey` is this: if the work to be performed by the execution of this action changes, the key must change. ... Examples of changes that should affect the key are: - Changes to the BUILD file that materially affect the rule which gave rise to this Action. - Changes to the command-line options, environment, or other global configuration resources which affect the behaviour of this kind of Action (other than changes to the names of the input/output files, which are handled externally). - An upgrade to the build tools which changes the program logic of this kind of Action (typically this is achieved by incorporating a UUID into the key, which is changed each time the program logic of this action changes). Note the following exception: for actions that discover inputs, the key must change if any input names change or else action validation may falsely validate.
Việc này loại trừ các thay đổi đối với nội dung của tệp đầu vào và bạn không nên nhầm lẫn với RemoteCacheClient#ActionKey.
Nội dung cập nhật
Nếu bạn có vấn đề/yêu cầu về tính năng, vui lòng báo cáo vấn đề tại đây.