diff --git a/README.md b/README.md index a648ca5..4ce7710 100644 --- a/README.md +++ b/README.md @@ -304,7 +304,7 @@ Language ecosystems and development tools across multiple categories. **Docs:** Docsify, Documenter.jl, Docusaurus, Dokka, Doxygen, ExDoc, Hugo, Javadoc, Jekyll, MkDocs, MultiQC, MyST-Parser, Nextra, Quarto, R Markdown, Read the Docs, Redoc, Sphinx, Starlight, Storybook, Swagger UI, TypeDoc, VitePress, Yard, Zensical, cargo doc, dart doc, deno doc, knitr, mdBook, phpDocumentor, pkgdown, pkgsite, roxygen2. -**Build:** Actix Web, AdonisJS, Angular, Astro, Autotools, Axum, Babashka, BitBake, CMake, Django, Dune, Echo, Electron, Eleventy, Ember.js, Express, FastAPI, Fastify, Fiber, Flask, Flutter, Foundry, Gatsby, Gin, GoReleaser, Hardhat, Hono, Invoke, Just, Koa, Laravel, Less, Mage, Make, Meson, Meteor, NestJS, Next.js, Nextflow, Nuxt, Parcel, Phoenix, PostCSS, Qwik, Rails, Rake, React Native, Remix, Rocket, Rollup, Rspack, SWC, Sass, Sinatra, Snakemake, Spin, Spring Boot, Svelte, SvelteKit, Symfony, Task, Tauri, Vite, Vue, Webpack, cibuildwheel, cross, esbuild, nf-core, targets, tsup. +**Build:** Actix Web, AdonisJS, Angular, Arch Linux Packaging, Astro, Autotools, Axum, Babashka, BitBake, CMake, Conda Build, Debian Packaging, Django, Dune, Echo, Electron, Eleventy, Ember.js, Express, FastAPI, Fastify, Fiber, Flask, Flutter, Foundry, FreeBSD pkg, Gatsby, Gin, GoReleaser, Hardhat, Hono, Invoke, Just, Koa, Laravel, Less, Mage, Make, Meson, Meteor, NestJS, Next.js, Nextflow, Nuxt, Parcel, Phoenix, PostCSS, Qwik, Rails, Rake, React Native, Remix, Rocket, Rollup, Rspack, SWC, Sass, Sinatra, Snakemake, Spin, Spring Boot, Svelte, SvelteKit, Symfony, Task, Tauri, Vite, Vue, Webpack, cibuildwheel, cross, esbuild, nf-core, targets, tsup. **Native Ext:** Maturin, Neon, Rustler, meson-python, mkmf, napi-rs, node-gyp, phpize, rb-sys, setuptools Extension, setuptools-rust. diff --git a/detect/package_build_tools_test.go b/detect/package_build_tools_test.go new file mode 100644 index 0000000..75b8824 --- /dev/null +++ b/detect/package_build_tools_test.go @@ -0,0 +1,153 @@ +package detect + +import ( + "slices" + "testing" +) + +func TestPackageBuildToolSignals(t *testing.T) { + tests := []struct { + name string + path string + content string + tool string + config bool + }{ + { + name: "Conda legacy YAML recipe", + path: "meta.yaml", + content: "package:\n name: example\n version: 1.0.0\n", + tool: "Conda Build", + config: true, + }, + { + name: "Conda legacy YML recipe", + path: "meta.yml", + content: "package:\n name: example\n version: 1.0.0\n", + tool: "Conda Build", + config: true, + }, + { + name: "Conda feedstock YAML recipe", + path: "recipe/meta.yaml", + content: "package:\n name: example\n version: 1.0.0\n", + tool: "Conda Build", + config: true, + }, + { + name: "Conda feedstock YML recipe", + path: "recipe/meta.yml", + content: "package:\n name: example\n version: 1.0.0\n", + tool: "Conda Build", + config: true, + }, + { + name: "Conda v1 YAML recipe", + path: "recipe/recipe.yaml", + content: "schema_version: 1\npackage:\n name: example\n version: 1.0.0\n", + tool: "Conda Build", + config: true, + }, + { + name: "Conda v1 YML recipe", + path: "recipe/recipe.yml", + content: "schema_version: 1\npackage:\n name: example\n version: 1.0.0\n", + tool: "Conda Build", + config: true, + }, + { + name: "Arch SRCINFO metadata", + path: ".SRCINFO", + content: "pkgbase = example\npkgver = 1.0.0\npkgrel = 1\npkgname = example\n", + tool: "Arch Linux Packaging", + config: true, + }, + { + name: "Arch legacy AURINFO metadata", + path: ".AURINFO", + content: "pkgname = example\npkgver = 1.0.0\npkgrel = 1\n", + tool: "Arch Linux Packaging", + config: true, + }, + { + name: "Arch package metadata", + path: ".PKGINFO", + content: "pkgname = example\npkgver = 1.0.0-1\narch = any\n", + tool: "Arch Linux Packaging", + }, + { + name: "Debian control file", + path: "debian/control", + content: "Source: example\nMaintainer: Example \n\nPackage: example\nArchitecture: any\n", + tool: "Debian Packaging", + config: true, + }, + { + name: "Debian source control file", + path: "example_1.0-1.dsc", + content: "Format: 3.0 (quilt)\nSource: example\nVersion: 1.0-1\n", + tool: "Debian Packaging", + }, + { + name: "FreeBSD compact manifest", + path: "+COMPACT_MANIFEST", + content: "{\"name\":\"example\",\"version\":\"1.0.0\"}\n", + tool: "FreeBSD pkg", + }, + } + + knowledgeBase := loadKB(t) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + dir := t.TempDir() + writeProjectFile(t, dir, test.path, test.content) + + report, err := New(knowledgeBase, dir).Run() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + assertToolDetected(t, report, "build", test.tool) + for _, tool := range report.Tools["build"] { + if tool.Name == test.tool { + if got := slices.Contains(tool.ConfigFiles, test.path); got != test.config { + t.Errorf("config files = %v, contains %q = %v, want %v", tool.ConfigFiles, test.path, got, test.config) + } + break + } + } + }) + } +} + +func TestPackageBuildToolFixtures(t *testing.T) { + tests := []struct { + fixture string + tool string + }{ + {fixture: "conda-build-project", tool: "Conda Build"}, + {fixture: "arch-linux-package-project", tool: "Arch Linux Packaging"}, + {fixture: "debian-package-project", tool: "Debian Packaging"}, + {fixture: "freebsd-package-project", tool: "FreeBSD pkg"}, + } + + for _, test := range tests { + t.Run(test.tool, func(t *testing.T) { + report := runOn(t, "../testdata/"+test.fixture) + assertToolDetected(t, report, "build", test.tool) + }) + } +} + +func TestCondaBuildOffersRattlerBuildForV1Recipes(t *testing.T) { + report := runOn(t, "../testdata/conda-build-project") + for _, tool := range report.Tools["build"] { + if tool.Name != "Conda Build" { + continue + } + if tool.Command == nil || !slices.Contains(tool.Command.Alternatives, "rattler-build build") { + t.Fatalf("Conda Build command = %+v, want rattler-build alternative", tool.Command) + } + return + } + t.Fatal("expected Conda Build in build category") +} diff --git a/knowledge/_shared/arch-linux-packaging.toml b/knowledge/_shared/arch-linux-packaging.toml new file mode 100644 index 0000000..6807288 --- /dev/null +++ b/knowledge/_shared/arch-linux-packaging.toml @@ -0,0 +1,20 @@ +[tool] +name = "Arch Linux Packaging" +category = "build" +homepage = "https://wiki.archlinux.org/title/Creating_packages" +docs = "https://man.archlinux.org/man/makepkg.8" +repo = "https://gitlab.archlinux.org/pacman/pacman" +description = "Builds and describes packages for Arch Linux" + +[detect] +files = [".SRCINFO", ".AURINFO", ".PKGINFO"] + +[commands] +run = "makepkg" +alternatives = ["makepkg --printsrcinfo"] + +[config] +files = [".SRCINFO", ".AURINFO"] + +[taxonomy] +role = ["build-tool"] diff --git a/knowledge/_shared/conda-build.toml b/knowledge/_shared/conda-build.toml new file mode 100644 index 0000000..b91a292 --- /dev/null +++ b/knowledge/_shared/conda-build.toml @@ -0,0 +1,20 @@ +[tool] +name = "Conda Build" +category = "build" +homepage = "https://docs.conda.io/projects/conda-build/" +docs = "https://docs.conda.io/projects/conda-build/en/stable/" +repo = "https://github.com/conda/conda-build" +description = "Builds conda packages from recipe metadata" + +[detect] +files = ["meta.yaml", "meta.yml", "recipe/meta.yaml", "recipe/meta.yml", "recipe/recipe.yaml", "recipe/recipe.yml"] + +[commands] +run = "conda-build ." +alternatives = ["rattler-build build", "conda render ."] + +[config] +files = ["meta.yaml", "meta.yml", "recipe/meta.yaml", "recipe/meta.yml", "recipe/recipe.yaml", "recipe/recipe.yml"] + +[taxonomy] +role = ["build-tool"] diff --git a/knowledge/_shared/debian-packaging.toml b/knowledge/_shared/debian-packaging.toml new file mode 100644 index 0000000..9a6a5c3 --- /dev/null +++ b/knowledge/_shared/debian-packaging.toml @@ -0,0 +1,20 @@ +[tool] +name = "Debian Packaging" +category = "build" +homepage = "https://www.debian.org/doc/manuals/maint-guide/" +docs = "https://www.debian.org/doc/debian-policy/" +repo = "https://salsa.debian.org/dpkg-team/dpkg" +description = "Builds and describes Debian source and binary packages" + +[detect] +files = ["debian/control", "*.dsc"] + +[commands] +run = "dpkg-buildpackage" +alternatives = ["debuild"] + +[config] +files = ["debian/control"] + +[taxonomy] +role = ["build-tool"] diff --git a/knowledge/_shared/freebsd-pkg.toml b/knowledge/_shared/freebsd-pkg.toml new file mode 100644 index 0000000..d3e8c0b --- /dev/null +++ b/knowledge/_shared/freebsd-pkg.toml @@ -0,0 +1,16 @@ +[tool] +name = "FreeBSD pkg" +category = "build" +homepage = "https://github.com/freebsd/pkg" +docs = "https://man.freebsd.org/cgi/man.cgi?query=pkg-create&sektion=8" +repo = "https://github.com/freebsd/pkg" +description = "Creates and describes binary packages for FreeBSD" + +[detect] +files = ["+COMPACT_MANIFEST"] + +[commands] +run = "pkg create" + +[taxonomy] +role = ["build-tool"] diff --git a/testdata/arch-linux-package-project/.SRCINFO b/testdata/arch-linux-package-project/.SRCINFO new file mode 100644 index 0000000..06f72da --- /dev/null +++ b/testdata/arch-linux-package-project/.SRCINFO @@ -0,0 +1,7 @@ +pkgbase = example + pkgdesc = Example package + pkgver = 1.0.0 + pkgrel = 1 + arch = any + +pkgname = example diff --git a/testdata/conda-build-project/recipe/recipe.yaml b/testdata/conda-build-project/recipe/recipe.yaml new file mode 100644 index 0000000..5274dcb --- /dev/null +++ b/testdata/conda-build-project/recipe/recipe.yaml @@ -0,0 +1,4 @@ +schema_version: 1 +package: + name: example + version: 1.0.0 diff --git a/testdata/debian-package-project/debian/control b/testdata/debian-package-project/debian/control new file mode 100644 index 0000000..b77008a --- /dev/null +++ b/testdata/debian-package-project/debian/control @@ -0,0 +1,9 @@ +Source: example +Section: devel +Priority: optional +Maintainer: Example Maintainer +Standards-Version: 4.7.2 + +Package: example +Architecture: any +Description: Example package diff --git a/testdata/freebsd-package-project/+COMPACT_MANIFEST b/testdata/freebsd-package-project/+COMPACT_MANIFEST new file mode 100644 index 0000000..b8eddd6 --- /dev/null +++ b/testdata/freebsd-package-project/+COMPACT_MANIFEST @@ -0,0 +1,6 @@ +{ + "name": "example", + "version": "1.0.0", + "origin": "devel/example", + "comment": "Example package" +}