Lệnh aquery
cho phép bạn truy vấn các hành động trong biểu đồ bản dựng.
Cấu phần phần mềm này hoạt động dựa trên biểu đồ mục tiêu đã định cấu hình sau 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 các Hành động/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/công cụ ghi nhớ của các lệnh đó.
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 một bản dựng.
Phiên bản này hỗ trợ cùng một tập hợp các hàm cũng có trong query
truyền thống nhưng siblings
, buildfiles
và tests
.
Ví dụ về kết quả đầu ra của aquery
(không có thông tin 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à một 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
. Thông tin chi tiết bên dưới.function(...)
: các hàm tiêu chuẩn nhưquery
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 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 đầu ramnemonic
: lọc các hành động theo cách 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))'
Các hàm outputs
và mnemonic
có cú pháp tương tự.
Bạn cũng có thể kết hợp các hàm để đạt được 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 tất cả hành động liên quan đến việc tạo //src/target_a
có thông tin ghi nhớ khớp với "Cpp.*"
và dữ liệu đầu vào khớp với mẫu ".*cpp"
và "foo.*"
.
Ví dụ về lỗi cú pháp được tạo:
$ 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
aquery
chạy trên một bản dựng Bazel thông thường và do đó kế thừa tập hợp tuỳ chọn có sẵn trong quá trình tạo bản dựng.
Tuỳ chọn truy vấn
--output=(text|summary|proto|jsonproto|textproto), default=text
Định dạng đầu ra mặc định (text
) là định dạng có thể đọc được, hãy sử dụng proto
, textproto
hoặc jsonproto
cho định dạng mà máy có thể đọ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 đầu vào và đầu ra của hành động trong đầu ra (có thể lớn).
--include_aspects, default=true
Liệu có đưa hành động được tạo theo Khung hình vào đầu ra hay không.
--include_param_files, default=false
Bao gồm nội dung của các tệp tham 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 thao tác SourceSymlinkManifest
. Nội dung tệp sẽ được trả về trong trường file_contents
với --output=
xxxproto
.
Với --output=text
, dữ liệu đầu ra có dòng FileWriteContents: [<base64-encoded file contents>]
--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 về trạng thái của Skyframe
Skyframe là mô hình đánh giá và 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 tạo từ toà nhà //target_a
hay //target_b
.
Người dùng 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
và lần lượt là mục tiêu. Tuy nhiên, số lượng mục tiêu khác nhau được tạo trước đó có thể lớn hơn 2, điều này khiến việc chạy nhiều lệnh aquery
trở nên rắc rối.
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")'
Với chế độ --skyframe_state
, aquery
sẽ lấy nội dung của Biểu đồ hành động mà Skyframe giữ lại trên thực thể của Bazel (không bắt buộc) thực hiện lọc trên đó và xuất 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 đưa các nhãn mục tiêu vào 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ể các mục tiêu là gì. Việc chỉ định nhãn mục tiêu 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 truy vấn
Bạn có thể so sánh kết quả của hai lệnh gọi một truy vấn 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
là công cụ để làm việc đó.
Công cụ này có trong kho lưu trữ bazelbuild/bazel. Để sử dụng kho lưu trữ này, 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
:
các hành động nào có trong một nhưng không có trong một hành động khác, các hành động nào có
dòng lệnh/đầu vào khác nhau trong mỗi đầu ra 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 sẽ được so sánh
--input_type=(proto|text_proto), default=proto
: định dạng của các tệp đầu vào. Hỗ trợ được cung cấp cho kết quả truy vấn proto
và textproto
.
--attrs=(cmdline|inputs), default=cmdline
: các thuộc tính của các hành động cần so sánh.
Góc nhìn
Bạn có thể áp dụng Các khía cạnh chồng lên nhau. Sau đó, truy vấn đầu ra của thao tác do các khía cạnh này tạo ra sẽ bao gồm đường dẫn Khung hình. Đây là trình tự các khía cạnh được áp dụng cho mục tiêu đã tạo ra hành động.
Ví dụ về Tỷ lệ khung hình:
t0 ^ | <- a1 t1 ^ | <- a2 t2
Đặt ti là mục tiêu của quy tắc ri, sẽ áp dụng Khung hình ai cho các phần phụ thuộc.
Giả sử 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à hành động X
được tạo bởi Khung hình a2
và áp dụng cho a1(t0)
, trong đó a1(t0)
là kết quả của Khung hình a1
được áp dụng cho mục tiêu t0
.
Mỗi AspectDescriptor
có định dạng sau:
AspectClass([param=value,...])
AspectClass
có thể là tên của lớp Aspects (đối với Aspects gốc)) hoặc bzl_file%aspect_name
(đối với Starlark Aspects). AspectDescriptor
được sắp xếp theo thứ tự cấu trúc liên kết của 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 các hành động đó đang được chạy, đầu vào/đầu ra của các hành động đó), nhưng hồ sơ JSON cho chúng ta biết thời gian và khoảng thời gian thực thi các hành động đó. Có thể kết hợp 2 tập hợp thông tin này qua một mẫu số chung: đầu ra chính của hành động.
Để đưa kết quả của các hành động vào hồ sơ JSON, hãy tạo hồ sơ bằng --experimental_include_primary_output --noslim_profile
.
Cấu hình mỏng không tương thích với việc thêm đầu ra chính. Theo mặc định, một truy vấn sẽ đưa dữ liệu đầu ra chính của hành động vào.
Chúng tôi hiện chưa cung cấp công cụ chính tắc để kết hợp 2 nguồn dữ liệu này, nhưng bạn có thể tự xây dựng tập lệnh của riêng mình với những thông tin trên.
Vấn đề đã biết
Xử lý các thao tác được chia sẻ
Đôi khi, các thao tác được dùng chung giữa các mục tiêu đã định cấu hình.
Trong giai đoạn thực thi, các hành động dù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 thực thi trước và sau phân tích nên sẽ xử lý các hành động này như các hành động riêng biệt mà Cấu phần phần mềm đầu ra có cùng execPath
. Do đó, các Cấu phần phần mềm tương đương bị trùng lặp.
Bạn có thể xem danh sách các vấn đề về truy vấn/các tính năng theo kế hoạch trên GitHub.
Câu hỏi thường gặp
ActionKey vẫn giữ nguyên mặc dù nội dung của tệp nhập thay đổi.
Trong ngữ cảnh của một truy vấn, ActionKey
tham chiếu đế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.
Điều này không bao gồm các thay đổi đối với nội dung của tệp nhập và không nhầm lẫn với RemoteCacheClient#ActionKey.
Các bản cập nhật
Đối với mọi vấn đề/yêu cầu về tính năng, vui lòng báo cáo vấn đề tại đây.