คู่มือเริ่มต้นการค้นหาฉบับย่อ

บทแนะนำนี้ครอบคลุมวิธีใช้ Bazel เพื่อติดตามทรัพยากร Dependency ในโค้ดโดยใช้โปรเจ็กต์ Bazel ที่สร้างไว้ล่วงหน้า

ดูรายละเอียดเกี่ยวกับภาษาและแฟล็ก --output ได้ในคู่มืออ้างอิงการค้นหาของ Bazel และคู่มืออ้างอิงการค้นหาของ Bazel รับความช่วยเหลือใน IDE โดยพิมพ์ bazel help query หรือ bazel help cquery ในบรรทัดคำสั่ง

วัตถุประสงค์

คู่มือนี้จะแนะนำคุณเกี่ยวกับชุดการค้นหาพื้นฐานที่คุณใช้เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับทรัพยากร Dependency ของไฟล์ในโปรเจ็กต์ได้ คู่มือนี้เหมาะสำหรับนักพัฒนาซอฟต์แวร์ Bazel มือใหม่ที่มีความรู้พื้นฐานเกี่ยวกับวิธีการทำงานของ Bazel และไฟล์ BUILD

ข้อกำหนดเบื้องต้น

เริ่มต้นด้วยการติดตั้ง Bazel หากยังไม่ได้ติดตั้ง บทแนะนำนี้ใช้ Git สำหรับการควบคุมแหล่งที่มา ดังนั้นให้ติดตั้ง Git ด้วยเพื่อให้ได้ผลลัพธ์ที่ดีที่สุด

หากต้องการแสดงภาพกราฟทรัพยากร Dependency ให้ใช้เครื่องมือที่เรียกว่า Graphviz ซึ่งคุณสามารถดาวน์โหลดเพื่อทำตามได้

รับโปรเจ็กต์ตัวอย่าง

จากนั้นดึงข้อมูลแอปตัวอย่างจาก ที่เก็บตัวอย่างของ Bazel โดยเรียกใช้คำสั่งต่อไปนี้ในเครื่องมือบรรทัดคำสั่งที่คุณเลือก

git clone https://github.com/bazelbuild/examples.git

โปรเจ็กต์ตัวอย่างสำหรับบทแนะนำนี้อยู่ในไดเรกทอรี examples/query-quickstart

เริ่มต้นใช้งาน

การค้นหาของ Bazel คืออะไร

การค้นหาช่วยให้คุณเรียนรู้เกี่ยวกับฐานของโค้ด Bazel โดยการวิเคราะห์ความสัมพันธ์ระหว่างไฟล์ BUILD และตรวจสอบเอาต์พุตที่ได้เพื่อหาข้อมูลที่เป็นประโยชน์ คู่มือนี้จะแสดงฟังก์ชันการค้นหาพื้นฐานบางอย่าง แต่หากต้องการดูตัวเลือกเพิ่มเติม โปรดดูคู่มือการค้นหา การค้นหาช่วยให้คุณเรียนรู้เกี่ยวกับทรัพยากร Dependency ในโปรเจ็กต์ขนาดใหญ่ได้โดยไม่ต้องไปยังไฟล์ BUILD ด้วยตนเอง

หากต้องการเรียกใช้การค้นหา ให้เปิดเทอร์มินัลบรรทัดคำสั่งแล้วป้อนคำสั่งต่อไปนี้

bazel query 'query_function'

สถานการณ์

ลองนึกถึงสถานการณ์ที่เจาะลึกความสัมพันธ์ระหว่าง Cafe Bazel กับเชฟของร้าน คาเฟ่แห่งนี้ขายเฉพาะพิซซ่าและมักกะโรนีและชีส ดูโครงสร้างโปรเจ็กต์ด้านล่าง

bazelqueryguide
├── BUILD
├── src
   └── main
       └── java
           └── com
               └── example
                   ├── customers
                      ├── Jenny.java
                      ├── Amir.java
                      └── BUILD
                   ├── dishes
                      ├── Pizza.java
                      ├── MacAndCheese.java
                      └── BUILD
                   ├── ingredients
                      ├── Cheese.java
                      ├── Tomatoes.java
                      ├── Dough.java
                      ├── Macaroni.java
                      └── BUILD
                   ├── restaurant
                      ├── Cafe.java
                      ├── Chef.java
                      └── BUILD
                   ├── reviews
                      ├── Review.java
                      └── BUILD
                   └── Runner.java
└── MODULE.bazel

ตลอดบทแนะนำนี้ ให้พยายามอย่าดูไฟล์ BUILD เพื่อค้นหาข้อมูลที่ต้องการ และใช้ฟังก์ชันการค้นหาเท่านั้น เว้นแต่จะมีการระบุไว้เป็นอย่างอื่น

โปรเจ็กต์ประกอบด้วยแพ็กเกจต่างๆ ที่รวมกันเป็นคาเฟ่ โดยแบ่งออกเป็น restaurant, ingredients, dishes, customers และ reviews กฎภายในแพ็กเกจเหล่านี้กำหนดคอมโพเนนต์ต่างๆ ของคาเฟ่ด้วยแท็กและทรัพยากร Dependency ต่างๆ

เรียกใช้บิลด์

โปรเจ็กต์นี้มีเมธอดหลักอยู่ภายใน Runner.java ซึ่งคุณสามารถเรียกใช้เพื่อพิมพ์เมนูของคาเฟ่ออกมาได้ สร้างโปรเจ็กต์โดยใช้ Bazel ด้วยคำสั่ง bazel build และใช้ : เพื่อระบุว่าเป้าหมายชื่อ runner ดู ชื่อเป้าหมายเพื่อเรียนรู้วิธี อ้างอิงเป้าหมาย

หากต้องการสร้างโปรเจ็กต์นี้ ให้วางคำสั่งนี้ลงในเทอร์มินัล

bazel build :runner

เอาต์พุตควรมีลักษณะดังนี้หากบิลด์สำเร็จ

INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
  bazel-bin/runner.jar
  bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actions

หลังจากสร้างสำเร็จแล้ว ให้เรียกใช้แอปพลิเคชันโดยวางคำสั่งนี้

bazel-bin/runner
--------------------- MENU -------------------------

Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner

----------------------------------------------------

คุณจะได้รับรายการเมนูพร้อมคำอธิบายสั้นๆ

สำรวจเป้าหมาย

โปรเจ็กต์จะแสดงรายการส่วนผสมและอาหารไว้ในแพ็กเกจของตัวเอง หากต้องการใช้การค้นหาเพื่อดูกฎของแพ็กเกจ ให้เรียกใช้คำสั่ง bazel query package/…

ในกรณีนี้ คุณสามารถใช้คำสั่งนี้เพื่อดูส่วนผสมและอาหารที่คาเฟ่แห่งนี้มีได้โดยเรียกใช้คำสั่งต่อไปนี้

bazel query //src/main/java/com/example/dishes/...
bazel query //src/main/java/com/example/ingredients/...

หากคุณค้นหาเป้าหมายของแพ็กเกจส่วนผสม เอาต์พุตควรมีลักษณะดังนี้

//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato

ค้นหาทรัพยากร Dependency

Runner ของคุณต้องอาศัยเป้าหมายใดในการทำงาน

สมมติว่าคุณต้องการเจาะลึกโครงสร้างของโปรเจ็กต์โดยไม่ต้องค้นหาในระบบไฟล์ (ซึ่งอาจทำไม่ได้สำหรับโปรเจ็กต์ขนาดใหญ่) Cafe Bazel ใช้กฎใด

หากเป้าหมายสำหรับ Runner ของคุณคือ runner เหมือนในตัวอย่างนี้ ให้ค้นหาทรัพยากร Dependency ที่ซ่อนอยู่ของเป้าหมายโดยเรียกใช้คำสั่งต่อไปนี้

bazel query --noimplicit_deps "deps(target)"
bazel query --noimplicit_deps "deps(:runner)"
//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef

ในกรณีส่วนใหญ่ ให้ใช้ฟังก์ชันการค้นหา deps() เพื่อดูทรัพยากร Dependency ของเอาต์พุตแต่ละรายการของเป้าหมายที่เฉพาะเจาะจง

แสดงภาพกราฟทรัพยากร Dependency (ไม่บังคับ)

ส่วนนี้อธิบายวิธีแสดงภาพเส้นทางทรัพยากร Dependency สำหรับการค้นหาที่เฉพาะเจาะจง Graphviz ช่วยให้เห็นเส้นทางเป็นรูปภาพกราฟแบบมีทิศทางและไม่มีวงจรแทนที่จะเป็นรายการแบบแบน คุณสามารถเปลี่ยนการแสดงกราฟการค้นหาของ Bazel ได้โดยใช้ตัวเลือกบรรทัดคำสั่ง --output ต่างๆ ดูตัวเลือกได้ที่ รูปแบบเอาต์พุต

เริ่มต้นด้วยการเรียกใช้การค้นหาที่ต้องการและเพิ่มแฟล็ก --noimplicit_deps เพื่อนำทรัพยากร Dependency ของเครื่องมือที่ไม่จำเป็นออก จากนั้นเรียกใช้การค้นหาด้วยแฟล็กเอาต์พุตและจัดเก็บกราฟไว้ในไฟล์ที่ชื่อ graph.in เพื่อสร้างการแสดงกราฟเป็นข้อความ

หากต้องการค้นหาทรัพยากร Dependency ทั้งหมดของเป้าหมาย :runner และจัดรูปแบบเอาต์พุตเป็นกราฟ ให้ทำดังนี้

bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.in

คำสั่งนี้จะสร้างไฟล์ที่ชื่อ graph.in ซึ่งเป็นการแสดงกราฟบิลด์เป็นข้อความ Graphviz ใช้ dot ซึ่งเป็นเครื่องมือที่ประมวลผลข้อความเป็นภาพเพื่อสร้างไฟล์ PNG

dot -Tpng < graph.in > graph.png

เมื่อเปิด graph.png คุณควรเห็นภาพที่มีลักษณะดังนี้ กราฟด้านล่างได้รับการลดความซับซ้อนเพื่อให้รายละเอียดเส้นทางที่สำคัญชัดเจนขึ้นในคู่มือนี้

แผนภาพแสดงความสัมพันธ์จากคาเฟ่ไปจนถึงเชฟและอาหาร ได้แก่ พิซซ่าและมักกะโรนีชีส ซึ่งแยกออกเป็นส่วนผสมต่างๆ ได้แก่ ชีส มะเขือเทศ แป้ง และมักกะโรนี

ซึ่งจะมีประโยชน์เมื่อคุณต้องการดูเอาต์พุตของฟังก์ชันการค้นหาต่างๆ ในคู่มือนี้

ค้นหาทรัพยากร Dependency แบบย้อนกลับ

หากคุณมีเป้าหมายที่ต้องการวิเคราะห์ว่าเป้าหมายอื่นๆ ใช้เป้าหมายนั้นอย่างไร คุณสามารถใช้การค้นหาเพื่อตรวจสอบว่าเป้าหมายใดขึ้นอยู่กับกฎที่เฉพาะเจาะจง ซึ่งเรียกว่า "ทรัพยากร Dependency แบบย้อนกลับ" การใช้ rdeps() อาจมีประโยชน์เมื่อแก้ไขไฟล์ในฐานของโค้ดที่คุณไม่คุ้นเคย และช่วยป้องกันไม่ให้คุณทำลายไฟล์อื่นๆ ที่ขึ้นอยู่กับไฟล์นั้นโดยไม่รู้ตัว

เช่น คุณต้องการแก้ไขส่วนผสม cheese คุณต้องตรวจสอบว่าอาหารใดขึ้นอยู่กับ cheese เพื่อหลีกเลี่ยงไม่ให้เกิดปัญหาสำหรับ Cafe Bazel

หากต้องการดูว่าเป้าหมายใดขึ้นอยู่กับเป้าหมาย/แพ็กเกจที่เฉพาะเจาะจง คุณสามารถใช้ rdeps(universe_scope, target) ฟังก์ชันการค้นหา rdeps() รับอาร์กิวเมนต์อย่างน้อย 2 รายการ ได้แก่ universe_scope ซึ่งเป็นไดเรกทอรีที่เกี่ยวข้อง และ target Bazel จะค้นหาทรัพยากร Dependency แบบย้อนกลับของเป้าหมายภายใน universe_scope ที่ระบุ โอเปอเรเตอร์ rdeps() รับอาร์กิวเมนต์ที่ 3 ที่ไม่บังคับ ซึ่งเป็นตัวอักษรจำนวนเต็มที่ระบุขอบเขตบนของความลึกในการค้นหา

หากต้องการค้นหาทรัพยากร Dependency แบบย้อนกลับของเป้าหมาย cheese ภายในขอบเขตของโปรเจ็กต์ทั้งหมด "//…" ให้เรียกใช้คำสั่งต่อไปนี้

bazel query "rdeps(universe_scope, target)"
ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"
//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef

ผลลัพธ์การค้นหาแสดงให้เห็นว่าทั้งพิซซ่าและมักกะโรนีและชีสขึ้นอยู่กับชีส น่าประหลาดใจมาก

ค้นหาเป้าหมายตามแท็ก

ลูกค้า 2 คนเดินเข้าไปใน Bazel Cafe ได้แก่ Amir และ Jenny เราไม่ทราบข้อมูลใดๆ เกี่ยวกับลูกค้าทั้ง 2 คนนี้เลยนอกจากชื่อ โชคดีที่คำสั่งซื้อของลูกค้าทั้ง 2 คนนี้มีแท็กอยู่ในไฟล์ BUILD ของ "customers" คุณจะเข้าถึงแท็กนี้ได้อย่างไร

นักพัฒนาซอฟต์แวร์สามารถติดแท็กเป้าหมาย Bazel ด้วยตัวระบุต่างๆ ซึ่งมักใช้เพื่อวัตถุประสงค์ในการทดสอบ ตัวอย่างเช่น แท็กในการทดสอบสามารถใส่คำอธิบายประกอบบทบาทของการทดสอบในกระบวนการแก้ไขข้อบกพร่องและการเผยแพร่ โดยเฉพาะอย่างยิ่งสำหรับการทดสอบ C++ และ Python ซึ่งไม่มีความสามารถในการใส่คำอธิบายประกอบขณะรันไทม์ การใช้แท็กและองค์ประกอบขนาดช่วยให้มีความยืดหยุ่นในการประกอบชุดการทดสอบตามนโยบายการเช็กอินของฐานของโค้ด

ในตัวอย่างนี้ แท็กจะเป็น pizza หรือ macAndCheese เพื่อแสดงรายการเมนู คำสั่งนี้จะค้นหาเป้าหมายที่มีแท็กที่ตรงกับตัวระบุของคุณภายในแพ็กเกจที่เฉพาะเจาะจง

bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'

การค้นหานี้จะแสดงเป้าหมายทั้งหมดในแพ็กเกจ "customers" ที่มีแท็ก "pizza"

ทดสอบตัวเอง

ใช้การค้นหานี้เพื่อดูว่า Jenny ต้องการสั่งอะไร

คำตอบ

มักกะโรนีและชีส

เพิ่มทรัพยากร Dependency ใหม่

Cafe Bazel ได้เพิ่มเมนูใหม่แล้ว ตอนนี้ลูกค้าสามารถสั่งสมูทตี้ได้ สมูทตี้สูตรนี้ประกอบด้วยส่วนผสม Strawberry และ Banana

ขั้นแรก ให้เพิ่มส่วนผสมที่สมูทตี้ขึ้นอยู่กับ ได้แก่ Strawberry.java และ Banana.java เพิ่มคลาส Java ว่าง

src/main/java/com/example/ingredients/Strawberry.java

package com.example.ingredients;

public class Strawberry {

}

src/main/java/com/example/ingredients/Banana.java

package com.example.ingredients;

public class Banana {

}

จากนั้นเพิ่ม Smoothie.java ลงในไดเรกทอรีที่เหมาะสม ได้แก่ dishes

src/main/java/com/example/dishes/Smoothie.java

package com.example.dishes;

public class Smoothie {
    public static final String DISH_NAME = "Smoothie";
    public static final String DESCRIPTION = "Yummy and Refreshing";
}

สุดท้าย ให้เพิ่มไฟล์เหล่านี้เป็นกฎในไฟล์ BUILD ที่เหมาะสม สร้างไลบรารี Java ใหม่สำหรับส่วนผสมใหม่แต่ละรายการ รวมถึงชื่อ การมองเห็นแบบสาธารณะ และไฟล์ "src" ที่สร้างขึ้นใหม่ คุณควรได้ไฟล์ BUILD ที่อัปเดตแล้วดังนี้

src/main/java/com/example/ingredients/BUILD

java_library(
    name = "cheese",
    visibility = ["//visibility:public"],
    srcs = ["Cheese.java"],
)

java_library(
    name = "dough",
    visibility = ["//visibility:public"],
    srcs = ["Dough.java"],
)

java_library(
    name = "macaroni",
    visibility = ["//visibility:public"],
    srcs = ["Macaroni.java"],
)

java_library(
    name = "tomato",
    visibility = ["//visibility:public"],
    srcs = ["Tomato.java"],
)

java_library(
    name = "strawberry",
    visibility = ["//visibility:public"],
    srcs = ["Strawberry.java"],
)

java_library(
    name = "banana",
    visibility = ["//visibility:public"],
    srcs = ["Banana.java"],
)

ในไฟล์ BUILD สำหรับอาหาร คุณต้องเพิ่มกฎใหม่สำหรับ Smoothie การดำเนินการดังกล่าวจะรวมไฟล์ Java ที่สร้างขึ้นสำหรับ Smoothie เป็นไฟล์ "src" และกฎใหม่ที่คุณสร้างขึ้นสำหรับส่วนผสมแต่ละรายการของสมูทตี้

src/main/java/com/example/dishes/BUILD

java_library(
    name = "macAndCheese",
    visibility = ["//visibility:public"],
    srcs = ["MacAndCheese.java"],
    deps = [
        "//src/main/java/com/example/ingredients:cheese",
        "//src/main/java/com/example/ingredients:macaroni",
    ],
)

java_library(
    name = "pizza",
    visibility = ["//visibility:public"],
    srcs = ["Pizza.java"],
    deps = [
        "//src/main/java/com/example/ingredients:cheese",
        "//src/main/java/com/example/ingredients:dough",
        "//src/main/java/com/example/ingredients:tomato",
    ],
)

java_library(
    name = "smoothie",
    visibility = ["//visibility:public"],
    srcs = ["Smoothie.java"],
    deps = [
        "//src/main/java/com/example/ingredients:strawberry",
        "//src/main/java/com/example/ingredients:banana",
    ],
)

สุดท้าย คุณต้องรวมสมูทตี้เป็นทรัพยากร Dependency ในไฟล์ BUILD ของเชฟ

src/main/java/com/example/restaurant/BUILD

java\_library(
    name = "chef",
    visibility = ["//visibility:public"],
    srcs = [
        "Chef.java",
    ],

    deps = [
        "//src/main/java/com/example/dishes:macAndCheese",
        "//src/main/java/com/example/dishes:pizza",
        "//src/main/java/com/example/dishes:smoothie",
    ],
)

java\_library(
    name = "cafe",
    visibility = ["//visibility:public"],
    srcs = [
        "Cafe.java",
    ],
    deps = [
        ":chef",
    ],
)

สร้าง cafe อีกครั้งเพื่อยืนยันว่าไม่มีข้อผิดพลาด หากสร้างสำเร็จ ยินดีด้วย คุณได้เพิ่มทรัพยากร Dependency ใหม่สำหรับ "Cafe" แล้ว หากไม่สำเร็จ ให้ตรวจสอบการสะกดคำและการตั้งชื่อแพ็กเกจ ดูข้อมูลเพิ่มเติมเกี่ยวกับการเขียนไฟล์ BUILD ได้ที่ คู่มือรูปแบบไฟล์ BUILD

ตอนนี้ให้แสดงภาพกราฟทรัพยากร Dependency ใหม่ด้วยการเพิ่ม Smoothie เพื่อเปรียบเทียบกับกราฟก่อนหน้า ตั้งชื่ออินพุตกราฟเป็น graph2.in และ graph2.png เพื่อความชัดเจน

bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.in
dot -Tpng < graph2.in > graph2.png

กราฟเดียวกันกับกราฟแรก ยกเว้นตอนนี้มีกิ่งก้านที่แตกแขนงมาจากเป้าหมายเชฟที่มีสมูทตี้ ซึ่งนำไปสู่กล้วยและสตรอว์เบอร์รี

เมื่อดู graph2.png คุณจะเห็นว่า Smoothie ไม่มีทรัพยากร Dependency ที่แชร์กับอาหารอื่นๆ แต่เป็นเพียงเป้าหมายอีกรายการหนึ่งที่ Chef ขึ้นอยู่กับ

somepath() และ allpaths()

จะเกิดอะไรขึ้นหากคุณต้องการค้นหาว่าทำไมแพ็กเกจหนึ่งจึงขึ้นอยู่กับอีกแพ็กเกจหนึ่ง การแสดงเส้นทางทรัพยากร Dependency ระหว่างแพ็กเกจทั้ง 2 จะให้คำตอบ

ฟังก์ชัน 2 ฟังก์ชันต่อไปนี้จะช่วยคุณค้นหาเส้นทางทรัพยากร Dependency ได้ ได้แก่ somepath() และ allpaths() เมื่อกำหนดเป้าหมายเริ่มต้น S และจุดสิ้นสุด E ให้ค้นหาเส้นทางระหว่าง S กับ E โดยใช้ somepath(S,E)

สำรวจความแตกต่างระหว่างฟังก์ชันทั้ง 2 นี้โดยดูความสัมพันธ์ระหว่างเป้าหมาย "Chef" กับ "Cheese" มีเส้นทางที่เป็นไปได้ต่างๆ ในการเดินทางจากเป้าหมายหนึ่งไปยังอีกเป้าหมายหนึ่ง ดังนี้

  • Chef → MacAndCheese → Cheese
  • Chef → Pizza → Cheese

somepath() จะแสดงเส้นทางเดียวจาก 2 ตัวเลือก ในขณะที่ `allpaths()` จะแสดงทุกเส้นทางที่เป็นไปได้

เรียกใช้คำสั่งต่อไปนี้โดยใช้ Cafe Bazel เป็นตัวอย่าง

bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheese

เอาต์พุตจะเป็นไปตามเส้นทางแรกของ Cafe → Chef → MacAndCheese → Cheese หากใช้ allpaths() แทน คุณจะได้ผลลัพธ์ดังนี้

bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef

เส้นทางเอาต์พุตของคาเฟ่ไปเชฟไปพิซซ่าไปมักกะโรนีชีสไปชีส

เอาต์พุตของ allpaths() อ่านยากกว่าเล็กน้อยเนื่องจากเป็นรายการทรัพยากร Dependency แบบแบน การแสดงภาพกราฟนี้โดยใช้ Graphviz จะช่วยให้เข้าใจความสัมพันธ์ได้ชัดเจนขึ้น

ทดสอบตัวเอง

ลูกค้าคนหนึ่งของ Cafe Bazel ได้เขียนรีวิวแรกของร้านอาหาร แต่รีวิวนี้ไม่มีรายละเอียดบางอย่าง เช่น ข้อมูลระบุตัวตนของผู้เขียนรีวิวและอาหารที่รีวิวถึง โชคดีที่คุณเข้าถึงข้อมูลนี้ได้ด้วย Bazel แพ็กเกจ reviews มีโปรแกรมที่พิมพ์รีวิวจากลูกค้าที่ไม่เปิดเผยตัวตน สร้างและดำเนินการด้วย:

bazel build //src/main/java/com/example/reviews:review
bazel-bin/src/main/java/com/example/reviews/review

ลองค้นหาว่าใครเป็นผู้เขียนรีวิวและอาหารที่ผู้เขียนรีวิวถึง โดยใช้เฉพาะการค้นหาของ Bazel

คำใบ้

ตรวจสอบแท็กและทรัพยากร Dependency เพื่อหาข้อมูลที่เป็นประโยชน์

คำตอบ

รีวิวนี้กล่าวถึงพิซซ่าและผู้เขียนรีวิวคือ Amir หากคุณดูทรัพยากร Dependency ที่กฎนี้มีโดยใช้ bazel query --noimplicit\_deps 'deps(//src/main/java/com/example/reviews:review)' ผลลัพธ์ของคำสั่งนี้จะแสดงให้เห็นว่า Amir เป็นผู้เขียนรีวิว จากนั้นเมื่อทราบว่าผู้เขียนรีวิวคือ Amir คุณสามารถใช้ฟังก์ชันการค้นหาเพื่อดูว่า Amir มีแท็กใดในไฟล์ `BUILD` เพื่อดูว่ามีอาหารใดบ้าง คำสั่ง bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)' แสดงให้เห็นว่า Amir เป็นลูกค้าเพียงคนเดียวที่สั่งพิซซ่าและเป็นผู้เขียนรีวิว ซึ่งให้คำตอบแก่เรา

ใกล้จะเสร็จแล้ว

ยินดีด้วย ตอนนี้คุณได้เรียกใช้การค้นหาพื้นฐานหลายรายการแล้ว ซึ่งคุณสามารถลองใช้กับโปรเจ็กต์ของคุณเองได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับไวยากรณ์ของภาษาการค้นหาได้ที่หน้าอ้างอิงการค้นหา หากต้องการการค้นหาขั้นสูงเพิ่มเติม คู่มือการค้นหาจะแสดงรายการกรณีการใช้งานเพิ่มเติมอย่างละเอียดกว่าที่กล่าวถึงในคู่มือนี้