Bazel ile günlük etkileşim öncelikle birkaç komut aracılığıyla gerçekleşir:
build
, test
ve run
. Bununla birlikte, bazen bu kapasite kısıtlı olabilir: Paketleri bir depoya aktarmak, son kullanıcılar için belge yayınlamak veya Kubernetes ile uygulama dağıtmak isteyebilirsiniz. Ancak Bazel'ın publish
veya deploy
komutu yok. Bu işlemler nerede gerçekleşir?
bazel run komutu
Bazel'in hermetiklik, yeniden üretilebilirlik ve artımlılığa odaklanması, build
ve test
komutlarının yukarıdaki görevler için yararlı olmadığı anlamına gelir. Bu işlemler,
sınırlı ağ erişimiyle bir korumalı alanda çalıştırılabilir ve her bazel build
ile tekrar
çalıştırılacağı garanti edilmez.
Bunun yerine, bazel run
'ten yararlanın: İstediğiniz yan etkilerin olduğu görevler için idealdir. Bazel kullanıcıları, yürütülebilir dosyalar oluşturan kurallara alışkındır ve kural yazarları, bunu "özel fiiller"e genişletmek için ortak bir kalıp grubunu takip edebilir.
Doğada: rules_k8s
Örneğin, Bazel'in Kubernetes kuralları olan rules_k8s
'i ele alalım. Aşağıdaki hedefe sahip olduğunuzu varsayalım:
# BUILD file in //application/k8s
k8s_object(
name = "staging",
kind = "deployment",
cluster = "testing",
template = "deployment.yaml",
)
k8s_object
kuralı, staging
hedefinde bazel build
kullanıldığında standart bir Kubernetes YAML dosyası oluşturur. Ancak ek hedefler, k8s_object
staging.apply
ve :staging.delete
gibi adlara sahip makrolar tarafından da oluşturulur. Bu işlemleri gerçekleştirmek için kullanılan derleme komut dosyaları ve bazel run
staging.apply
ile yürütüldüğünde bunlar kendi bazel k8s-apply
veya bazel
k8s-delete
komutlarımız gibi davranır.
Başka bir örnek: ts_api_Guardian_test
Bu kalıp Angular projesinde de görülebilir. ts_api_guardian_test
makrosu iki hedef oluşturur. Bunlardan ilki, oluşturulan bazı çıkışları "altın" bir dosyayla (yani beklenen çıkışı içeren bir dosya) karşılaştıran standart bir nodejs_test
hedefidir. Bu özellik, normal bir bazel
test
çağrısıyla derlenip çalıştırılabilir. angular-cli
'te, bazel test //etc/api:angular_devkit_core_api
ile böyle bir hedef çalıştırabilirsiniz.
Zaman içinde bu altın dosyanın geçerli nedenlerle güncellenmesi gerekebilir.
Bunun manuel olarak güncellenmesi yorucu ve hataya açık olduğundan bu makro, karşılaştırma yerine altın dosyayı güncelleyen bir nodejs_binary
hedefi de sağlar. Aynı test komut dosyası, çağrılma şekline bağlı olarak "doğrulama" veya "kabul etme" modunda çalışacak şekilde yazılabilir. Bu, daha önce öğrendiğiniz kalıbı takip eder: Yerleşik bir bazel test-accept
komutu yoktur ancak aynı etki bazel run //etc/api:angular_devkit_core_api.accept
ile elde edilebilir.
Bu kalıp oldukça güçlü olabilir ve tanımayı öğrendikten sonra oldukça yaygın olduğunu görebilirsiniz.
Kendi kurallarınızı uyarlama
Makrolar bu kalıbın temelini oluşturur. Makrolar kurallar gibi kullanılır ancak birden fazla hedef oluşturabilir. Genellikle, birincil derleme işlemini gerçekleştiren, belirtilen ada sahip bir hedef oluştururlar: Normal bir ikili dosyayı, Docker görüntüsünü veya kaynak kodu arşivini derleyebilirler. Bu kalıpta, elde edilen ikili programı yayınlama veya beklenen test çıkışını güncelleme gibi birincil hedefin çıkışına göre yan etkiler yapan komut dosyaları oluşturmak için ek hedefler oluşturulur.
Bunu açıklamak için, Sphinx ile web sitesi oluşturan hayali bir kuralı, kullanıcının hazır olduğunda yayınlamasına olanak tanıyan ek bir hedef oluşturmak için bir makroyla sarmalayın. Sfenks içeren bir web sitesi oluşturmak için aşağıdaki mevcut kuralı göz önünde bulundurun:
_sphinx_site = rule(
implementation = _sphinx_impl,
attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
)
Ardından, aşağıdaki gibi bir kural düşünün. Bu kural, çalıştırıldığında oluşturulan sayfaları yayınlayan bir komut dosyası oluşturur:
_sphinx_publisher = rule(
implementation = _publish_impl,
attrs = {
"site": attr.label(),
"_publisher": attr.label(
default = "//internal/sphinx:publisher",
executable = True,
),
},
executable = True,
)
Son olarak, yukarıdaki kuralların her ikisi için de hedefler oluşturmak üzere aşağıdaki makroyu tanımlayın:
def sphinx_site(name, srcs = [], **kwargs):
# This creates the primary target, producing the Sphinx-generated HTML.
_sphinx_site(name = name, srcs = srcs, **kwargs)
# This creates the secondary target, which produces a script for publishing
# the site generated above.
_sphinx_publisher(name = "%s.publish" % name, site = name, **kwargs)
BUILD
dosyalarında, makroyu yalnızca birincil hedefi oluşturuyormuş gibi kullanın:
sphinx_site(
name = "docs",
srcs = ["index.md", "providers.md"],
)
Bu örnekte, makro standart, tek bir Bazel kuralıymış gibi bir "docs" hedefi oluşturulur. Kural oluşturulduğunda bazı yapılandırmalar oluşturur ve manuel incelemeye hazır bir HTML sitesi oluşturmak için Sphinx'i çalıştırır. Ancak, siteyi yayınlamak için bir komut dosyası oluşturan ek bir "docs.publish" hedefi de oluşturulur. Birincil hedefin çıkışını kontrol ettikten sonra, bazel run :docs.publish
kullanarak sanal bir bazel publish
komutu gibi herkesin kullanımına açık şekilde yayınlayabilirsiniz.
_sphinx_publisher
Kuralının uygulanmasının nasıl görüneceği hemen anlaşılmıyor. Genellikle, bunun gibi işlemler bir başlatıcı kabuk komut dosyası yazar.
Bu yöntemde genellikle çok basit bir kabuk komut dosyası yazmak için ctx.actions.expand_template
kullanılması gerekir. Bu örnekte, yayıncı ikili programı, birincil hedefin çıkışına giden bir yol ile birlikte çağrılır. Bu şekilde, yayıncının uygulaması genel kalabilir, _sphinx_site
kuralı yalnızca HTML oluşturabilir ve bu küçük komut dosyası, ikisini birlikte birleştirmek için gereken tek şeydir.
rules_k8s
ürününde .apply
, tam olarak bunu yapar:
expand_template
, birincil hedefin çıkışıyla kubectl
çalıştıran apply.sh.tpl
öğesine dayalı olarak çok basit bir Bash komut dosyası yazar. Bu komut dosyası daha sonra bazel run :staging.apply
ile derlenip çalıştırılabilir. Böylece k8s_object
hedefleri için etkili bir k8s-apply
komutu sağlanır.