Sorgu hızlı başlangıç kılavuzu

Sorun bildir Kaynağı görüntüle Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Bu eğitimde, önceden oluşturulmuş bir Bazel projesi kullanarak kodunuzdaki bağımlılıkları izlemek için Bazel ile nasıl çalışacağınız açıklanmaktadır.

Dil ve --output işareti ayrıntıları için Bazel sorgu referansı ve Bazel cquery referansı kılavuzlarına bakın. Komut satırına bazel help query veya bazel help cquery yazarak IDE'nizde yardım alın.

Hedef

Bu kılavuzda, projenizin dosya bağımlılıkları hakkında daha fazla bilgi edinmek için kullanabileceğiniz bir dizi temel sorgu açıklanmaktadır. Bu doküman, Bazel ve BUILD dosyalarının nasıl çalıştığına dair temel bilgilere sahip yeni Bazel geliştiricileri için hazırlanmıştır.

Ön koşullar

Henüz yapmadıysanız Bazel'i yükleyerek başlayın. Bu eğitimde kaynak kontrolü için Git kullanılıyor. En iyi sonuçları elde etmek için Git'i de yükleyin.

Bağımlılık grafiklerini görselleştirmek için Graphviz adlı araç kullanılır. Bu aracı indirerek adımları takip edebilirsiniz.

Örnek projeyi alma

Ardından, tercih ettiğiniz komut satırı aracında aşağıdakileri çalıştırarak Bazel'in örnekler deposundan örnek uygulamayı alın:

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

Bu eğitimdeki örnek proje examples/query-quickstart dizinindedir.

Başlarken

Bazel sorguları nedir?

Sorgular, BUILD dosyaları arasındaki ilişkileri analiz ederek ve sonuçtaki çıktıyı faydalı bilgiler için inceleyerek Bazel kod tabanı hakkında bilgi edinmenize yardımcı olur. Bu kılavuzda bazı temel sorgu işlevleri önizlenmektedir. Daha fazla seçenek için sorgu kılavuzuna bakın. Sorgular, BUILD dosyaları arasında manuel olarak gezinmeden büyük ölçekli projelerdeki bağımlılıklar hakkında bilgi edinmenize yardımcı olur.

Sorgu çalıştırmak için komut satırı terminalinizi açıp şunu girin:

bazel query 'query_function'

Senaryo

Cafe Bazel ile şefi arasındaki ilişkiyi ele alan bir senaryo hayal edin. Bu kafede yalnızca pizza ve mac & cheese satılıyor. Projenin nasıl yapılandırıldığına dair bilgileri aşağıda bulabilirsiniz:

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

Bu eğitimin tamamında, aksi belirtilmedikçe ihtiyacınız olan bilgileri bulmak için BUILD dosyalarına bakmamaya çalışın ve bunun yerine yalnızca sorgu işlevini kullanın.

Bir proje, bir kafeyi oluşturan farklı paketlerden oluşur. Bunlar restaurant, ingredients, dishes, customers ve reviews olarak ayrılır. Bu paketlerdeki kurallar, çeşitli etiketler ve bağımlılıklarla Cafe'nin farklı bileşenlerini tanımlar.

Derleme çalıştırma

Bu proje, Runner.java içinde bir ana yöntem içerir. Bu yöntemi çalıştırarak kafenin menüsünü yazdırabilirsiniz. bazel build komutuyla Bazel'i kullanarak projeyi oluşturun ve hedefin runner olarak adlandırıldığını belirtmek için : kullanın. Hedeflere nasıl referans vereceğinizi öğrenmek için hedef adlarına bakın.

Bu projeyi oluşturmak için aşağıdaki komutu bir terminale yapıştırın:

bazel build :runner

Derleme başarılı olursa çıkışınız aşağıdaki gibi görünür.

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

Başarıyla oluşturulduktan sonra, bu komutu yapıştırarak uygulamayı çalıştırın:

bazel-bin/runner
--------------------- MENU -------------------------

Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner

----------------------------------------------------

Bu işlem sonucunda, menü öğelerinin listesi ve kısa açıklamaları gösterilir.

Hedefleri keşfetme

Proje, içerikleri ve yemekleri kendi paketlerinde listeler. Bir paketin kurallarını görüntülemek için sorgu kullanmak üzere bazel query package/… komutunu çalıştırın.

Bu durumda, aşağıdaki kodu çalıştırarak bu kafenin malzemelerini ve yemeklerini inceleyebilirsiniz:

bazel query //src/main/java/com/example/dishes/...
bazel query //src/main/java/com/example/ingredients/...

Malzemeler paketinin hedeflerini sorgularsanız çıkış şu şekilde görünmelidir:

//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

Bağımlılıkları bulma

Çalıştırıcınızın çalışmak için kullandığı hedefler nelerdir?

Örneğin, dosya sistemini incelemeden (büyük projeler için uygun olmayabilir) projenizin yapısını daha ayrıntılı bir şekilde incelemek istiyorsunuz. Cafe Bazel hangi kuralları kullanır?

Bu örnekte olduğu gibi koşucunuzun hedefi runner ise şu komutu çalıştırarak hedefin temel bağımlılıklarını keşfedin:

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

Çoğu durumda, belirli bir hedefin bağımsız çıkış bağımlılıklarını görmek için sorgu işlevini deps() kullanın.

Bağımlılık grafiğini görselleştirme (isteğe bağlı)

Bu bölümde, belirli bir sorgunun bağımlılık yollarını nasıl görselleştirebileceğiniz açıklanmaktadır. Graphviz, yolu düzleştirilmiş bir liste yerine yönlendirilmiş döngüsüz grafik görüntüsü olarak görmenize yardımcı olur. Çeşitli --output komut satırı seçeneklerini kullanarak Bazel sorgu grafiğinin görünümünü değiştirebilirsiniz. Seçenekler için Çıkış Biçimleri bölümüne bakın.

İstediğiniz sorguyu çalıştırarak başlayın ve gereksiz araç bağımlılıklarını kaldırmak için --noimplicit_deps işaretini ekleyin. Ardından, sorguyu çıkış işaretiyle birlikte kullanın ve grafiğin metin gösterimini oluşturmak için grafiği graph.in adlı bir dosyada saklayın.

Hedef :runner öğesinin tüm bağımlılıklarını aramak ve çıkışı grafik olarak biçimlendirmek için:

bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.in

Bu işlem, derleme grafiğinin metin gösterimi olan graph.in adlı bir dosya oluşturur. Graphviz, metni görselleştirmeye dönüştüren bir araç olan dot 'ı kullanarak PNG oluşturur:

dot -Tpng < graph.in > graph.png

graph.png simgesini açtığınızda aşağıdakine benzer bir ekran görürsünüz. Aşağıdaki grafik, bu kılavuzda temel yol ayrıntılarını daha net hale getirmek için basitleştirilmiştir.

Kafeden şefe, oradan da yemeklere (pizza ve peynirli makarna) giden ilişkiyi gösteren şema. Yemekler, ayrı malzemelere (peynir, domates, hamur ve makarna) ayrılıyor.

Bu kılavuzdaki farklı sorgu işlevlerinin çıkışlarını görmek istediğinizde bu özellikten yararlanabilirsiniz.

Ters bağımlılıkları bulma

Bunun yerine, diğer hedeflerin hangi hedefi kullandığını analiz etmek istiyorsanız belirli bir kurala bağlı olan hedefleri incelemek için bir sorgu kullanabilirsiniz. Bu duruma "ters bağımlılık" adı verilir. rdeps(), aşina olmadığınız bir kod tabanında dosya düzenlerken faydalı olabilir ve bağımlı olduğu diğer dosyaları bilmeden bozmanızı önleyebilir.

Örneğin, cheese bileşeninde bazı düzenlemeler yapmak istiyorsunuz. Cafe Bazel'de sorun yaşanmaması için hangi yemeklerde cheese kullanıldığını kontrol etmeniz gerekir.

Hangi hedeflerin belirli bir hedefe/pakete bağlı olduğunu görmek için rdeps(universe_scope, target) kullanabilirsiniz. rdeps() sorgu işlevi en az iki bağımsız değişken alır: universe_scope (ilgili dizin) ve target. Bazel, sağlanan universe_scope içinde hedefin ters bağımlılıklarını arar. rdeps() operatörü, isteğe bağlı üçüncü bir bağımsız değişkeni kabul eder: arama derinliğinin üst sınırını belirten bir tam sayı değişmezi.

olarak ayarlayın.

Hedef cheese öğesinin tüm proje kapsamındaki ("//…") ters bağımlılıklarını aramak için şu komutu çalıştırın:

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

Sorgu sonucu, hem pizzanın hem de macAndCheese'in peynir kullandığını gösteriyor. Ne sürpriz ama!

Etiketlere göre hedefler bulma

Bazel Cafe'ye iki müşteri giriyor: Amir ve Jenny. Adları dışında haklarında hiçbir bilgi yoktur. Neyse ki siparişleri "müşteriler" BUILD dosyasında etiketlenmiş. Bu etikete nasıl erişebilirsiniz?

Geliştiriciler, genellikle test amacıyla Bazel hedeflerini farklı tanımlayıcılarla etiketleyebilir. Örneğin, testlerdeki etiketler, özellikle çalışma zamanı notlandırma özelliği olmayan C++ ve Python testleri için bir testin hata ayıklama ve yayınlama sürecindeki rolünü notlandırabilir. Etiket ve boyut öğeleri kullanmak, test paketlerini bir kod tabanının check-in politikasına göre oluşturma konusunda esneklik sağlar.

Bu örnekte, menü öğelerini temsil etmek için etiketler pizza veya macAndCheese olarak belirlenmiştir. Bu komut, belirli bir pakette tanımlayıcınızla eşleşen etiketlere sahip hedefleri sorgular.

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

Bu sorgu, "pizza" etiketi olan "customers" paketindeki tüm hedefleri döndürür.

Kendinizi test edin

Jenny'nin ne sipariş etmek istediğini öğrenmek için bu sorguyu kullanın.

Yanıt

Peynirli Makarna

Yeni bağımlılık ekleme

Cafe Bazel menüsünü genişletti. Müşteriler artık smoothie siparişi verebilir. Bu özel smoothie, Strawberry ve Banana malzemelerinden oluşuyor.

Öncelikle smoothie'nin temel malzemelerini ekleyin: Strawberry.java ve Banana.java. Boş Java sınıflarını ekleyin.

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 {

}

Ardından, Smoothie.java öğesini uygun dizine ekleyin: 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";
}

Son olarak, bu dosyaları uygun BUILD dosyalarına kural olarak ekleyin. Adı, herkese açık görünürlüğü ve yeni oluşturulan "src" dosyası da dahil olmak üzere her yeni bileşen için yeni bir Java kitaplığı oluşturun. Sonuç olarak şu güncellenmiş BUILD dosyasına sahip olursunuz:

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"],
)

Yemekler için BUILD dosyasında Smoothie için yeni bir kural eklemek istiyorsunuz. Bu işlem, Smoothie için "src" dosyası olarak oluşturulan Java dosyasını ve smoothie'nin her malzemesi için oluşturduğunuz yeni kuralları içerir.

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",
    ],
)

Son olarak, smoothie'yi Chef'in BUILD dosyasında bağımlı öğe olarak eklemek istiyorsunuz.

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",
    ],
)

Hata olmadığından emin olmak için cafe öğesini tekrar oluşturun. Başarıyla oluşturulursa tebrikler. "Kafe" için yeni bir bağımlılık eklediniz. Aksi takdirde, yazım hatalarına ve paket adlandırmasına dikkat edin. BUILD dosyaları yazma hakkında daha fazla bilgi için BUILD Stil Kılavuzu'na bakın.

Şimdi, öncekiyle karşılaştırmak için Smoothie eklenmiş yeni bağımlılık grafiğini görselleştirin. Netlik için grafik girişini graph2.in ve graph2.png olarak adlandırın.

bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.in
dot -Tpng < graph2.in > graph2.png

İlk grafikle aynı. Ancak şimdi şef hedefinden smoothie ile başlayan ve muz ile çileğe giden bir kol var.

graph2.png'ya baktığınızda Smoothie'nin diğer yemeklerle paylaşılan bağımlılıkları olmadığını ancak Chef'nin bağlı olduğu başka bir hedef olduğunu görebilirsiniz.

somepath() ve allpaths()

Bir paketin neden başka bir pakete bağlı olduğunu sorgulamak isterseniz ne yapmanız gerekir? İkisi arasındaki bağımlılık yolunu göstermek yanıtı sağlar.

Bağımlılık yollarını bulmanıza yardımcı olabilecek iki işlev vardır: somepath() ve allpaths(). Başlangıç hedefi S ve bitiş noktası E verildiğinde, somepath(S,E) kullanarak S ile E arasında bir yol bulun.

"Şef" ve "Peynir" hedefleri arasındaki ilişkilere bakarak bu iki işlev arasındaki farkları inceleyin. Bir hedeften diğerine ulaşmak için farklı yollar izlenebilir:

  • Chef → MacAndCheese → Cheese
  • Chef → Pizza → Cheese

somepath(), iki seçenekten tek bir yol sunarken "allpaths()" işlevi olası tüm yolları verir.

Cafe Bazel'i örnek olarak kullanarak aşağıdakileri çalıştırın:

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

Çıkış, Cafe → Chef → MacAndCheese → Cheese şeklindeki ilk yolu izler. Bunun yerine allpaths() kullanırsanız:

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

Kafeden şefe,pizzadan makarnaya ve peynire giden çıkış yolu

allpaths() çıktısı, bağımlılıkların düzleştirilmiş bir listesi olduğundan okunması biraz daha zordur. Bu grafiği Graphviz kullanarak görselleştirmek, ilişkiyi daha net anlamanızı sağlar.

Kendinizi test edin

Cafe Bazel'in müşterilerinden biri, restoranın ilk yorumunu yaptı. Yorumda, yorumcunun kimliği ve hangi yemeğe atıfta bulunduğu gibi bazı ayrıntılar eksik. Neyse ki bu bilgilere Bazel ile erişebilirsiniz. reviews paketi, gizemli bir müşterinin yorumunu yazdıran bir program içeriyor. Aşağıdakilerle derleyip çalıştırın:

bazel build //src/main/java/com/example/reviews:review
bazel-bin/src/main/java/com/example/reviews/review

Yalnızca Bazel sorgularını kullanarak yorumu kimin yazdığını ve hangi yemeği tarif ettiğini bulmaya çalış.

İpucu

Faydalı bilgiler için etiketleri ve bağımlılıkları kontrol edin.

Yanıt

Bu yorumda pizza anlatılıyor ve yorumu yapan kişi Amir. bazel query --noimplicit\_deps 'deps(//src/main/java/com/example/reviews:review)' komutunu kullanarak bu kuralın hangi bağımlılıkları olduğuna bakarsanız bazel query --noimplicit\_deps 'deps(//src/main/java/com/example/reviews:review)' Bu komutun sonucu, Amir'in inceleyici olduğunu gösterir. Ardından, incelemeyi yapan kişinin Amir olduğunu bildiğiniz için sorgu işlevini kullanarak Amir'in hangi yemeğin olduğunu görmek üzere "BUILD" dosyasında hangi etikete sahip olduğunu arayabilirsiniz. bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)' komutunun çıktısında, pizza sipariş eden tek müşterinin Amir olduğu ve yorumu yapanın da Amir olduğu belirtiliyor.

Özet

Tebrikler! Artık kendi projelerinizde deneyebileceğiniz birkaç temel sorgu çalıştırdınız. Sorgu dili söz dizimi hakkında daha fazla bilgi edinmek için Sorgu referans sayfası'na bakın. Daha gelişmiş sorgular mı istiyorsunuz? Sorgu kılavuzunda, bu kılavuzda ele alınanlardan daha fazla kullanım alanının ayrıntılı bir listesi yer almaktadır.