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

7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

หากมีเป้าหมายที่ต้องการวิเคราะห์ว่าเป้าหมายอื่นๆ ใช้เป้าหมายนั้นอย่างไร ให้ใช้การค้นหาเพื่อดูว่าเป้าหมายใดใช้กฎหนึ่งๆ ลักษณะนี้เรียกว่า "Dependency แบบย้อนกลับ" การใช้ rdeps() อาจมีประโยชน์เมื่อแก้ไขไฟล์ในโค้ดเบสที่คุณไม่คุ้นเคย และช่วยป้องกันไม่ให้คุณทำไฟล์อื่นๆ ที่ขึ้นอยู่กับไฟล์นั้นเสียหายโดยไม่รู้ตัว

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

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

หากต้องการค้นหาการพึ่งพาย้อนกลับของเป้าหมาย 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 "customers" คุณเข้าถึงแท็กนี้ได้อย่างไร

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

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

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

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

ทดสอบตัวเอง

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

คำตอบ

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

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

ตอนนี้ 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",
    ],
)

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

somepath() และ allpaths()

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

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

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

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

คำตอบ

รีวิวนี้อธิบายถึงพิซซ่าและ Amir เป็นผู้รีวิว หากดูที่สิ่งที่กฎนี้ใช้อ้างอิงโดยใช้ 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 โดยละเอียดมากกว่าที่ครอบคลุมในคู่มือนี้