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

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

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

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

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

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

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

เครื่องมือที่เรียกว่า Graphviz ใช้ในการดาวน์โหลดเพื่อให้เห็นภาพของกราฟทรัพยากร Dependency

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

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

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

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

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

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

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

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

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

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

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

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

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

นักพัฒนาแอปสามารถติดแท็กเป้าหมาย 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 Style Guide

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

คำตอบ

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

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

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