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

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

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

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

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

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

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

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

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

จากนั้นดึงแอปตัวอย่างจาก ที่เก็บตัวอย่างของ 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

เป้าหมายใดบ้างที่โปรแกรมเรียกใช้ของคุณต้องอาศัยในการทำงาน

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

หากเป้าหมายสำหรับโปรแกรมเรียกใช้ของคุณคือ 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 ได้แก่ อามีร์และเจนนี่ เราไม่ทราบข้อมูลใดๆ เกี่ยวกับลูกค้าทั้ง 2 คนนี้เลยนอกจากชื่อ โชคดีที่ลูกค้าทั้ง 2 คนนี้มีคำสั่งซื้อที่ติดแท็กไว้ในไฟล์ BUILD ของ "customers" คุณจะเข้าถึงแท็กนี้ได้อย่างไร

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

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

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

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

ทดสอบตัวเอง

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

คำตอบ

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

เพิ่มทรัพยากร 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 เพื่อดูข้อมูลที่เป็นประโยชน์

คำตอบ

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

สรุป

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