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

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

ดูรายละเอียดเกี่ยวกับภาษาและแฟล็ก --output ได้ในคู่มืออ้างอิงการค้นหาของ Bazel และคู่มืออ้างอิงการค้นหา cquery ของ 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 ช่วยให้เห็นเส้นทางเป็นรูปภาพกราฟแบบมีทิศทางและไม่มีวงจร (Directed Acyclic Graph) แทนที่จะเป็นรายการแบบแบน คุณสามารถเปลี่ยนการแสดงกราฟการค้นหาของ 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 รายการ ได้แก่ somepath() และ allpaths() จะช่วยคุณค้นหาเส้นทางทรัพยากร Dependency ได้ กำหนดเป้าหมายเริ่มต้น 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 เป็นลูกค้าเพียงคนเดียวที่สั่งพิซซ่าและเป็นผู้เขียนรีวิว ซึ่งให้คำตอบแก่เรา

สรุป

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