///|
/// A recipe owns target metadata and the functions that produce commands.
/// Adding a target means registering one value here; the planner and CLI do
/// not dispatch on target identifiers.
priv struct Recipe {
target : Target
set_commands : (Source, Scope) -> Array[Command]
get_commands : (Scope) -> Array[Command]
restore_commands : (ArrayView[SavedValue], Scope) -> Array[Command] raise PlanError
capture_command : (Int, StringView) -> SavedValue
set_file_steps : (Source, Scope) -> Array[FileStep]
get_file_steps : (Scope) -> Array[FileStep]
restore_file_steps : (ArrayView[SavedValue], Scope) -> Array[FileStep]
}
///|
fn no_set_file_steps(_source : Source, _scope : Scope) -> Array[FileStep] {
[]
}
///|
fn no_get_file_steps(_scope : Scope) -> Array[FileStep] {
[]
}
///|
fn no_restore_file_steps(
_values : ArrayView[SavedValue],
_scope : Scope,
) -> Array[FileStep] {
[]
}
///|
fn recipes() -> Array[Recipe] {
[
{
target: {
id: "npm",
name: "npm registry",
aliases: [],
scopes: [Project, User, System],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://registry.npmjs.org/", },
{ mirror_id: "npmmirror", url: "https://registry.npmmirror.com/", },
],
},
set_commands: (source, scope) => [npm_command(source, scope)],
get_commands: scope => [npm_get_command(scope)],
restore_commands: (values, scope) => {
require_snapshot_size("npm", values, 1)
[npm_restore_command(values[0], scope)]
},
capture_command: capture_value,
set_file_steps: no_set_file_steps,
get_file_steps: no_get_file_steps,
restore_file_steps: no_restore_file_steps,
},
{
target: {
id: "pnpm",
name: "pnpm registry",
aliases: [],
scopes: [Project, User],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://registry.npmjs.org/", },
{ mirror_id: "npmmirror", url: "https://registry.npmmirror.com/", },
],
},
set_commands: (source, scope) => [pnpm_command(source, scope)],
get_commands: scope => [pnpm_get_command(scope)],
restore_commands: (values, scope) => {
require_snapshot_size("pnpm", values, 1)
[pnpm_restore_command(values[0], scope)]
},
capture_command: capture_value,
set_file_steps: no_set_file_steps,
get_file_steps: no_get_file_steps,
restore_file_steps: no_restore_file_steps,
},
{
target: {
id: "yarn",
name: "Yarn registry (Yarn 2+)",
aliases: [],
scopes: [Project, User],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://registry.yarnpkg.com/", },
{ mirror_id: "npmmirror", url: "https://registry.npmmirror.com/", },
],
},
set_commands: (source, scope) => [yarn_command(source, scope)],
get_commands: _ => [yarn_get_command()],
restore_commands: (values, scope) => {
require_snapshot_size("yarn", values, 1)
[yarn_restore_command(values[0], scope)]
},
capture_command: capture_value,
set_file_steps: no_set_file_steps,
get_file_steps: no_get_file_steps,
restore_file_steps: no_restore_file_steps,
},
{
target: {
id: "node",
name: "Node.js package manager registries",
aliases: ["nodejs"],
scopes: [Project, User],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://registry.npmjs.org/", },
{ mirror_id: "npmmirror", url: "https://registry.npmmirror.com/", },
],
},
set_commands: (source, scope) => {
[
npm_command(source, scope),
pnpm_command(source, scope),
yarn_command(source, scope),
]
},
get_commands: scope => {
[npm_get_command(scope), pnpm_get_command(scope), yarn_get_command()]
},
restore_commands: (values, scope) => {
require_snapshot_size("node", values, 3)
[
npm_restore_command(values[0], scope),
pnpm_restore_command(values[1], scope),
yarn_restore_command(values[2], scope),
]
},
capture_command: capture_value,
set_file_steps: no_set_file_steps,
get_file_steps: no_get_file_steps,
restore_file_steps: no_restore_file_steps,
},
{
target: {
id: "pip",
name: "Python package index",
aliases: ["python", "pypi"],
scopes: [Project, User, System],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://pypi.org/simple", },
{
mirror_id: "tuna",
url: "https://pypi.tuna.tsinghua.edu.cn/simple",
},
{ mirror_id: "ustc", url: "https://pypi.mirrors.ustc.edu.cn/simple", },
],
},
set_commands: (source, scope) => [pip_command(source, scope)],
get_commands: scope => [pip_get_command(scope)],
restore_commands: (values, scope) => {
require_snapshot_size("pip", values, 1)
[pip_restore_command(values[0], scope)]
},
capture_command: capture_value,
set_file_steps: no_set_file_steps,
get_file_steps: no_get_file_steps,
restore_file_steps: no_restore_file_steps,
},
{
target: {
id: "go",
name: "Go module proxy",
aliases: ["golang"],
scopes: [User],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://proxy.golang.org,direct", },
{ mirror_id: "goproxycn", url: "https://goproxy.cn,direct", },
],
},
set_commands: (source, _) => [go_command(source)],
get_commands: _ => [go_get_command()],
restore_commands: (values, _) => {
require_snapshot_size("go", values, 1)
[go_restore_command(values[0])]
},
capture_command: capture_value,
set_file_steps: no_set_file_steps,
get_file_steps: no_get_file_steps,
restore_file_steps: no_restore_file_steps,
},
{
target: {
id: "composer",
name: "PHP Composer repository",
aliases: ["packagist"],
scopes: [Project, User],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://repo.packagist.org", },
{ mirror_id: "aliyun", url: "https://mirrors.aliyun.com/composer/", },
],
},
set_commands: (source, scope) => [composer_command(source, scope)],
get_commands: scope => [composer_get_command(scope)],
restore_commands: (values, scope) => {
require_snapshot_size("composer", values, 1)
[composer_restore_command(values[0], scope)]
},
capture_command: capture_value,
set_file_steps: no_set_file_steps,
get_file_steps: no_get_file_steps,
restore_file_steps: no_restore_file_steps,
},
{
target: {
id: "cargo",
name: "Rust Cargo registry",
aliases: ["rust", "crate", "crates"],
scopes: [Project, User],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://index.crates.io/", },
{ mirror_id: "rsproxy", url: "https://rsproxy.cn/index/", },
{
mirror_id: "ustc",
url: "https://mirrors.ustc.edu.cn/crates.io-index/",
},
],
},
set_commands: (_, _) => [],
get_commands: _ => [],
restore_commands: (values, _) => {
require_snapshot_size("cargo", values, 1)
[]
},
capture_command: capture_value,
set_file_steps: cargo_set_file_steps,
get_file_steps: cargo_get_file_steps,
restore_file_steps: cargo_restore_file_steps,
},
{
target: {
id: "mooncakes",
name: "MoonBit package registry",
aliases: ["moon", "moonbit"],
scopes: [User],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://mooncakes.io", },
{ mirror_id: "ustc", url: "https://mirrors.ustc.edu.cn/mooncakes", },
],
},
set_commands: (_, _) => [],
get_commands: _ => [],
restore_commands: (values, _) => {
require_snapshot_size("mooncakes", values, 1)
[]
},
capture_command: capture_value,
set_file_steps: moon_set_file_steps,
get_file_steps: moon_get_file_steps,
restore_file_steps: moon_restore_file_steps,
},
{
target: {
id: "rubygems",
name: "RubyGems sources",
aliases: ["ruby", "gem", "rb"],
scopes: [User],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://rubygems.org/", },
{ mirror_id: "rubychina", url: "https://gems.ruby-china.com/", },
],
},
set_commands: (source, _) => rubygems_set_commands(source),
get_commands: _ => [rubygems_get_command()],
restore_commands: (values, _) => {
require_snapshot_size("rubygems", values, 1)
rubygems_restore_commands(values[0])
},
capture_command: capture_rubygems_sources,
set_file_steps: no_set_file_steps,
get_file_steps: no_get_file_steps,
restore_file_steps: no_restore_file_steps,
},
{
target: {
id: "flathub",
name: "Flathub Flatpak remote",
aliases: ["flatpak"],
scopes: [User, System],
capabilities: [CanGet, CanSet, CanReset, CanMeasure],
sources: [
{ mirror_id: "official", url: "https://dl.flathub.org/repo", },
{ mirror_id: "ustc", url: "https://mirrors.ustc.edu.cn/flathub", },
{
mirror_id: "sjtug",
url: "https://mirrors.sjtug.sjtu.edu.cn/flathub",
},
],
},
set_commands: (source, scope) => [flatpak_command(source, scope)],
get_commands: scope => [flatpak_get_command(scope)],
restore_commands: (values, scope) => {
require_snapshot_size("flathub", values, 1)
[flatpak_restore_command(values[0], scope)]
},
capture_command: capture_flathub_url,
set_file_steps: no_set_file_steps,
get_file_steps: no_get_file_steps,
restore_file_steps: no_restore_file_steps,
},
]
}
///|
fn find_recipe(name : StringView) -> Recipe? {
let query = name.to_owned().to_lower()
let all = recipes()
match
all.search_by(recipe => {
recipe.target.id == query || recipe.target.aliases.contains(query)
}) {
Some(index) => Some(all[index])
None => None
}
}
///|
pub fn capture_command_value(
target_name : StringView,
exit_code : Int,
output : StringView,
) -> SavedValue {
match find_recipe(target_name) {
Some(recipe) => (recipe.capture_command)(exit_code, output)
None => capture_value(exit_code, output)
}
}