Özel Fiiller Oluşturmak için Makroları Kullanma

Sorun bildir Kaynağı göster Gece · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Bazel ile günlük etkileşim öncelikle birkaç komut aracılığıyla gerçekleşir: build, test ve run. Ancak zaman zaman bu görüşler kısıtlanabilir. paketleri bir depoya aktarmak, son kullanıcılar için belge yayınlamak veya Kubernetes ile uygulama dağıtma. Ancak Bazel'ın bir publish veya deploy komutu – bu işlemler nerede yer alır?

Bazel çalıştırma komutu

Bazel'in hermetiklik, tekrar üretilebilirlik ve artımlılığa odaklanması, build ve test komutları yukarıdaki görevler için faydalı değil. Bu işlemler sınırlı ağ erişimi olan bir korumalı alanda çalışabilir ve her bazel build ile tekrar çalıştır.

Bunun yerine, sahip olmak istediğiniz görevler için destek sağlayan bazel run teknolojisinden yararlanın. yardımcı olabilir. Bazel kullanıcıları yürütülebilir dosyalar oluşturan kurallara alışkındır ve kural yazarları bunu genişletmek için ortak bir kalıplar kümesi izleyebilir "özel fiiller".

Vahşi yaşam: rules_k8s

Örneğin, rules_k8s, Bazel için Kubernetes kurallarını gözden geçireceğiz. 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 üzerinde bazel build kullanıldığında standart Kubernetes YAML dosyası hedefi belirleyebilirsiniz. Ancak ek hedefler k8s_object tarafından da oluşturulur. makrosu staging.apply ve :staging.delete gibi adlara sahiptir. Bu derleme komut dosyaları kullanabilir 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. İlgili içeriği oluşturmak için kullanılan ts_api_guardian_test makrosu iki hedef oluşturur. İlki standart bir nodejs_test hedefidir. "altın" yerine üretilmiş bir çıktı dosyası (yani beklenen çıktı). Bu özellik, normal bir bazel test çağrısıyla derlenip çalıştırılabilir. angular-cli üzerinde böyle bir hedef bazel test //etc/api:angular_devkit_core_api ile.

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 makronun karşılaştırmak yerine altın dosyayı güncelleyen bir nodejs_binary hedefi çıkar. Aynı test komut dosyası "doğrula"da çalışacak şekilde yazılabilir veya "kabul et" yöntemini çağırın. Bu, aynı kalıbı izler zaten öğrenmiş olduğunuz gibi, yerel bir bazel test-accept komutu yoktur ancak aynı etkiye başkalarını da bazel run //etc/api:angular_devkit_core_api.accept.

Bu kalıp oldukça güçlü olabilir ve bir kerede yeni bir onu tanımayı öğrenirsiniz.

Kendi kurallarınızı uyarlama

Makrolar bu kalıbın temelini oluşturur. Makrolar, fakat birkaç hedef oluşturabilirler. Genellikle bir birincil derleme işlemini gerçekleştiren, belirtilen ada sahip bir hedef: belki normal bir ikili program, bir Docker görüntüsü veya bir kaynak kod arşivi oluşturur. İçinde performans gösteren komut dosyaları oluşturmak için ek hedefler oluşturulur birincil hedefin çıktısına dayalı olarak ortaya çıkan etkiler (ör. sonuçta kalan ikili dosyayı veya beklenen test çıkışını günceller.

Bunu göstermek için, bir web sitesi oluşturan hayali bir kuralı Ek oluşturmak için bir makro içeren Sfenks Kullanıcının hazır olduğunda yayınlamasına olanak tanıyan bir hedef belirler. Aşağıdakileri göz önünde bulundurun mevcut kurala göre Sfenks içeren bir web sitesi oluşturabilirsiniz:

_sphinx_site = rule(
     implementation = _sphinx_impl,
     attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
)

Daha sonra, çalıştırıldığında , oluşturulan sayfaları yayınlar:

_sphinx_publisher = rule(
    implementation = _publish_impl,
    attrs = {
        "site": attr.label(),
        "_publisher": attr.label(
            default = "//internal/sphinx:publisher",
            executable = True,
        ),
    },
    executable = True,
)

Son olarak, yukarıdakilerin her ikisi için de hedefler oluşturmak üzere aşağıdaki makroyu tanımlayın bir araya getirir:

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 hedef:

sphinx_site(
    name = "docs",
    srcs = ["index.md", "providers.md"],
)

Bu örnekte, bir "docs" otomatik bir hedef oluşturulur. standart, tek Bazel kuralı. 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, ek bir "docs.publish" oluşturulan bir hedef de oluşturulur. Bu komut dosyası, en iyi yoludur. Birincil hedefin çıkışını kontrol ettikten sonra gibi herkesin kullanımına açık olarak yayınlamak için bazel run :docs.publish kullanabilirsiniz. hayali bir bazel publish komutu içerir.

_sphinx_publisher işlevinin ne anlama geldiği hemen anlaşılmıyor. görünebilir. Genellikle, bunun gibi işlemler bir başlatıcı kabuk komut dosyası yazar. Bu yöntem genelde ctx.actions.expand_template kullanarak çok basit bir kabuk komut dosyası yazın. Bu örnekte, birincil hedefin çıkışına giden bir yol ile birlikte. Bu şekilde yayıncı genel kalabilir, _sphinx_site kuralı yalnızca ve bu küçük komut dosyası, bu ikisini birleştirmek için gereken tek şeydir birlikte.

.apply, rules_k8s ayında gerçekten bunu yapıyor: expand_template temel olarak çok basit bir Bash komut dosyası yazar apply.sh.tpl, birincil hedefin çıkışıyla kubectl çalıştıran bir sayfa oluşturun. Bu komut dosyası kullanarak bazel run :staging.apply ile derlemenizi ve çalıştırmanızı sağlar. k8s_object hedefleri için k8s-apply komutu.