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

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

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

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

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

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

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

หากต้องการแสดงภาพกราฟการอ้างอิง ให้ใช้เครื่องมือที่เรียกว่า 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
└── WORKSPACE

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

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

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

โปรเจ็กต์นี้มีเมธอดหลักภายใน Runner.java ซึ่งคุณดำเนินการเพื่อพิมพ์เมนูของ Cafe ได้ สร้างโปรเจ็กต์โดยใช้ 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 สำหรับคำค้นหาหนึ่งๆ กราฟวิซช่วยให้เห็นเส้นทางเป็นรูปภาพกราฟแบบวงกลมมีทิศทางตรง ไม่ใช่รายชื่อที่แยกเป็นเดี่ยว คุณสามารถเปลี่ยนการแสดงกราฟการค้นหาของ 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 แบบย้อนกลับ

หากคุณมีเป้าหมายที่ต้องการวิเคราะห์สิ่งที่เป้าหมายอื่นๆ ใช้ คุณสามารถใช้การค้นหาเพื่อตรวจสอบว่าเป้าหมายใดที่ใช้กฎบางกฎได้ การทำเช่นนี้เรียกว่า "การอ้างอิงแบบย้อนกลับ" การใช้ 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

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

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

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

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

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

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

ข้อความค้นหานี้จะแสดงเป้าหมายทั้งหมดในแพ็กเกจ "ลูกค้า" ที่มีแท็กเป็น "พิซซ่า"

ทดสอบตัวเอง

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

คำตอบ

แมคแอนด์ชีส

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

จากนั้น ให้ดูกราฟการอ้างอิงใหม่ด้วยการเพิ่ม 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()

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

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

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

  • เชฟ → MacAndCheese → ชีส
  • เชฟ → พิซซ่า → ชีส

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 → ชีส หากใช้ 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 ที่กฎนี้ใช้ 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/...)' เอาต์พุตว่าอาเมียร์เป็นลูกค้าคนเดียวที่สั่งพิซซ่า และเป็นผู้ตรวจสอบที่ให้คำตอบเรา

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

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