harn-stdlib 0.10.134

Embedded Harn standard library source catalog
Documentation
import { help_requested, parse_typed, parser, render_help } from "std/cli/argparse"
import { RuntimeInstallRequest, install_runtime, runtime_plan } from "./install.harn"

type BootstrapOptions = {
  mode?: string,
  version?: string,
  version_file?: string,
  target?: string,
  cache_dir?: string,
  install_dir?: string,
  max_attempts?: int,
  retry_delay_seconds?: int,
  github_output?: string,
  github_path?: string,
  github_summary?: string,
  offline: bool,
}

fn arguments() {
  return parser(
    {
      name: "bootstrap-harn",
      about: "Install an exact checksum-verified Harn release.",
      args: [
        {name: "mode", kind: "positional", required: false, default: "install"},
        {name: "version", kind: "flag", long: "--version"},
        {name: "version_file", kind: "flag", long: "--version-file"},
        {name: "target", kind: "flag", long: "--target"},
        {name: "cache_dir", kind: "flag", long: "--cache-dir"},
        {name: "install_dir", kind: "flag", long: "--install-dir"},
        {name: "max_attempts", kind: "flag", long: "--max-attempts", parse: "int"},
        {name: "retry_delay_seconds", kind: "flag", long: "--retry-delay-seconds", parse: "int"},
        {name: "github_output", kind: "flag", long: "--github-output"},
        {name: "github_path", kind: "flag", long: "--github-path"},
        {name: "github_summary", kind: "flag", long: "--github-summary"},
        {name: "offline", kind: "switch", long: "--offline"},
      ],
    },
  )
}

fn setting(env: HarnessEnv, name: string, explicit: string? = nil) -> string {
  return trim(explicit ?? env.get("HARN_BOOTSTRAP_" + name) ?? "")
}

fn output(fs: HarnessFs, path: string, name: string, value: string) {
  require !value.contains("\n") && !value.contains("\r"), "GitHub output contains a newline"
  fs.append(path, name + "=" + value + "\n")
}

fn resolve_request(harness: Harness, cli: BootstrapOptions) -> RuntimeInstallRequest {
  const explicit_version = setting(harness.env, "VERSION", cli.version)
  const version_file = if cli.version_file != nil || explicit_version == "" {
    setting(harness.env, "VERSION_FILE", cli.version_file)
  } else {
    ""
  }
  require explicit_version == "" || version_file == "",
    "--version and --version-file are mutually exclusive"
  const version = regex_replace(
    r"^v",
    "",
    trim(
      if explicit_version != "" {
        explicit_version
      } else {
        harness.fs.read_text(
          if version_file == "" {
            ".harn-version"
          } else {
            version_file
          },
        )
      },
    ),
  )
  const platform = harness.system.platform()
  const arch = if ["x64", "x86_64"].contains(platform.arch) {
    "x86_64"
  } else if ["arm64", "aarch64"].contains(platform.arch) {
    "aarch64"
  } else {
    "unsupported"
  }
  const suffix = if ["darwin", "macos"].contains(platform.os) {
    "apple-darwin"
  } else if platform.os == "linux" {
    "unknown-linux-gnu"
  } else if ["windows", "win32"].contains(platform.os) {
    "pc-windows-msvc"
  } else {
    "unsupported"
  }
  const requested_target = setting(harness.env, "TARGET", cli.target)
  const target = if requested_target == "" {
    arch + "-" + suffix
  } else {
    requested_target
  }
  const tools = harness.env.get("RUNNER_TOOL_CACHE") ?? ""
  const cache_home = harness.env.get("XDG_CACHE_HOME")
    ?? if platform.os == "windows" {
      harness.env.get("LOCALAPPDATA") ?? ""
    } else {
      ""
    }
  const default_cache = if tools != "" {
    path_join(tools, "harn-bootstrap")
  } else if cache_home != "" {
    path_join(cache_home, "harn", "bootstrap")
  } else {
    path_join(harness.env.get("HOME") ?? "", ".cache", "harn", "bootstrap")
  }
  const cache_override = setting(harness.env, "CACHE_DIR", cli.cache_dir)
  const cache = path_join(
    harness.fs.cwd(),
    if cache_override == "" {
      default_cache
    } else {
      cache_override
    },
  )
  const install_override = setting(harness.env, "INSTALL_DIR", cli.install_dir)
  const repository_override = setting(harness.env, "REPOSITORY")
  require repository_override != "", "runtime release repository is required"
  const install_dir = path_join(
    harness.fs.cwd(),
    if install_override != "" {
      install_override
    } else if tools != "" {
      path_join(tools, "harn", version, target)
    } else {
      path_join(cache, "installs", version, target)
    },
  )
  const request: RuntimeInstallRequest = {
    version: version,
    target: target,
    repository: repository_override,
    cache_dir: cache,
    install_dir: install_dir,
    installer: harness.env.get("HARN_EXT_BOOTSTRAP_INSTALLER") ?? "harn",
    token: harness.env.get("HARN_EXT_BOOTSTRAP_TOKEN") ?? "",
    attempts: cli.max_attempts ?? to_int(harness.env.get("HARN_BOOTSTRAP_MAX_ATTEMPTS") ?? "12"),
    delay_ms: (cli.retry_delay_seconds
        ?? to_int(harness.env.get("HARN_BOOTSTRAP_RETRY_DELAY_SECONDS") ?? "10"))
      * 1000,
    offline: cli.offline
      || ["1", "true"].contains(harness.env.get("HARN_EXT_BOOTSTRAP_OFFLINE") ?? ""),
  }
  return request
}

/**
 * Run the shared bootstrap command and emit its receipt and requested Actions outputs.
 *
 * @effects: [env, fs, net, process, clock, random, stdio]
 * @errors: [invalid_runtime_request, verification_failed, install_failed]
 */
pub fn run_bootstrap(harness: Harness, args: list<string>) -> nil {
  const spec = arguments()
  if help_requested(args) {
    harness.stdio.println(render_help(spec))
    return
  }
  const cli = unwrap(parse_typed(spec, args, schema_of(BootstrapOptions))).options
  const mode = cli.mode ?? "install"
  require ["install", "resolve"].contains(mode), "unknown bootstrap command"
  const request = resolve_request(harness, cli)
  const resolved = runtime_plan(request)
  const result = if mode == "resolve" {
    resolved
  } else {
    install_runtime(harness, request)
  }
  harness.stdio.println(json_stringify(result))
  if cli.github_output != nil {
    for key in ["version", "target", "asset", "checksum"] {
      if result[key] != nil {
        output(harness.fs, cli.github_output, key, to_string(result[key]))
      }
    }
    for mapping in [
      {field: "cache_dir", key: "cache-dir"},
      {field: "install_dir", key: "install-dir"},
      {field: "binary_path", key: "path"},
      {field: "source", key: "source-url"},
      {field: "cache_hit", key: "cache-hit"},
    ] {
      if result[mapping.field] != nil {
        output(harness.fs, cli.github_output, mapping.key, to_string(result[mapping.field]))
      }
    }
    if mode == "resolve" {
      for path in [resolved.metadata_path, resolved.archive_path] {
        require !path.contains("\n") && !path.contains("\r")
          && !path.contains("harn-bootstrap-output"),
          "invalid cache output path"
      }
      harness.fs.append(
        cli.github_output,
        "cache-path<<harn-bootstrap-output\n" + resolved.metadata_path + "\n"
          + resolved.archive_path
          + "\nharn-bootstrap-output\n",
      )
    } else {
      output(harness.fs, cli.github_output, "receipt", json_stringify(result))
    }
  }
  if mode == "install" && cli.github_path != nil {
    harness.fs.append(cli.github_path, resolved.install_dir + "\n")
  }
  if mode == "install" && cli.github_summary != nil {
    harness.fs.append(
      cli.github_summary,
      "Installed checksum-verified Harn " + resolved.version + " for " + resolved.target + ".\n",
    )
  }
}