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

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

โปรเจ็กต์ประกอบด้วยแพ็กเกจต่างๆ ที่ประกอบกันเป็น Cafe โดยแบ่งออกเป็น restaurant, ingredients, dishes, customers และ reviews กฎภายในแพ็กเกจเหล่านี้จะกำหนดคอมโพเนนต์ต่างๆ ของ Cafe ด้วยแท็กและ 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 คือ 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 (ไม่บังคับ)

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

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

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

กำลังค้นหาเป้าหมายตามแท็ก

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

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

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

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

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

ทดสอบตัวเอง

ใช้คำค้นหานี้เพื่อดูสิ่งที่เจนนภาต้องการสั่งซื้อ

คำตอบ

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

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

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 ของ Chef

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()

ในกรณีที่คุณต้องการค้นหาสาเหตุที่แพ็กเกจหนึ่งต้องอาศัยแพ็กเกจอื่น การแสดงเส้นทางการอ้างอิงระหว่างเส้นทางทั้งสองจะให้คำตอบ

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

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

  • Chef → MacAndCheese → 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() จะอ่านได้ยากกว่าเล็กน้อยเนื่องจากเป็นรายการแบบแบนของการพึ่งพา การแสดงภาพกราฟนี้โดยใช้ 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/...)' จะแสดงข้อความว่าอัมราเป็นลูกค้าเพียงคนเดียวที่สั่งพิซซ่าและเป็นผู้รีวิวที่ให้คำตอบแก่เรา

สรุป

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