Bazel ile günlük etkileşim öncelikle birkaç komut aracılığıyla gerçekleşir:
build
, test
ve run
. Bununla birlikte, bazen bu kapasitenin kısıtlı olduğu durumlar 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 çalıştırma 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ışabilir ve her bazel build
ile tekrar çalıştırılacağı garanti edilmez.
Bunun yerine, yan etkileri istediğiniz görevler için destekleyici olan bazel run
'den yararlanın. Bazel kullanıcıları yürütülebilir dosyalar oluşturan kurallara alışkındır. Kural yazarları, bunu "özel fiillere" genişletmek için ortak bir kalıplar dizisini izleyebilirler.
Vahşi yaşam: 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",
)
staging
hedefinde bazel build
kullanıldığında k8s_object
kuralı standart bir Kubernetes YAML dosyası oluşturur. Bununla birlikte, ek hedefler staging.apply
ve :staging.delete
gibi adlara sahip k8s_object
makrosu 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. Birincisi, oluşturulan bir çıktıyı "altın" dosya (yani beklenen çıkışı içeren bir dosya) ile 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
bölgesinde, bazel test //etc/api:angular_devkit_core_api
ile böyle bir hedef çalıştırabilirsiniz.
Bu altın dosyanın zaman içinde 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ın aynısını uygular: Yerel bir bazel test-accept
komutu yoktur ancak aynı etki bazel run //etc/api:angular_devkit_core_api.accept
ile de elde edilebilir.
Bu kalıp oldukça güçlü olabilir ve tanımayı öğrendiğinizde oldukça yaygın olduğu ortaya çıkar.
Kendi kurallarınızı uyarlama
Makrolar bu kalıbın temelini oluşturur. Makrolar kurallar gibi kullanılsa da birkaç hedef oluşturabilir. Genellikle, belirtilen adla birincil derleme işlemini (ör. normal bir ikili program, Docker görüntüsü veya bir kaynak kodu arşivi derleme) gerçekleştiren bir hedef oluştururlar. 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 göstermek için, Sfenks içeren bir web sitesi oluşturan sanal bir kuralı, bir makroyla sarmalayın. Böylece, kullanıcının hazır olduğunda bu kuralı yayınlamasına izin veren ek bir hedef oluşturabilirsiniz. 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, ç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 yalnızca birincil hedefi oluşturuyormuş gibi kullanın:
sphinx_site(
name = "docs",
srcs = ["index.md", "providers.md"],
)
Bu örnekte, sanki makro standart, tek bir Bazel kuralıymış gibi bir "docs" hedefi oluşturulmuştur. Kural oluşturulduğunda bir yapılandırma oluşturur ve Sphinx'i çalıştırarak manuel inceleme için hazır bir HTML sitesi oluşturur. Bununla birlikte, ek bir "docs.publish" hedefi de oluşturulur. Böylece, siteyi yayınlamak için bir komut dosyası 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 nasıl uygulandığı hemen anlaşılmaz. 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. Daha sonra bu komut dosyası, 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.