Bazel ile günlük etkileşim genellikle birkaç komut aracılığıyla gerçekleşir:
build
, test
ve run
. Ancak bazen bu olanaklar sizi sınırlı hale getirebilir: Paketleri bir depoya aktarmak, son kullanıcılar için belge yayınlamak veya Kubernetes ile bir uygulama dağıtmak isteyebilirsiniz. Ancak Bazel'ın bir publish
veya deploy
komutu yok. Bu işlemler nerede geçerli?
Bazel çalıştırma komutu
Bazel'in hermetiklik, yeniden oluşturulabilirlik ve artımlılık konularına odaklanması, build
ve test
komutlarının yukarıdaki görevler için faydalı olmadığı anlamına geliyor. Bu işlemler, sınırlı ağ erişimine sahip bir korumalı alanda çalıştırılabilir ve her bazel build
ile tekrar çalıştırılacağı garanti edilmez.
Bunun yerine, yan etkileri istediğiniz görevlerin gerçekleştireceği bazel run
aracını kullanın. Bazel kullanıcıları yürütülebilir dosyalar oluşturan kurallara alışkındır. Kural yazarları, bunu "özel fiilleri" kapsayacak şekilde genişletmek için ortak bir kalıp kümesini izleyebilir.
Doğada: rules_k8s
Örneğin, Bazel iç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",
)
staging
hedefinde bazel build
kullanıldığında k8s_object
kuralı, standart bir Kubernetes YAML dosyası oluşturur. Bununla birlikte, ek hedefler k8s_object
makrosu tarafından staging.apply
ve :staging.delete
gibi adlarla oluşturulur. Bunlar, bu işlemleri gerçekleştirmek için komut dosyaları oluşturur 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. Birincisi, oluşturulan bazı çıktıları "golden" dosyası (yani beklenen çıkışı içeren bir dosya) ile karşılaştıran standart bir nodejs_test
hedefidir. Bu özellik normal bazel
test
çağrısıyla oluşturulup çalıştırılabilir. angular-cli
ürününde 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.
Bu dosyayı manuel olarak güncellemek yorucu ve hataya açıktır. Bu nedenle bu makro, aynı zamanda altın dosyasını karşılaştırmak yerine güncelleyen bir nodejs_binary
hedefi de sağlar. Etkin olarak, çağrılma şekline bağlı olarak aynı test komut dosyası "doğrulama" veya "kabul etme" modunda çalışacak şekilde yazılabilir. Bu, daha önce öğrendiğiniz şablonun aynısıdır: Yerel bir bazel test-accept
komutu yoktur ancak bazel run //etc/api:angular_devkit_core_api.accept
ile aynı etki elde edilebilir.
Bu kalıp oldukça güçlü olabilir ve bu modeli tanımayı öğrendiğinizde oldukça yaygın hale gelir.
Kendi kurallarınızı uyarlama
Makrolar bu kalıbın temelinde yer alır. Makrolar, kurallar gibi kullanılır ancak birkaç hedef oluşturabilir. Genellikle birincil derleme işlemini gerçekleştiren, belirtilen ada sahip bir hedef oluştururlar. Belki normal bir ikili program, Docker görüntüsü veya kaynak kodu arşivi oluşturur. Bu kalıpta, birincil hedefin çıktısına bağlı olarak yan etkiler gerçekleştiren komut dosyaları oluşturmak için ek hedefler oluşturulur (sonuçta ortaya çıkan ikili dosyayı yayınlama veya beklenen test çıkışını güncelleme gibi).
Bunu göstermek için, Sfenks içeren bir web sitesi oluşturan sanal bir kuralı, kullanıcının hazır olduğunda yayınlamasına olanak tanıyan ek bir hedef oluşturmak üzere makroyla sarmalayın. Sfenks ile web sitesi oluşturmak için şu mevcut kuralı düşünün:
_sphinx_site = rule(
implementation = _sphinx_impl,
attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
)
Ardından, çalıştırıldığında oluşturulan sayfaları yayınlayan bir komut dosyası oluşturan aşağıdaki gibi bir kural düşünün:
_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 birlikte 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 birincil hedefi oluşturur gibi kullanın:
sphinx_site(
name = "docs",
srcs = ["index.md", "providers.md"],
)
Bu örnekte, makro standart, tek bir Bazel kuralı olduğu gibi, bir "dokümanlar" hedefi oluşturulur. Kural oluşturulduğunda, bir yapılandırma oluşturur ve manuel inceleme için hazır bir HTML sitesi oluşturmak üzere Sfenks'i çalıştırır. Bununla birlikte, 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 tıpkı sanal bir bazel publish
komutu gibi bazel run :docs.publish
kullanarak bunu herkese açık kullanım için yayınlayabilirsiniz.
_sphinx_publisher
kuralının nasıl uygulandığı hemen belli olmaz. Genellikle, bu tür 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ılır. Bu durumda, yayıncı ikili programı birincil hedefin çıkışına giden bir yolla çağrılır. Böylece, yayıncı uygulaması genel kalabilir, _sphinx_site
kuralı yalnızca HTML üretebilir ve ikisini bir araya getirmek için gereken tek şey bu küçük komut dosyasıdır.
rules_k8s
ürününde .apply
tam olarak bu işlemi gerçekleştirir: expand_template
, birincil hedefin çıkışıyla kubectl
çalıştıran apply.sh.tpl
tabanlı çok basit bir Bash komut dosyası yazar. Daha sonra bu komut dosyası bazel run :staging.apply
ile derlenip çalıştırılabilir ve k8s_object
hedefleri için etkili bir şekilde k8s-apply
komutu sağlar.