İşlevler

Sorun bildir Kaynağı görüntüle Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

İçindekiler

paket

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

Bu işlev, paketteki her kural için geçerli olan meta verileri tanımlar. Bir pakette (BUILD dosyası) en fazla bir kez kullanılır.

Depo genelindeki her kural için geçerli olan meta verileri açıklayan karşı taraf için, deponuzun kökündeki REPO.bazel dosyasında repo() işlevini kullanın. repo() işlevi, package() işleviyle tam olarak aynı bağımsız değişkenleri alır.

package() işlevi, dosyanın üst kısmındaki tüm load() ifadelerinden hemen sonra, herhangi bir kuraldan önce çağrılmalıdır.

Bağımsız değişkenler

Özellik Açıklama
default_applicable_licenses

default_package_metadata için takma ad.

default_visibility

Etiketler listesi; varsayılan değer []'dir.

Bu paketteki üst düzey kural hedeflerinin ve sembolik makroların varsayılan görünürlüğü (yani, sembolik makro içinde tanımlanmayan hedefler ve sembolik makrolar). Hedef veya makro bir visibility değeri belirtiyorsa bu özellik yoksayılır.

Bu özelliğin söz dizimi hakkında ayrıntılı bilgi için görünürlük dokümanlarına bakın. Paketin varsayılan görünürlüğü, varsayılan olarak herkese açık olan exports_files için geçerli değildir.

default_deprecation

Dize; varsayılan değer ""'tir

Bu paketteki tüm kurallar için varsayılan deprecation mesajını ayarlar.

default_package_metadata

Etiketler listesi; varsayılan değer []'dir.

Paketteki diğer tüm hedefler için geçerli olan varsayılan bir meta veri hedefi listesi ayarlar. Bunlar genellikle açık kaynak paketi ve lisans beyanlarıyla ilgili hedeflerdir. Örnekler için rules_license bölümüne bakın.

default_testonly

Boole; belirtilmediği sürece varsayılan değer False'tür

Bu paketteki tüm kurallar için varsayılan testonly mülkünü ayarlar.

javatests altındaki paketlerde varsayılan değer True'dur.

features

Dize listesi; varsayılan değer []'tür.

Bu BUILD dosyasının anlamını etkileyen çeşitli işaretler ayarlar.

Bu özellik, genellikle derleme sisteminde çalışan kişiler tarafından bir tür özel işleme tabi tutulması gereken paketleri etiketlemek için kullanılır. Derleme sisteminde çalışan biri tarafından açıkça istenmediği sürece bunu kullanmayın.

Örnekler

Aşağıdaki beyan, bu paketteki kuralların yalnızca //foo:target paket grubunun üyelerine gösterileceğini belirtir. Bir kuralda varsa ayrı görünürlük beyanları bu spesifikasyonu geçersiz kılar.
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

Bu işlev, bir paket grubu tanımlar ve bir etiketi grupla ilişkilendirir. Etiket, visibility özelliklerinde referans olarak kullanılabilir.

Paket grupları öncelikle görünürlük kontrolü için kullanılır. Herkesin görebileceği bir hedefe kaynak ağacındaki her paketten referans verilebilir. Gizli olarak görünen bir hedefe yalnızca kendi paketi içinde (alt paketlerde değil) referans verilebilir. Bu iki uç nokta arasında bir hedef, kendi paketine ve bir veya daha fazla paket grubu tarafından açıklanan paketlerin herhangi birine erişime izin verebilir. Görünürlük sisteminin daha ayrıntılı bir açıklaması için visibility özelliğine bakın.

Belirli bir paket, packages özelliğiyle eşleşiyorsa veya includes özelliğinde belirtilen diğer paket gruplarından birinde zaten yer alıyorsa grupta yer aldığı kabul edilir.

Paket grupları teknik olarak hedeftir ancak kurallarla oluşturulmaz ve kendileri görünürlük korumasına sahip değildir.

Bağımsız değişkenler

Özellik Açıklama
name

Ad; zorunlu

Bu hedef için benzersiz bir ad.

packages

Dize listesi; varsayılan değer []'tir.

Sıfır veya daha fazla paket özelliğinin listesi.

Her paket spesifikasyonu dizesi aşağıdaki biçimlerden birinde olabilir:

  1. Deposu olmadan bir paketin tam adı, çift eğik çizgiyle başlar. Örneğin, //foo/bar, bu ada sahip ve paket grubuyla aynı depoda bulunan paketi belirtir.
  2. Yukarıdakiyle aynıdır ancak sonuna /... eklenir. Örneğin, //foo/..., //foo ve tüm alt paketlerini belirtir. //..., geçerli depodaki tüm paketleri belirtir.
  3. Sırasıyla her paketi veya hiçbir paketi belirten public ya da private dizeleri. (Bu form için --incompatible_package_group_has_public_syntax işaretinin ayarlanması gerekir.)

Ayrıca, ilk iki paket spesifikasyonu türü, reddedildiğini belirtmek için önlerine - eklenerek de yazılabilir.

Paket grubu, pozitif özelliklerinden en az biriyle eşleşen ve negatif özelliklerinden hiçbiriyle eşleşmeyen tüm paketleri içerir. Örneğin, [//foo/..., -//foo/tests/...] değeri, //foo'un //foo/tests'nin alt paketi olmayan tüm alt paketlerini içerir. (//foo kendisi dahil edilirken //foo/testler kendisi dahil edilmez.)

Herkese açık görünürlük dışında, mevcut deponun dışındaki paketleri doğrudan belirtmenin bir yolu yoktur.

Bu özellik eksikse boş bir listeye ayarlanmış gibi kabul edilir. Bu, yalnızca private içeren bir listeye ayarlanmış gibi kabul edilmekle aynıdır.

Not: Bazel 6.0'dan önce //... spesifikasyonunun davranışı, public ile aynı olan eski bir davranıştı. Bu davranış, Bazel 6.0'dan sonra varsayılan olarak etkinleştirilen --incompatible_fix_package_group_reporoot_syntax etkinleştirildiğinde düzeltilir.

Not: Bazel 6.0'dan önce bu özellik bazel query --output=proto (veya --output=xml) parçası olarak serileştirildiğinde ön eğik çizgiler atlanır. Örneğin, //pkg/foo/... \"pkg/foo/...\" olarak çıktı verir. Bu davranış, Bazel 6.0'dan sonra varsayılan olarak etkinleştirilen --incompatible_package_group_includes_double_slash etkinleştirildiğinde düzeltilir.

includes

Etiketler listesi; varsayılan değer []'dir.

Bu gruba dahil olan diğer paket grupları.

Bu özellikteki etiketler diğer paket gruplarına atıfta bulunmalıdır. Referans verilen paket gruplarındaki paketler bu paket grubunun bir parçası olarak kabul edilir. Bu ilişki geçişlidir. a paket grubu b paket grubunu, b ise c paket grubunu içeriyorsa c'deki her paket a'nin de üyesi olur.

Negatif paket özellikleriyle birlikte kullanıldığında, her grup için paket grubunun önce bağımsız olarak hesaplandığını ve ardından sonuçların birleştirildiğini unutmayın. Bu, bir gruptaki reddedilen özelliklerin başka bir gruptaki özellikleri etkilemediği anlamına gelir.

Örnekler

Aşağıdaki package_group beyanı, tropikal meyveler içeren "tropikal" adlı bir paket grubu belirtir.

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

Aşağıdaki beyanlar, kurgusal bir uygulamanın paket gruplarını belirtir:

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

exports_files

exports_files([label, ...], visibility, licenses)

exports_files(), bu pakete ait olup diğer paketlere aktarılan dosyaların listesini belirtir.

Bir paketin BUILD dosyası, yalnızca exports_files() ifadesiyle açıkça dışa aktarılan başka bir pakete ait kaynak dosyalara doğrudan referans verebilir. Dosyaların görünürlüğü hakkında daha fazla bilgi edinin.

Eski bir davranış olarak, bir kuralın girişi olarak belirtilen dosyalar da işaret --incompatible_no_implicit_file_export tıklanana kadar varsayılan görünürlükle dışa aktarılır. Ancak bu davranışa güvenilmemeli ve bu davranıştan aktif olarak uzaklaşılmalıdır.

Bağımsız değişkenler

Parametre, geçerli paketteki dosya adlarının listesidir. Görünürlük beyanı da belirtilebilir. Bu durumda, dosyalar belirtilen hedeflere görünür olur. Hiçbir görünürlük belirtilmezse dosyalar, package işlevinde bir paket varsayılan görünürlük belirtilmiş olsa bile her paket tarafından görülebilir. Lisanslar da belirtilebilir.

Örnek

Aşağıdaki örnekte, test_data paketindeki bir metin dosyası olan golden.txt dışa aktarılır. Böylece diğer paketler bu dosyayı (ör. testlerin data özelliğinde) kullanabilir.

# from //test_data/BUILD

exports_files(["golden.txt"])

glob

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

Glob, belirli yol kalıplarıyla eşleşen tüm dosyaları bulan ve yollarının yeni, değiştirilebilir, sıralanmış bir listesini döndüren bir yardımcı işlevdir. Glob yalnızca kendi paketindeki dosyaları arar ve yalnızca kaynak dosyaları (oluşturulan dosyaları veya diğer hedefleri değil) arar.

Dosyanın pakete göre yolu include kalıplarından herhangi biriyle eşleşiyorsa ve exclude kalıplarından hiçbiriyle eşleşmiyorsa kaynak dosyanın etiketi sonuca dahil edilir.

include ve exclude listeleri, mevcut pakete göre yol kalıplarını içerir. Her desen bir veya daha fazla yol segmentinden oluşabilir. Unix yollarında olduğu gibi, bu segmentler / ile ayrılır. Kalıptaki segmentler, yolun segmentleriyle eşleştirilir. Segmentler * joker karakterini içerebilir: Bu karakter, dizin ayırıcı / hariç olmak üzere yol segmentindeki herhangi bir alt dizeyle (boş alt dize dahil) eşleşir. Bu joker karakter, tek bir yol segmentinde birden çok kez kullanılabilir. Ayrıca ** joker karakteri sıfır veya daha fazla tam yol segmentiyle eşleşebilir ancak bağımsız bir yol segmenti olarak tanımlanmalıdır.

Örnekler:
  • foo/bar.txt, bu paketteki foo/bar.txt dosyasıyla tam olarak eşleşiyor (foo/ alt paket değilse)
  • foo/*.txt, dosya .txt ile bitiyorsa (foo/ alt paket olmadığı sürece) foo/ dizinindeki her dosyayla eşleşir.
  • foo/a*.htm*, foo/ dizininde a ile başlayan, ardından rastgele bir dize (boş olabilir) içeren, ardından .htm içeren ve başka bir rastgele dizeyle biten (foo/ alt paket olmadığı sürece) her dosyayı eşleştirir. Örneğin, foo/axx.htm ve foo/a.html veya foo/axxx.html
  • foo/*, foo/ dizinindeki her dosyayla eşleşir (foo/ bir alt paket değilse); exclude_directories 0 olarak ayarlanmış olsa bile foo dizininin kendisiyle eşleşmez
  • foo/**, paketin birinci düzey alt dizini foo/ altındaki alt paket olmayan her alt dizindeki her dosyayı eşleştirir; exclude_directories 0 olarak ayarlanırsa foo dizini de kalıpla eşleşir; bu durumda **'in sıfır yol segmentiyle eşleştiği kabul edilir
  • **/a.txt, bu paketin dizininde ve alt paket olmayan alt dizinlerde a.txt dosyalarıyla eşleşir.
  • **/bar/**/*.txt, elde edilen yolda en az bir dizin bar olarak adlandırılıyorsa (xxx/bar/yyy/zzz/a.txt veya bar/a.txt gibi) bu paketin alt paket olmayan her alt dizinindeki her .txt dosyasıyla eşleşir (**'in sıfır segmentle de eşleştiğini unutmayın) veya bar/zzz/a.txt
  • **, bu paketin alt paket olmayan her alt dizinindeki her dosyayla eşleşir
  • ** bir segment olarak tek başına durması gerektiği için foo**/a.txt geçersiz bir kalıptır
  • /'dan sonra tanımlanan ikinci segment boş bir dize olduğu için foo/ geçersiz bir kalıptır.

exclude_directories bağımsız değişkeni etkinleştirilirse (1 olarak ayarlanırsa) dizin türündeki dosyalar sonuçlardan çıkarılır (varsayılan 1).

allow_empty bağımsız değişkeni False olarak ayarlanırsa sonuç boş liste olacaksa glob işlevi hata verir.

Birkaç önemli sınırlama ve uyarı vardır:

  1. glob(), BUILD dosya değerlendirmesi sırasında çalıştığından yalnızca kaynak ağacınızdaki dosyalarla eşleşir, oluşturulan dosyalarla hiçbir zaman eşleşmez.glob() Hem kaynak hem de oluşturulmuş dosyalar gerektiren bir hedef oluşturuyorsanız oluşturulmuş dosyaların açık bir listesini glob'a eklemeniz gerekir. :mylib ve :gen_java_srcs ile ilgili aşağıdaki örneğe bakın.

  2. Bir kural, eşleşen bir kaynak dosyayla aynı ada sahipse dosyayı "gölgeler".

    Bunu anlamak için glob()'ün bir yol listesi döndürdüğünü unutmayın.Bu nedenle, diğer kuralların özelliğinde (ör. srcs = glob(["*.cc"])) glob() kullanmak, eşleşen yolları açıkça listelemekle aynı etkiye sahiptir. Örneğin, glob() ["Foo.java", "bar/Baz.java"] sonucunu verirse ancak pakette "Foo.java " adlı bir kural da varsa (buna izin verilir ancak Bazel bu konuda uyarı verir) glob()'nin tüketicisi "Foo.java" dosyası yerine "Foo.java" kuralını (çıktılarını) kullanır. Daha fazla bilgi için GitHub 10395 numaralı sorunu inceleyin.

  3. Glob'lar, alt dizinlerdeki dosyalarla eşleşebilir. Alt dizin adlarında joker karakter kullanılabilir. Ancak...
  4. Etiketlerin paket sınırını aşmasına izin verilmez ve glob, alt paketlerdeki dosyalarla eşleşmez.

    Örneğin, x/y bir paket olarak mevcutsa (x/y/BUILD olarak veya package-path'te başka bir yerde) x paketindeki **/*.cc genel ifadesi x/y/z.cc değerini içermez. Bu, glob ifadesinin sonucunun aslında BUILD dosyalarının varlığına bağlı olduğu anlamına gelir. Yani x/y adlı bir paket yoksa veya --deleted_packages işaretçisi kullanılarak silinmiş olarak işaretlendiyse aynı glob ifadesi x/y/z.cc değerini içerir.

  5. Yukarıdaki kısıtlama, hangi joker karakterleri kullandıklarına bakılmaksızın tüm glob ifadeleri için geçerlidir.
  6. . ile başlayan dosya adı, hem ** hem de * joker karakterleriyle tamamen eşleşir. Gizli bir dosyayı birleşik bir desenle eşleştirmek isterseniz deseninizin . ile başlaması gerekir. Örneğin, * ve .*.txt, .foo.txt ile eşleşir ancak *.txt ile eşleşmez. Gizli dizinler de aynı şekilde eşlenir. Gizli dizinler, giriş olarak gerekli olmayan dosyalar içerebilir ve gereksiz yere glob ile birleştirilen dosyaların sayısını ve bellek tüketimini artırabilir. Gizli dizinleri hariç tutmak için "hariç tut" liste bağımsız değişkenine ekleyin.
  7. "**" joker karakterinin tek bir özel durumu vardır: "**" kalıbı, paketin dizin yoluyla eşleşmez. Yani glob(["**"], exclude_directories = 0), geçerli paketin dizininin altındaki tüm dosya ve dizinlerle kesinlikle geçişli olarak eşleşir (ancak tabii ki alt paketlerin dizinlerine girmez. Bu konuyla ilgili önceki notu inceleyin).

Genel olarak, bir genel ifade kalıbı için yalnızca "*" kullanmak yerine uygun bir uzantı (ör. *.html) sağlamaya çalışmalısınız. Daha açık bir ad hem kendi kendini açıklayıcıdır hem de yedek dosyaları veya emacs/vi/... otomatik kayıt dosyalarını yanlışlıkla eşleştirmenizi önler.

Derleme kuralları yazarken glob öğelerini sayabilirsiniz. Bu sayede, örneğin her giriş için ayrı kurallar oluşturabilirsiniz. Aşağıdaki genişletilmiş glob örneği bölümüne bakın.

Glob Örnekleri

Bu dizindeki tüm Java dosyalarından ve :gen_java_srcs kuralı tarafından oluşturulan tüm dosyalardan bir Java kitaplığı oluşturun.

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

experimental.txt dışındaki tüm txt dosyalarını testdata dizinine ekleyin. testdata alt dizinlerindeki dosyaların dahil edilmeyeceğini unutmayın. Bu dosyaların dahil edilmesini istiyorsanız yinelenen bir glob (**) kullanın.

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

Yinelenen Glob Örnekleri

Testin, testdata dizinindeki ve alt dizinlerindeki (ve alt dizinlerinin vb.) tüm txt dosyalarına bağlı olmasını sağlayın. BUILD dosyası içeren alt dizinler yoksayılır. (Yukarıdaki sınırlamalara ve uyarılara bakın.)

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

Bu dizindeki ve yolları testing adlı bir dizin içerenler hariç tüm alt dizinlerdeki tüm Java dosyalarından oluşturulmuş bir kitaplık oluşturun. Olasıysa bu kalıptan kaçının. Bu kalıp, artımlı derlemeyi azaltıp derleme sürelerini uzatabilir.

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

Genişletilmiş Glob Örnekleri

Geçerli dizinde *_test.cc için dosyanın satır sayısını sayan ayrı bir genrule oluşturun.

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

Yukarıdaki BUILD dosyası //foo paketindeyse ve pakette a_test.cc, b_test.cc ve c_test.cc adlı üç eşleşen dosya varsa bazel query '//foo:all' çalıştırıldığında oluşturulan tüm kurallar listelenir:

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

seç

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select(), kural özelliğini yapılandırılabilir hale getiren yardımcı işlevdir. Neredeyse tüm özellik atamalarını değiştirebileceğinden, değeri komut satırı Bazel işaretlerine bağlıdır. Örneğin, platforma özgü bağımlılıkları tanımlamak veya bir kuralın "geliştirici" modunda mı yoksa "sürüm" modunda mı oluşturulduğuna bağlı olarak farklı kaynaklar yerleştirmek için bu özelliği kullanabilirsiniz.

Temel kullanım şu şekildedir:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

Bu, normal etiket listesi atamasını, yapılandırma koşullarını eşleşen değerlerle eşleyen bir select çağrısıyla değiştirerek bir sh_binary öğesinin srcs özelliğini yapılandırılabilir hale getirir. Her koşul, bir config_setting veya constraint_value değerine referans veren bir etikettir. Hedefin yapılandırması beklenen bir değer kümesiyle eşleşirse bu etiket "eşleşir". mytarget#srcs değeri, geçerli çağrıyla eşleşen etiket listesine dönüşür.

Notlar:

  • Her çağrıda tam olarak bir koşul seçilir.
  • Birden fazla koşul eşleşirse ve bunlardan biri diğerlerinin uzmanlık alanıysa uzmanlık önceliklidir. B koşulu, A koşuluyla aynı işaretlere ve kısıtlama değerlerine sahipse ve bazı ek işaretler veya kısıtlama değerlerine sahipse A koşulunun bir uzmanlığı olarak kabul edilir. Bu durum, aşağıdaki 2. örnekte gösterildiği gibi uzmanlık çözümünün bir sıralama oluşturmak için tasarlanmadığı anlamına da gelir.
  • Birden fazla koşul eşleşirse ve bunlardan biri diğerlerinin özelleşmesi değilse tüm koşullar aynı değere çözüm bulmazsa Bazel hatayla başarısız olur.
  • Başka bir koşul eşleşmezse özel sözde etiket //conditions:default'ün eşleştiği kabul edilir. Bu koşul atlanırsa hata olmaması için başka bir kuralın eşleşmesi gerekir.
  • select, daha büyük bir özellik atamasına yerleştirilebilir. Dolayısıyla srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) ve srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) geçerli ifadelerdir.
  • select, özelliklerin çoğuyla ancak hepsiyle çalışmaz. Uyumlu olmayan özellikler, dokümanlarda nonconfigurable ile işaretlenir.

    alt paketler

    subpackages(include, exclude=[], allow_empty=True)

    subpackages(), dosya ve dizinler yerine alt paketleri listeleyen glob()'a benzer bir yardımcı işlevdir. glob() ile aynı yol kalıplarını kullanır ve şu anda yüklenen BUILD dosyasının doğrudan alt öğesi olan tüm alt paketlerle eşleşebilir. Dahil etme ve hariç tutma kalıplarıyla ilgili ayrıntılı açıklama ve örnekler için glob işlevine bakın.

    Sonuç olarak döndürülen alt paket listesi sıralı olarak listelenir ve mevcut yükleme paketine göre exclude'daki değil, include'teki belirli kalıplarla eşleşen yollar içerir.

    Örnek

    Aşağıdaki örnekte, foo/BUILD paketine ait tüm doğrudan alt paketler listelenmiştir.

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/bar/but/bad/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs1 = subpackages(include = ["**"])
    
    # results in subs1 == ["sub", "bar/baz", "bar/but/bad"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    
    subs2 = subpackages(include = ["bar/*"])
    # results in subs2 = ["bar/baz"]
    #
    # Since 'bar' is not a subpackage itself, this looks for any subpackages under
    # all first level subdirectories of 'bar'.
    
    subs3 = subpackages(include = ["bar/**"])
    # results in subs3 = ["bar/baz", "bar/but/bad"]
    #
    # Since bar is not a subpackage itself, this looks for any subpackages which are
    # (1) under all subdirectories of 'bar' which can be at any level, (2) not a
    # subpackage of another subpackages.
    
    subs4 = subpackages(include = ["sub"])
    subs5 = subpackages(include = ["sub/*"])
    subs6 = subpackages(include = ["sub/**"])
    # results in subs4 and subs6 being ["sub"]
    # results in subs5 = [].
    #
    # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a
    # subpackage of 'foo').
    # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since
    # 'foo/sub' is already a subpackage itself, the subdirectories will not be
    # traversed anymore.
    # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it
    # is returned. But the subdirectories of 'foo/sub' will not be traversed
    # anymore.
    

    Genel olarak, kullanıcıların bu işlevi doğrudan çağırmak yerine skylib'in "subpackages" modülünü kullanması tercih edilir.