Bu sayfada, Çevik yaklaşımın temellerini göz önünde bulundurur ve hem basit hem de örnekler.
En boy oranları, ek bilgi içeren bağımlılık grafiklerinin artırılmasına olanak tanır ve işlemler. Özelliklerin yararlı olabileceği bazı tipik senaryolar:
- Bazel'i entegre eden entegre geliştirme ortamları, Google Haritalar'daki belirler.
- Kod oluşturma araçları, belli bir ekip üyesine ait girdileri
hedeften bağımsız bir yöntemdir. Örneğin,
BUILD
dosyaları bir hiyerarşi belirtebilir protobuf kitaplığının tanımlar ve dile özgü kurallar, Çevik ve Scrum’ın belirli bir dil için protobuf destek kodu oluşturan işlemler.
Aspect ile ilgili temel bilgiler
BUILD
dosyaları, bir projenin kaynak koduyla ilgili bir açıklama sağlar: Hangi kaynak?
hangi yapıların (hedefler) oluşturulması gerektiğine,
ve bu dosyalar arasındaki bağımlılıkların neler olduğu gibi konuları ele alacağız. Bazel,
yani bir derleme işlemi için gereken işlemleri
yapıları oluşturmak için gerekli olan (örneğin, derleyici veya bağlayıcı çalıştırma) ve
bu işlemleri yürütür. Bazel bunu başarmak için bir bağımlılık
grafiği ziyaret edin.
Şu BUILD
dosyasını göz önünde bulundurun:
java_library(name = 'W', ...)
java_library(name = 'Y', deps = [':W'], ...)
java_library(name = 'Z', deps = [':W'], ...)
java_library(name = 'Q', ...)
java_library(name = 'T', deps = [':Q'], ...)
java_library(name = 'X', deps = [':Y',':Z'], runtime_deps = [':T'], ...)
Bu BUILD
dosyası, aşağıdaki şekilde gösterilen bir bağımlılık grafiğini tanımlar:
Şekil 1. BUILD
dosya bağımlılık grafiği.
Bazel, bu bağımlılık grafiğini analiz etmek için
her biri için karşılık gelen kural (bu örnekte "java_library")
hedef. Kural uygulama işlevleri,
.jar
dosyaları gibi derleme yapıları ve konumlar gibi ilet bilgileri
ve bu eserlerin adlarını, bu hedeflerin ters bağımlılıklarına
sağlayıcılar.
Yönler kurallara benzer, çünkü özellik içeren bir uygulama işlevine işlem ve iade sağlayıcıları oluşturur. Ancak güçleri bağımlılık grafiğinin onlar için oluşturulduğu şeydir. Bir yöne göre uygulama mevcut ve yayıldığı tüm özelliklerin listesini içerir. Projenin gidişatı boyunca "deps" adlı özellikler boyunca yayılır. Bu özellik, bir hedef X oluşturduğundan, A(X) en boy uygulama düğümü elde edilir. Uygulaması sırasında A yönü, X'in "dep"lerinde atıfta bulunduğu tüm hedeflere yinelemeli olarak uygulanır. özelliği (A'nın yayılım listesindeki tüm özellikler).
Bu yüzden, A niteliğini bir hedef X'e uygularken tek bir işlem bir "gölge grafiği" üretir / aşağıda gösterilen hedeflerin orijinal bağımlılık grafiğidir:
Şekil 2. Farklı yönleri olan bir grafik oluşturun.
Gölgelendirilen yalnızca kenarlar,
yayılım seti olduğundan runtime_deps
kenarı bu
örneğine bakalım. Ardından, tablodaki tüm düğümlerde bir en boy uygulama işlevi
Düğümlerde kural uygulamalarının çağrılmasına benzer şekilde gölge grafik
farklı olabilir.
Basit örnek
Bu örnekte, bir
kuralı ve tüm bağımlılıkları deps
özelliğine sahiptir. Bu sonuçta
özellik uygulaması, en boy tanımı ve hususun nasıl çağrılacağı
komutunu çalıştırın.
def _print_aspect_impl(target, ctx):
# Make sure the rule has a srcs attribute.
if hasattr(ctx.rule.attr, 'srcs'):
# Iterate through the files that make up the sources and
# print their paths.
for src in ctx.rule.attr.srcs:
for f in src.files.to_list():
print(f.path)
return []
print_aspect = aspect(
implementation = _print_aspect_impl,
attr_aspects = ['deps'],
)
Örneği bölümlere ayıralım ve her birini ayrı ayrı inceleyelim.
En boy tanımı
print_aspect = aspect(
implementation = _print_aspect_impl,
attr_aspects = ['deps'],
)
En boy tanımları, kural tanımlarına benzer ve
aspect
işlevini kullanın.
Kural gibi, bir özelliğin de bir uygulama işlevi vardır. Bu örnekte
_print_aspect_impl
attr_aspects
, özelliğin yayıldığı kural özelliklerinin listesidir.
Bu örnekte, boy oranıdeps
tüm kuralları oluşturur.
attr_aspects
için yaygın olarak kullanılan bir diğer bağımsız değişken de ['*']
bağımsız değişkenidir. Bu bağımsız değişken
özelliğini nasıl kullanacağınızı göstereceğim.
Aspect uygulaması
def _print_aspect_impl(target, ctx):
# Make sure the rule has a srcs attribute.
if hasattr(ctx.rule.attr, 'srcs'):
# Iterate through the files that make up the sources and
# print their paths.
for src in ctx.rule.attr.srcs:
for f in src.files.to_list():
print(f.path)
return []
Aspect uygulama işlevleri, kural uygulamasına benzer işlevlerine dahildir. Sağlayıcılar döndürürler, işlem yapın ve iki bağımsız değişken alın:
target
: Özelliğin uygulandığı hedef.ctx
: Özelliklere erişmek için kullanılabilecekctx
nesnesi ve çıktılar ile eylemler üretin.
Uygulama işlevi,
ctx.rule.attr
. Şu anda Google’da çalışan
uygulandığı hedef tarafından sağlanır (target
bağımsız değişkeni aracılığıyla).
Sağlayıcı listesini döndürmek için özellikler gerekir. Bu örnekte, herhangi bir şey sağlamaz, bu nedenle boş bir liste döndürür.
Komut satırını kullanarak detayı çağırma
Bir özelliği uygulamanın en basit yolu,
--aspects
bağımsız değişkeninin önüne geçer. Yukarıdaki özelliğin print.bzl
adlı bir dosyada tanımlandığı varsayıldığında
bu:
bazel build //MyExample:example --aspects print.bzl%print_aspect
print_aspect
, example
hedefine ve
deps
özelliği aracılığıyla yinelemeli olarak erişilebilen hedef kuralları.
--aspects
işareti bir bağımsız değişken alır. Bu bağımsız değişken, özelliğin özelliği
<extension file label>%<aspect top-level name>
biçimindedir.
Gelişmiş örnek
Aşağıdaki örnekte, hedef kuraldaki bir özelliğin kullanımı gösterilmektedir , hedeflerdeki dosyaları sayan, potansiyel olarak uzantıları uzantıya göre filtreleyen bir programdır. Değer döndürmek için bir sağlayıcının nasıl kullanılacağını, bir bağımsız değişkeni özellik uygulamasına ve bir kuraldan bir özelliğin nasıl çağrılacağını öğreneceksiniz.
file_count.bzl
dosyası:
FileCountInfo = provider(
fields = {
'count' : 'number of files'
}
)
def _file_count_aspect_impl(target, ctx):
count = 0
# Make sure the rule has a srcs attribute.
if hasattr(ctx.rule.attr, 'srcs'):
# Iterate through the sources counting files
for src in ctx.rule.attr.srcs:
for f in src.files.to_list():
if ctx.attr.extension == '*' or ctx.attr.extension == f.extension:
count = count + 1
# Get the counts from our dependencies.
for dep in ctx.rule.attr.deps:
count = count + dep[FileCountInfo].count
return [FileCountInfo(count = count)]
file_count_aspect = aspect(
implementation = _file_count_aspect_impl,
attr_aspects = ['deps'],
attrs = {
'extension' : attr.string(values = ['*', 'h', 'cc']),
}
)
def _file_count_rule_impl(ctx):
for dep in ctx.attr.deps:
print(dep[FileCountInfo].count)
file_count_rule = rule(
implementation = _file_count_rule_impl,
attrs = {
'deps' : attr.label_list(aspects = [file_count_aspect]),
'extension' : attr.string(default = '*'),
},
)
BUILD.bazel
dosyası:
load('//:file_count.bzl', 'file_count_rule')
cc_library(
name = 'lib',
srcs = [
'lib.h',
'lib.cc',
],
)
cc_binary(
name = 'app',
srcs = [
'app.h',
'app.cc',
'main.cc',
],
deps = ['lib'],
)
file_count_rule(
name = 'file_count',
deps = ['app'],
extension = 'h',
)
En boy tanımı
file_count_aspect = aspect(
implementation = _file_count_aspect_impl,
attr_aspects = ['deps'],
attrs = {
'extension' : attr.string(values = ['*', 'h', 'cc']),
}
)
Bu örnekte, en boy oranının deps
özelliği aracılığıyla nasıl yayıldığı gösterilmektedir.
attrs
, bir yönle ilgili özellik grubunu tanımlar. Herkese açık özellik özellikleri
parametreleri tanımlar ve yalnızca bool
, int
veya string
türünde olabilir.
Kural yayılımlı unsurlar için int
ve string
parametrelerinde
Bu öğelerde values
belirtilmiş. Bu örnekte extension
adlı bir parametre var
'*
', 'h
' veya 'cc
' içermesine izin verilen siteler belirtirsiniz.
Kural yayılımlı özellikler için parametre değerleri, istekte bulunan kuraldan alınır.
kuralının aynı ada ve türe sahip özelliğini kullanarak en boy oranını girin.
(file_count_rule
kelimesinin tanımına bakın).
Komut satırı özellikleri için parametre değerleri
--aspects_parameters
tıklayın. int
ve string
parametreleri için values
kısıtlaması şu olabilir:
atlandı.
En boyların label
türünde gizli özelliklere de sahip olmasına izin verilir
label_list
. Özel etiket özellikleri,
unsurlarla oluşturulan işlemler için gerekli araçlar veya kitaplıklar bulunur. Yok
bu örnekte tanımlanmış bir gizli özellik, ancak aşağıdaki kod snippet'i
, aracı belirli bir unsura nasıl iletebileceğinizi gösterir:
...
attrs = {
'_protoc' : attr.label(
default = Label('//tools:protoc'),
executable = True,
cfg = "exec"
)
}
...
Aspect uygulaması
FileCountInfo = provider(
fields = {
'count' : 'number of files'
}
)
def _file_count_aspect_impl(target, ctx):
count = 0
# Make sure the rule has a srcs attribute.
if hasattr(ctx.rule.attr, 'srcs'):
# Iterate through the sources counting files
for src in ctx.rule.attr.srcs:
for f in src.files.to_list():
if ctx.attr.extension == '*' or ctx.attr.extension == f.extension:
count = count + 1
# Get the counts from our dependencies.
for dep in ctx.rule.attr.deps:
count = count + dep[FileCountInfo].count
return [FileCountInfo(count = count)]
Tıpkı kural uygulama işlevi gibi, bir görünüm uygulama işlevi de bağımlılıkları tarafından erişilebilen bir sağlayıcı yapısını döndürür.
Bu örnekte FileCountInfo
, benzersiz bir hizmet sağlayıcısı olarak tanımlanmış bir sağlayıcı
count
alanı. En iyi uygulama olarak, bir reklamverenin alanlarını açıkça tanımlamak
fields
özelliğini kullanan bir sağlayıcıdır.
A(X) en boy uygulaması için sağlayıcı grubu, sağlayıcıların birleşimidir
hedefi X için bir kuralın uygulanmasından ve
uygulanır. Bir kural uygulamasının yaydığı sağlayıcılar
öğeler uygulanmadan önce oluşturulur ve dondurulamaz ve
emin olun. Bir hedef ve ona uygulanan bir unsur varsa bu bir hatadır
aynı türde bir sağlayıcı sağlayabilir;
OutputGroupInfo
(birleştirildiği takdirde,
kuralı ve en boy oranı farklı çıkış gruplarını belirtir) ve
InstrumentedFilesInfo
(görüntüyü dikkate alın). Bu, özellik uygulamalarının
hiçbir zaman DefaultInfo
değerini döndürmez.
Parametreler ve gizli özellikler,
ctx
Bu örnekte, extension
parametresi kullanılmıştır ve
sayılacağını unutmayın.
Geri dönen sağlayıcılar için,
en boy oranı (attr_aspects
listesinden) şununla değiştirilir:
uygulamanın sonuçlarını tanımlamasına yardımcı olur. Örneğin,
X'in noktalarında Y ve Z değerleri vardır. A(X) için ctx.rule.attr.deps
değeri [A(Y), A(Z)] olur.
Bu örnekte ctx.rule.attr.deps
, en iyi performans gösteren
“dep”lere uygulamanın sonuçları orijinal hedefin
en boy oranı uygulandı.
Bu örnekte, özellik, FileCountInfo
sağlayıcısına şuradan erişiyor:
toplam geçişli dosya sayısını biriktirmek için bağımlıların bağımlılıklarını.
Bir kuraldan özellik çağrılıyor
def _file_count_rule_impl(ctx):
for dep in ctx.attr.deps:
print(dep[FileCountInfo].count)
file_count_rule = rule(
implementation = _file_count_rule_impl,
attrs = {
'deps' : attr.label_list(aspects = [file_count_aspect]),
'extension' : attr.string(default = '*'),
},
)
Kural uygulamasında, FileCountInfo
hedefine nasıl erişileceği gösterilmektedir
ctx.attr.deps
üzerinden.
Kural tanımı, bir parametrenin (extension
) nasıl tanımlanacağını gösterir.
ve varsayılan bir değer (*
) belirleyin. Projenin gidişatı boyunca
'cc
', 'h
' veya '*
' değerlerinden biri değildi
en boy tanımındaki parametreye uygulanan kısıtlamalar.
Hedef kuralı aracılığıyla bir özelliği çağırma
load('//:file_count.bzl', 'file_count_rule')
cc_binary(
name = 'app',
...
)
file_count_rule(
name = 'file_count',
deps = ['app'],
extension = 'h',
)
Bu görselde, extension
parametresinin özellik parametresine nasıl iletileceği gösterilmektedir
aracılığıyla iletişim kurabilirsiniz. extension
parametresinin
kuralının uygulanması yerine, extension
isteğe bağlı bir parametre olarak kabul edilir.
file_count
hedefi oluşturulduğunda, özelliklerimiz şu şekilde değerlendirilir:
kendisi ve deps
üzerinden yinelemeli olarak erişilebilen tüm hedefler.