├── .github ├── FUNDING.yml └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .moon ├── tasks │ └── rust.yml ├── toolchain.yml └── workspace.yml ├── .prototools ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── backends └── asdf │ ├── CHANGELOG.md │ ├── Cargo.toml │ ├── README.md │ ├── src │ ├── config.rs │ ├── lib.rs │ └── proto.rs │ └── tests │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__asdf_backend__creates_shims.snap │ └── versions_test.rs ├── crates ├── extension-common │ ├── Cargo.toml │ └── src │ │ ├── download.rs │ │ ├── lib.rs │ │ ├── migrator.rs │ │ └── project_graph.rs └── lang-node-common │ ├── Cargo.toml │ └── src │ ├── lib.rs │ ├── node_dist.rs │ └── package_json.rs ├── docs └── release.md ├── extensions ├── download │ ├── CHANGELOG.md │ ├── Cargo.toml │ ├── src │ │ ├── download_ext.rs │ │ └── lib.rs │ └── tests │ │ └── download_test.rs ├── migrate-nx │ ├── CHANGELOG.md │ ├── Cargo.toml │ ├── src │ │ ├── lib.rs │ │ ├── migrate_nx_ext.rs │ │ ├── nx_json.rs │ │ ├── nx_migrator.rs │ │ └── nx_project_json.rs │ └── tests │ │ ├── __fixtures__ │ │ ├── nx-executors │ │ │ ├── project.json │ │ │ └── yarn.lock │ │ ├── project-inputs │ │ │ └── project.json │ │ ├── project-name-deps │ │ │ └── project.json │ │ ├── project-targets │ │ │ └── project.json │ │ ├── project-type-tags │ │ │ ├── app │ │ │ │ └── project.json │ │ │ └── lib │ │ │ │ └── project.json │ │ ├── projects │ │ │ ├── bar │ │ │ │ └── project.json │ │ │ ├── baz │ │ │ │ └── project.json │ │ │ ├── foo │ │ │ │ └── project.json │ │ │ └── nx.json │ │ ├── root-inputs │ │ │ └── nx.json │ │ └── root │ │ │ ├── nx.json │ │ │ └── workspace.json │ │ ├── migrate_nx_test.rs │ │ └── snapshots │ │ ├── migrate_nx_test__migrate_nx_extension__converts_nx_builtin_executors.snap │ │ ├── migrate_nx_test__migrate_nx_extension__converts_root_files-2.snap │ │ ├── migrate_nx_test__migrate_nx_extension__converts_root_files.snap │ │ ├── migrate_nx_test__migrate_nx_extension__nx_json__converts_named_inputs.snap │ │ ├── migrate_nx_test__migrate_nx_extension__projects__converts_name_and_implicit_deps.snap │ │ ├── migrate_nx_test__migrate_nx_extension__projects__converts_named_inputs.snap │ │ ├── migrate_nx_test__migrate_nx_extension__projects__converts_project_json-2.snap │ │ ├── migrate_nx_test__migrate_nx_extension__projects__converts_project_json-3.snap │ │ ├── migrate_nx_test__migrate_nx_extension__projects__converts_project_json.snap │ │ ├── migrate_nx_test__migrate_nx_extension__projects__converts_targets.snap │ │ ├── migrate_nx_test__migrate_nx_extension__projects__converts_type_and_tags-2.snap │ │ ├── migrate_nx_test__migrate_nx_extension__projects__converts_type_and_tags.snap │ │ ├── migrate_nx_test__migrate_nx_extension__workspace_projects__inherits_layout.snap │ │ └── migrate_nx_test__migrate_nx_extension__workspace_projects__uses_defaults.snap ├── migrate-turborepo │ ├── CHANGELOG.md │ ├── Cargo.toml │ ├── src │ │ ├── lib.rs │ │ ├── migrate_turborepo_ext.rs │ │ ├── turbo_json.rs │ │ └── turbo_migrator.rs │ └── tests │ │ ├── __fixtures__ │ │ ├── error-missing-project-deps │ │ │ └── turbo.json │ │ ├── error-missing-project │ │ │ └── turbo.json │ │ ├── missing-pipeline │ │ │ └── turbo.json │ │ ├── monorepo │ │ │ ├── .moon │ │ │ │ ├── toolchain.yml │ │ │ │ └── workspace.yml │ │ │ ├── client │ │ │ │ ├── package.json │ │ │ │ └── turbo.json │ │ │ ├── server │ │ │ │ ├── package.json │ │ │ │ ├── tsconfig.json │ │ │ │ └── turbo.json │ │ │ ├── turbo.json │ │ │ └── yarn.lock │ │ ├── root-merge-existing │ │ │ ├── .moon │ │ │ │ ├── tasks │ │ │ │ │ └── node.yml │ │ │ │ └── workspace.yml │ │ │ ├── pnpm-lock.yaml │ │ │ └── turbo.json │ │ ├── root-only │ │ │ ├── .moon │ │ │ │ └── workspace.yml │ │ │ └── turbo.json │ │ └── root-project │ │ │ ├── .moon │ │ │ └── workspace.yml │ │ │ └── turbo.json │ │ ├── migrate_turborepo_test.rs │ │ └── snapshots │ │ ├── migrate_turborepo_test__migrate_turborepo_extension__can_force_bun_instead_of_node-2.snap │ │ ├── migrate_turborepo_test__migrate_turborepo_extension__can_force_bun_instead_of_node-3.snap │ │ ├── migrate_turborepo_test__migrate_turborepo_extension__can_force_bun_instead_of_node.snap │ │ ├── migrate_turborepo_test__migrate_turborepo_extension__converts_basic_root_file.snap │ │ ├── migrate_turborepo_test__migrate_turborepo_extension__converts_project_files-2.snap │ │ ├── migrate_turborepo_test__migrate_turborepo_extension__converts_project_files-3.snap │ │ ├── migrate_turborepo_test__migrate_turborepo_extension__converts_project_files.snap │ │ ├── migrate_turborepo_test__migrate_turborepo_extension__converts_to_a_root_project.snap │ │ └── migrate_turborepo_test__migrate_turborepo_extension__merges_with_existing_root_tasks.snap └── unpack │ ├── CHANGELOG.md │ ├── Cargo.toml │ ├── src │ ├── lib.rs │ └── unpack_ext.rs │ └── tests │ ├── __fixtures__ │ ├── tar │ │ ├── archive.tar │ │ └── archive.tar.gz │ └── zip │ │ └── archive.zip │ └── unpack_test.rs ├── justfile ├── moon.yml ├── rust-toolchain.toml ├── scripts ├── computeCiJobs.sh ├── generatePythonReleases.mjs └── release.mjs ├── toolchains ├── node │ ├── Cargo.toml │ └── src │ │ ├── config.rs │ │ ├── lib.rs │ │ └── moon.rs ├── rust │ ├── CHANGELOG.md │ ├── Cargo.toml │ ├── src │ │ ├── cargo_metadata.rs │ │ ├── cargo_toml.rs │ │ ├── config.rs │ │ ├── lib.rs │ │ ├── tier1.rs │ │ ├── tier2.rs │ │ ├── tier2_env.rs │ │ ├── tier3.rs │ │ └── toolchain_toml.rs │ └── tests │ │ ├── __fixtures__ │ │ ├── files │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ └── package │ │ │ │ └── Cargo.toml │ │ ├── locate │ │ │ ├── package-with-lock │ │ │ │ ├── Cargo.lock │ │ │ │ └── Cargo.toml │ │ │ ├── package │ │ │ │ └── Cargo.toml │ │ │ ├── workspace-with-lock │ │ │ │ ├── Cargo.lock │ │ │ │ ├── Cargo.toml │ │ │ │ └── crates │ │ │ │ │ └── a │ │ │ │ │ └── Cargo.toml │ │ │ └── workspace │ │ │ │ ├── Cargo.toml │ │ │ │ └── crates │ │ │ │ └── a │ │ │ │ └── Cargo.toml │ │ ├── projects │ │ │ ├── Cargo.toml │ │ │ ├── a │ │ │ │ ├── Cargo.toml │ │ │ │ └── src │ │ │ │ │ └── lib.rs │ │ │ ├── b │ │ │ │ ├── Cargo.toml │ │ │ │ └── src │ │ │ │ │ └── lib.rs │ │ │ ├── c │ │ │ │ ├── Cargo.toml │ │ │ │ └── src │ │ │ │ │ └── lib.rs │ │ │ └── no-manifest │ │ │ │ └── file │ │ ├── prune │ │ │ ├── Cargo.toml │ │ │ ├── src │ │ │ │ └── main.rs │ │ │ └── target │ │ │ │ ├── other-file │ │ │ │ └── release │ │ │ │ ├── rust_tc_test │ │ │ │ └── rust_tc_test.exe │ │ └── tc-cfg │ │ │ └── rust-toolchain.toml │ │ ├── cargo_toml_test.rs │ │ ├── tier1_test.rs │ │ ├── tier2_env_test.rs │ │ ├── tier2_test.rs │ │ └── toolchain_toml_test.rs └── typescript │ ├── CHANGELOG.md │ ├── Cargo.toml │ ├── src │ ├── config.rs │ ├── context.rs │ ├── lib.rs │ ├── tier1.rs │ ├── tier1_sync.rs │ ├── tier2.rs │ └── tsconfig_json.rs │ └── tests │ ├── __fixtures__ │ ├── configs │ │ ├── a │ │ │ └── tsconfig.json │ │ ├── b │ │ │ └── tsconfig.json │ │ ├── tsconfig.common.json │ │ ├── tsconfig.complete.json │ │ ├── tsconfig.default.json │ │ ├── tsconfig.inherits.json │ │ └── tsconfig.multi-inherits.json │ ├── create-custom │ │ ├── no-config │ │ │ └── empty │ │ ├── tsconfig.base.json │ │ └── tsconfig.json │ ├── hashing │ │ ├── no-config │ │ │ └── empty │ │ ├── no-options │ │ │ └── tsconfig.json │ │ ├── only-extend-root-options │ │ │ └── tsconfig.json │ │ ├── out-dir │ │ │ └── tsconfig.json │ │ ├── tsconfig.json │ │ ├── tsconfig.options.json │ │ └── with-options │ │ │ └── tsconfig.json │ ├── refs-custom │ │ ├── no-refs │ │ │ └── tsconfig.ref.json │ │ └── tsconfig.root.json │ ├── refs-paths │ │ ├── a │ │ │ ├── index.ts │ │ │ ├── package.json │ │ │ └── tsconfig.json │ │ ├── b │ │ │ ├── package.json │ │ │ ├── src │ │ │ │ └── index.ts │ │ │ └── tsconfig.json │ │ ├── c │ │ │ ├── index.tsx │ │ │ ├── package.json │ │ │ └── tsconfig.json │ │ ├── d │ │ │ └── tsconfig.json │ │ ├── other │ │ │ └── tsconfig.json │ │ └── tsconfig.json │ ├── refs-root-level │ │ ├── tsconfig.json │ │ └── tsconfig.project.json │ ├── refs-sibling-root │ │ ├── no-refs │ │ │ └── tsconfig.ref.json │ │ └── root │ │ │ └── tsconfig.json │ └── refs │ │ ├── a │ │ └── tsconfig.json │ │ ├── all-refs │ │ └── tsconfig.json │ │ ├── b │ │ └── tsconfig.json │ │ ├── c │ │ └── tsconfig.json │ │ ├── d │ │ └── empty │ │ ├── no-refs │ │ └── tsconfig.json │ │ ├── some-refs │ │ └── tsconfig.json │ │ └── tsconfig.json │ ├── snapshots │ ├── tier1_sync_test__typescript_toolchain_tier1__create_missing_config__creates_if_missing.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__create_missing_config__creates_if_missing_with_custom_options.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__include_project_reference_sources__adds_includes_from_refs.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__include_shared_types__adds_if_folder_exists.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__route_out_dir_to_cache__adds_when_has_options.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__route_out_dir_to_cache__adds_when_no_options.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__route_out_dir_to_cache__overrides_out_dir.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__sync_project_references__adds_deps_as_refs.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__sync_project_references__doesnt_dupe_add_refs.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__sync_project_references_to_paths__adds_paths_for_refs.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__sync_project_references_to_paths__doesnt_add_if_paths_sync_disabled.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__sync_root_project_reference__adds_project_as_ref.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__sync_root_project_reference__adds_project_as_ref_with_custom_options.snap │ ├── tier1_sync_test__typescript_toolchain_tier1__sync_root_project_reference__works_with_root_dir.snap │ └── tier1_sync_test__typescript_toolchain_tier1__sync_root_project_reference__works_with_root_level_project.snap │ ├── tier1_sync_test.rs │ ├── tier2_test.rs │ ├── tsconfig_json_test.rs │ └── utils.rs └── tools ├── bun ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── config.rs │ ├── lib.rs │ └── proto.rs └── tests │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__bun_tool__creates_shims.snap │ └── versions_test.rs ├── deno ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── config.rs │ ├── lib.rs │ └── proto.rs └── tests │ ├── build_test.rs │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__deno_tool__creates_shims.snap │ └── versions_test.rs ├── go ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── config.rs │ ├── lib.rs │ ├── proto.rs │ └── version.rs └── tests │ ├── build_test.rs │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__go_tool__creates_shims.snap │ └── versions_test.rs ├── internal-schema ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── lib.rs │ ├── proto.rs │ └── schema.rs └── tests │ ├── __fixtures__ │ └── schemas │ │ ├── base.toml │ │ ├── bins.toml │ │ ├── primary-platform.toml │ │ ├── primary.toml │ │ ├── secondary.toml │ │ └── version-pattern.toml │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__schema_tool__creates_shims.snap │ └── versions_test.rs ├── moon ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── lib.rs │ └── proto.rs └── tests │ ├── build_test.rs │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__moon_tool__creates_shims.snap │ └── versions_test.rs ├── node-depman ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── config.rs │ ├── lib.rs │ ├── npm_registry.rs │ ├── package_manager.rs │ └── proto.rs └── tests │ ├── download_test.rs │ ├── hooks_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ ├── shims_test__node_depman_tool__npm__creates_shims.snap │ ├── shims_test__node_depman_tool__pnpm__creates_shims.snap │ └── shims_test__node_depman_tool__yarn__creates_shims.snap │ └── versions_test.rs ├── node ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── config.rs │ ├── lib.rs │ └── proto.rs └── tests │ ├── build_test.rs │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__node_tool__creates_shims.snap │ └── versions_test.rs ├── proto ├── CHANGELOG.md ├── Cargo.toml ├── README.md └── src │ ├── lib.rs │ └── proto.rs ├── python-poetry ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── lib.rs │ └── proto.rs └── tests │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__python_poetry_tool__creates_shims.snap │ └── versions_test.rs ├── python-uv ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── lib.rs │ └── proto.rs └── tests │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__python_uv_tool__creates_shims.snap │ └── versions_test.rs ├── python ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── releases.json ├── src │ ├── lib.rs │ ├── proto.rs │ └── version.rs └── tests │ ├── build_test.rs │ ├── download_test.rs │ ├── metadata_test.rs │ ├── shims_test.rs │ ├── snapshots │ └── shims_test__python_tool__creates_shims.snap │ └── versions_test.rs ├── ruby ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src │ ├── lib.rs │ └── proto.rs └── tests │ └── build_test.rs └── rust ├── CHANGELOG.md ├── Cargo.toml ├── README.md ├── src ├── helpers.rs ├── lib.rs ├── proto.rs └── toolchain_toml.rs └── tests ├── download_test.rs ├── metadata_test.rs ├── shims_test.rs └── versions_test.rs /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: moonrepo 2 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | permissions: 4 | contents: write 5 | 6 | on: 7 | push: 8 | tags: 9 | - "**[0-9]+.[0-9]+.[0-9]+*" 10 | pull_request: 11 | 12 | jobs: 13 | build: 14 | name: Build 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: moonrepo/setup-rust@v1 19 | with: 20 | cache: false 21 | - id: build 22 | uses: moonrepo/build-wasm-plugin@v0 23 | - if: ${{ github.event_name == 'push' && github.ref_type == 'tag' }} 24 | uses: ncipollo/release-action@v1 25 | with: 26 | artifacts: builds/* 27 | artifactErrorsFailBuild: true 28 | body: ${{ steps.build.outputs.changelog-entry }} 29 | makeLatest: false 30 | prerelease: ${{ contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc') }} 31 | skipIfReleaseExists: true 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | debug/ 4 | target/ 5 | 6 | # These are backup files generated by rustfmt 7 | **/*.rs.bk 8 | 9 | # MSVC Windows builds of rustc generate these, which store debugging information 10 | *.pdb 11 | 12 | # moon 13 | .moon/cache 14 | .moon/docker 15 | -------------------------------------------------------------------------------- /.moon/tasks/rust.yml: -------------------------------------------------------------------------------- 1 | $schema: "https://moonrepo.dev/schemas/tasks.json" 2 | 3 | fileGroups: 4 | cargo: 5 | - "Cargo.toml" 6 | - "/Cargo.toml" 7 | # - "/.cargo/config.toml" 8 | - "/rust-toolchain.toml" 9 | sources: 10 | - "src/**/*" 11 | tests: 12 | - "benches/**/*" 13 | - "tests/**/*" 14 | 15 | tasks: 16 | build: 17 | command: "cargo build --target wasm32-wasip1 --release" 18 | inputs: 19 | - "@group(cargo)" 20 | - "@group(sources)" 21 | env: &env 22 | CARGO_TERM_COLOR: "always" 23 | # CARGO_TERM_QUIET: "true" 24 | 25 | check: 26 | command: "cargo check --all-targets" 27 | inputs: 28 | - "@group(cargo)" 29 | - "@group(sources)" 30 | - "@group(tests)" 31 | env: *env 32 | 33 | lint: 34 | command: "cargo clippy --all-targets" 35 | inputs: 36 | - "@group(cargo)" 37 | - "@group(sources)" 38 | - "@group(tests)" 39 | env: *env 40 | 41 | test: 42 | command: "cargo nextest run --no-default-features --no-fail-fast --no-tests=pass" 43 | deps: 44 | - "build" 45 | inputs: 46 | - "@group(cargo)" 47 | - "@group(sources)" 48 | - "@group(tests)" 49 | # - "/.config/nextest.*" 50 | env: 51 | <<: *env 52 | NO_COLOR: "true" 53 | -------------------------------------------------------------------------------- /.moon/toolchain.yml: -------------------------------------------------------------------------------- 1 | $schema: "https://moonrepo.dev/schemas/toolchain.json" 2 | 3 | rust: 4 | version: "1.87.0" 5 | bins: ["cargo-nextest"] 6 | components: ["clippy", "rustfmt"] 7 | targets: ["wasm32-wasip1"] 8 | syncToolchainConfig: true 9 | -------------------------------------------------------------------------------- /.moon/workspace.yml: -------------------------------------------------------------------------------- 1 | $schema: "https://moonrepo.dev/schemas/workspace.json" 2 | 3 | projects: 4 | root: . 5 | # Backends 6 | asdf-backend: backends/asdf 7 | # Common 8 | extension-common: crates/extension-common 9 | lang-node-common: crates/lang-node-common 10 | # Extensions 11 | download-extension: extensions/download 12 | migrate-nx-extension: extensions/migrate-nx 13 | migrate-turborepo-extension: extensions/migrate-turborepo 14 | unpack-extension: extensions/unpack 15 | # Tools 16 | bun-tool: tools/bun 17 | deno-tool: tools/deno 18 | go-tool: tools/go 19 | moon-tool: tools/moon 20 | node-tool: tools/node 21 | node-depman-tool: tools/node-depman 22 | proto-tool: tools/proto 23 | python-tool: tools/python 24 | python-poetry-tool: tools/python-poetry 25 | python-uv-tool: tools/python-uv 26 | ruby-tool: tools/ruby 27 | rust-tool: tools/rust 28 | schema-tool: tools/internal-schema 29 | # Toolchains 30 | node-toolchain: toolchains/node 31 | rust-toolchain: toolchains/rust 32 | typescript-toolchain: toolchains/typescript 33 | 34 | pipeline: 35 | logRunningCommand: true 36 | -------------------------------------------------------------------------------- /.prototools: -------------------------------------------------------------------------------- 1 | moon = "1.36.0" 2 | 3 | [plugins] 4 | # bun-test = "file://./target/wasm32-wasip1/release/bun_tool.wasm" 5 | # deno-test = "file://./target/wasm32-wasip1/release/deno_tool.wasm" 6 | # go-test = "file://./target/wasm32-wasip1/release/go_tool.wasm" 7 | # internal-schema = "file://./target/wasm32-wasip1/release/schema_tool.wasm" 8 | # moon-test = "file://./target/wasm32-wasip1/release/moon_tool.wasm" 9 | # node-test = "file://./target/wasm32-wasip1/release/node_tool.wasm" 10 | # npm-test = "file://./target/wasm32-wasip1/release/node_depman_tool.wasm" 11 | # pnpm-test = "file://./target/wasm32-wasip1/release/node_depman_tool.wasm" 12 | # poetry-test = "file://./target/wasm32-wasip1/release/python_poetry_tool.wasm" 13 | # python-test = "file://./target/wasm32-wasip1/release/python_tool.wasm" 14 | # ruby-test = "file://./target/wasm32-wasip1/release/ruby_tool.wasm" 15 | # rust-test = "file://./target/wasm32-wasip1/release/rust_tool.wasm" 16 | # uv-test = "file://./target/wasm32-wasip1/release/python_uv_tool.wasm" 17 | # yarn-test = "file://./target/wasm32-wasip1/release/node_depman_tool.wasm" 18 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = ["backends/*", "crates/*", "extensions/*", "tools/*", "toolchains/*"] 4 | 5 | [workspace.dependencies] 6 | # Common 7 | extism-pdk = { version = "1.4.1" } 8 | regex = { version = "1.11.1", default-features = false, features = ["std"] } 9 | rustc-hash = "2.1.1" 10 | schematic = { version = "0.18.5", default-features = false, features = [ 11 | "schema", 12 | ] } 13 | semver = "1.0.26" 14 | serde = { version = "1.0.219", features = ["derive"] } 15 | serde_json = "1.0.140" 16 | serial_test = "3.2.0" 17 | starbase_archive = { version = "0.10.6", default-features = false } 18 | starbase_sandbox = "0.9.3" 19 | starbase_utils = { version = "0.11.10", default-features = false } 20 | tokio = { version = "1.45.1", features = ["full"] } 21 | toml = { version = "0.8.22", default-features = false, features = ["parse"] } 22 | 23 | # moon 24 | moon_common = { version = "0.1.2" } 25 | moon_config = { version = "0.1.4" } 26 | moon_pdk = { version = "0.2.0" } 27 | moon_pdk_api = { version = "0.2.0" } 28 | moon_pdk_test_utils = { version = "0.2.0" } 29 | moon_project = { version = "0.1.3" } 30 | moon_target = { version = "0.1.2" } 31 | # moon_common = { path = "../../moon/crates/common" } 32 | # moon_config = { path = "../../moon/crates/config" } 33 | # moon_pdk = { path = "../../moon/crates/pdk" } 34 | # moon_pdk_api = { path = "../../moon/crates/pdk-api" } 35 | # moon_pdk_test_utils = { path = "../../moon/crates/pdk-test-utils" } 36 | # moon_project = { path = "../../moon/crates/project" } 37 | # moon_target = { path = "../../moon/crates/target" } 38 | 39 | # proto 40 | proto_pdk = { version = "0.28.10" } # , path = "../../proto/crates/pdk" } 41 | proto_pdk_api = { version = "0.27.13" } # , path = "../../proto/crates/pdk-api" } 42 | proto_pdk_test_utils = { version = "0.37.1" } # , path = "../../proto/crates/pdk-test-utils" } 43 | 44 | # JavaScript 45 | nodejs_package_json = "0.4.0" 46 | typescript_tsconfig_json = { version = "0.5.0", features = ["serialize"] } 47 | 48 | [profile.release] 49 | codegen-units = 1 50 | debug = false 51 | lto = true 52 | opt-level = "s" 53 | panic = "abort" 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 moonrepo, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Plugins 2 | 3 | This repository contains all official WASM plugins for moon and proto. The following plugin types are available: 4 | 5 | - **moon** 6 | - Extensions - Extend moon with new functionality. 7 | - Toolchains - Provide integrated tool/language support. 8 | - **proto** 9 | - Backends - Utilize plugins/registries from third-party managers. 10 | - Tools - Download and install tools by version. 11 | -------------------------------------------------------------------------------- /backends/asdf/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.2.1 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.2.0 10 | 11 | #### 🚀 Updates 12 | 13 | - Added `exec-env` experimental support. Runs as a `pre-run` hook to extract any set environment variables. 14 | - Added `latest-stable` script support when the alias "stable" is used for a version. 15 | - Reduced the amount of calls made for converting `/proto/backends` virtual paths into a real path. 16 | 17 | #### 🐞 Fixes 18 | 19 | - Ensure an executable is always returned, even if invalid. 20 | 21 | ## 0.1.2 22 | 23 | #### 🐞 Fixes 24 | 25 | - Fixed an issue where non-executable bins were being returned. We do our best to filter this list. 26 | 27 | ## 0.1.1 28 | 29 | #### 🐞 Fixes 30 | 31 | - Fixed some issues when the plugin is used as "asdf" directly. 32 | 33 | ## 0.1.0 34 | 35 | #### 🎉 Release 36 | 37 | - Initial release! 38 | -------------------------------------------------------------------------------- /backends/asdf/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "asdf_backend" 3 | version = "0.2.1" 4 | edition = "2024" 5 | 6 | [package.metadata.release] 7 | pre-release-replacements = [ 8 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 9 | ] 10 | 11 | [lib] 12 | crate-type = ["cdylib"] 13 | 14 | [dependencies] 15 | extism-pdk = { workspace = true } 16 | proto_pdk = { workspace = true } 17 | rustc-hash = { workspace = true } 18 | schematic = { workspace = true } 19 | serde = { workspace = true } 20 | starbase_utils = { workspace = true } 21 | 22 | [dev-dependencies] 23 | proto_pdk_test_utils = { workspace = true } 24 | starbase_sandbox = { workspace = true } 25 | tokio = { workspace = true } 26 | 27 | [features] 28 | default = ["wasm"] 29 | wasm = [] 30 | -------------------------------------------------------------------------------- /backends/asdf/README.md: -------------------------------------------------------------------------------- 1 | # asdf plugin 2 | 3 | [asdf](https://asdf-vm.com/) backend WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Unsupported 6 | 7 | The `exec-path`, `post-*`, `pre-*`, and `help.*` asdf scripts are currently not supported by this plugin. 8 | 9 | ## Installation 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | asdf = "https://github.com/moonrepo/plugins/releases/download/asdf_backend-vX.Y.Z/asdf_backend.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | asdf plugin can be configured with a `.prototools` file. 21 | 22 | - `asdf-shortname` (string) - The name of the [asdf plugin](https://github.com/asdf-vm/asdf-plugins) if different than the configured ID. 23 | - `asdf-repository` (string) - The Git repository URL in which to locate [scripts](https://asdf-vm.com/plugins/create.html#scripts-overview). If not defined, is extracted from the shortname plugin index. 24 | - `exes` (string[]) - List of executable file names (relative from `bin`) to be linked as a shim/bin. If not defined, we'll automatically scan the `bin` directory. 25 | 26 | ```toml 27 | = "asdf:1.2.3" 28 | 29 | [tools.] 30 | asdf-shortname = "..." 31 | ``` 32 | 33 | ## Hooks 34 | 35 | asdf plugin does not support hooks. 36 | 37 | ## Contributing 38 | 39 | Build the plugin: 40 | 41 | ```shell 42 | cargo build --target wasm32-wasip1 43 | ``` 44 | 45 | Test the plugin by running `proto` commands. 46 | 47 | ```shell 48 | proto install asdf-test 49 | proto versions asdf-test 50 | ``` 51 | -------------------------------------------------------------------------------- /backends/asdf/src/config.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use extism_pdk::*; 4 | use proto_pdk::*; 5 | use std::path::PathBuf; 6 | 7 | #[host_fn] 8 | extern "ExtismHost" { 9 | fn send_request(input: Json) -> Json; 10 | } 11 | 12 | const ASDF_PLUGINS_URL: &str = 13 | "https://raw.githubusercontent.com/asdf-vm/asdf-plugins/refs/heads/master/plugins"; 14 | 15 | /// https://asdf-vm.com/manage/plugins.html 16 | #[derive(Debug, Default, schematic::Schematic, serde::Deserialize, serde::Serialize)] 17 | #[serde(default, deny_unknown_fields, rename_all = "kebab-case")] 18 | pub struct AsdfPluginConfig { 19 | pub asdf_shortname: Option, 20 | pub asdf_repository: Option, 21 | pub exes: Option>, 22 | } 23 | 24 | impl AsdfPluginConfig { 25 | pub fn get_shortname(&self) -> AnyResult { 26 | match &self.asdf_shortname { 27 | Some(name) => Ok(name.into()), 28 | None => get_plugin_id(), 29 | } 30 | } 31 | 32 | pub fn get_backend_id(&self) -> AnyResult { 33 | Ok(format!("asdf-{}", self.get_shortname()?)) 34 | } 35 | 36 | pub fn get_backend_path(&self) -> AnyResult { 37 | let backend_id = self.get_backend_id()?; 38 | 39 | Ok(PathBuf::from(format!("/proto/backends/{backend_id}"))) 40 | } 41 | 42 | pub fn get_script_path(&self, script: &str) -> AnyResult { 43 | self.get_backend_path() 44 | .map(|path| path.join("bin").join(script)) 45 | } 46 | 47 | pub fn get_repo_url(&self) -> AnyResult { 48 | if let Some(repo_url) = &self.asdf_repository { 49 | return Ok(repo_url.into()); 50 | } 51 | 52 | let id = self.get_shortname()?; 53 | let filepath = format!("{ASDF_PLUGINS_URL}/{id}"); 54 | let repo_response = send_request!(&filepath); 55 | 56 | let repo_config = match repo_response.status { 57 | 200 => Ok::(repo_response.text()?), 58 | 404 => Err(PluginError::Message(format!("URL not found: {filepath}")).into()), 59 | _ => Err(PluginError::Message(format!("Failed to fetch URL: {filepath}")).into()), 60 | }?; 61 | 62 | let Some(repo_url) = repo_config.split("=").last() else { 63 | return Err(PluginError::Message(String::from( 64 | "Repository not found in downloaded file!", 65 | )) 66 | .into()); 67 | }; 68 | 69 | Ok(repo_url.trim().trim_end_matches(".git").into()) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /backends/asdf/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod config; 2 | 3 | #[cfg(feature = "wasm")] 4 | mod proto; 5 | 6 | #[cfg(feature = "wasm")] 7 | pub use proto::*; 8 | -------------------------------------------------------------------------------- /backends/asdf/tests/download_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(windows))] 2 | mod asdf_backend { 3 | use proto_pdk_test_utils::*; 4 | 5 | generate_native_install_tests!("asdf:zig", "asdf:0.13.0"); 6 | } 7 | -------------------------------------------------------------------------------- /backends/asdf/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(windows))] 2 | mod asdf_backend { 3 | use proto_pdk_test_utils::*; 4 | 5 | #[tokio::test(flavor = "multi_thread")] 6 | async fn registers_metadata() { 7 | let sandbox = create_empty_proto_sandbox(); 8 | let plugin = sandbox.create_plugin("zig").await; 9 | 10 | let metadata = plugin 11 | .register_tool(RegisterToolInput { id: "zig".into() }) 12 | .await; 13 | 14 | assert_eq!(metadata.name, "asdf:zig"); 15 | assert_eq!( 16 | metadata.plugin_version.unwrap().to_string(), 17 | env!("CARGO_PKG_VERSION") 18 | ); 19 | } 20 | 21 | #[tokio::test(flavor = "multi_thread")] 22 | async fn registers_backend() { 23 | let sandbox = create_empty_proto_sandbox(); 24 | let plugin = sandbox.create_plugin("zig").await; 25 | 26 | let metadata = plugin 27 | .register_backend(RegisterBackendInput::default()) 28 | .await; 29 | 30 | assert_eq!(metadata.backend_id, "asdf-zig"); 31 | 32 | if let SourceLocation::Git(git) = metadata.source.unwrap() { 33 | assert_eq!(git.url, "https://github.com/cheetah/asdf-zig"); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /backends/asdf/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(windows))] 2 | mod asdf_backend { 3 | use proto_pdk_test_utils::*; 4 | 5 | generate_shims_test!("asdf:zig", ["zig"]); 6 | } 7 | -------------------------------------------------------------------------------- /backends/asdf/tests/snapshots/shims_test__asdf_backend__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: backends/asdf/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "zig": {} 7 | } 8 | -------------------------------------------------------------------------------- /backends/asdf/tests/versions_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(windows))] 2 | mod asdf_backend { 3 | use proto_pdk_test_utils::*; 4 | 5 | generate_resolve_versions_tests!("asdf:zig", { 6 | "asdf:0.12" => "0.12.1", 7 | "asdf:0.13.0" => "0.13.0", 8 | }); 9 | 10 | #[tokio::test(flavor = "multi_thread")] 11 | async fn loads_versions_from_git() { 12 | let sandbox = create_empty_proto_sandbox(); 13 | let plugin = sandbox 14 | .create_plugin_with_backend("zig", Backend::Asdf) 15 | .await; 16 | 17 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 18 | 19 | assert!(!output.versions.is_empty()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /crates/extension-common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "extension_common" 3 | version = "0.1.1" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [dependencies] 9 | extism-pdk = { workspace = true } 10 | moon_common = { workspace = true } 11 | moon_config = { workspace = true } 12 | moon_pdk = { workspace = true } 13 | rustc-hash = { workspace = true } 14 | serde = { workspace = true } 15 | starbase_utils = { workspace = true, features = ["yaml"] } 16 | -------------------------------------------------------------------------------- /crates/extension-common/src/download.rs: -------------------------------------------------------------------------------- 1 | use crate::format_virtual_path; 2 | use extism_pdk::debug; 3 | use moon_pdk::{AnyResult, VirtualPath, fetch_bytes}; 4 | use std::fs; 5 | 6 | pub fn download_from_url, P: AsRef>( 7 | src_url: U, 8 | dst_dir: P, 9 | file_name: Option<&str>, 10 | ) -> AnyResult { 11 | let url = src_url.as_ref(); 12 | let dir = dst_dir.as_ref(); 13 | 14 | debug!("Downloading file from {}", url); 15 | 16 | // Extract the file name from the URL 17 | let file_name = file_name.unwrap_or_else(|| &url[url.rfind('/').unwrap() + 1..]); 18 | 19 | // Fetch the bytes of the URL 20 | let bytes = fetch_bytes(url)?; 21 | 22 | // Write the to the provided file 23 | let file = dir.join(file_name); 24 | 25 | fs::create_dir_all(dir)?; 26 | fs::write(&file, bytes)?; 27 | 28 | debug!("Downloaded to {}", format_virtual_path(&file)); 29 | 30 | Ok(file) 31 | } 32 | -------------------------------------------------------------------------------- /crates/extension-common/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod download; 2 | pub mod migrator; 3 | pub mod project_graph; 4 | 5 | use moon_pdk::VirtualPath; 6 | use std::borrow::Cow; 7 | 8 | pub fn format_virtual_path(path: &VirtualPath) -> Cow<'_, str> { 9 | if let Some(real) = path.real_path_string() { 10 | Cow::Owned(real) 11 | } else if let Some(rel) = path.without_prefix() { 12 | rel.to_string_lossy() 13 | } else if let Some(virt) = path.virtual_path_string() { 14 | Cow::Owned(virt) 15 | } else { 16 | Cow::Owned(path.to_string()) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /crates/extension-common/src/project_graph.rs: -------------------------------------------------------------------------------- 1 | use rustc_hash::FxHashMap; 2 | use serde::Deserialize; 3 | 4 | // Only type fields we actually need! 5 | 6 | #[derive(Default, Deserialize)] 7 | #[serde(rename_all = "camelCase")] 8 | pub struct Project { 9 | pub alias: Option, // package.json name 10 | pub id: String, 11 | pub source: String, 12 | } 13 | 14 | #[derive(Default, Deserialize)] 15 | #[serde(rename_all = "camelCase")] 16 | pub struct ProjectGraph { 17 | pub projects: FxHashMap, 18 | } 19 | -------------------------------------------------------------------------------- /crates/lang-node-common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lang_node_common" 3 | version = "0.1.0" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [dependencies] 9 | serde = { workspace = true } 10 | -------------------------------------------------------------------------------- /crates/lang-node-common/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod node_dist; 2 | mod package_json; 3 | 4 | pub use node_dist::*; 5 | pub use package_json::*; 6 | -------------------------------------------------------------------------------- /crates/lang-node-common/src/node_dist.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | 3 | #[derive(Deserialize)] 4 | #[serde(untagged)] 5 | pub enum NodeDistLTS { 6 | Name(String), 7 | State(bool), 8 | } 9 | 10 | #[derive(Deserialize)] 11 | pub struct NodeDistVersion { 12 | pub files: Vec, 13 | pub lts: NodeDistLTS, 14 | pub npm: Option, // No v prefix 15 | pub version: String, // With v prefix 16 | } 17 | -------------------------------------------------------------------------------- /crates/lang-node-common/src/package_json.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | 3 | #[derive(Debug, Deserialize)] 4 | pub struct VoltaField { 5 | pub node: Option, 6 | pub npm: Option, 7 | pub pnpm: Option, 8 | pub yarn: Option, 9 | // Special 10 | pub extends: Option, 11 | } 12 | -------------------------------------------------------------------------------- /docs/release.md: -------------------------------------------------------------------------------- 1 | # Release workflow 2 | 3 | Releases require [cargo-release](https://crates.io/crates/cargo-release). 4 | 5 | ``` 6 | cargo binstall cargo-release --force 7 | ``` 8 | 9 | ## Adding changelogs 10 | 11 | Before releaseing a plugin, changelog entries can be added to `CHANGELOG.md` under an unreleased header, like so. 12 | 13 | ```md 14 | ## Unreleased 15 | 16 | - Changelog entry goes here. 17 | ``` 18 | 19 | ## Releasing plugins 20 | 21 | Plugin based Rust crates are _not_ published to crates.io but are still released using `cargo-release`. We use this library to help bump the version, tag the release, and push back to the repository. This can be achieved with the following command: 22 | 23 | ``` 24 | cargo release -p --no-publish 25 | ``` 26 | 27 | Once the tag is pushed, the `release.yml` GitHub workflow will build the WASM plugin in release mode, and create a GitHub release. 28 | 29 | > Note: Plugins _must_ be published individually, because if more than 8 tags are pushed at once, the GitHub workflow will _not_ run! 30 | -------------------------------------------------------------------------------- /extensions/download/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.0.10 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.0.9 10 | 11 | #### 🚀 Updates 12 | 13 | - Updated dependencies. 14 | 15 | ## 0.0.8 16 | 17 | #### 🚀 Updates 18 | 19 | - Updated dependencies. 20 | 21 | ## 0.0.7 22 | 23 | #### 🚀 Updates 24 | 25 | - Added `register_extension` API. 26 | 27 | ## 0.0.6 28 | 29 | #### 🚀 Updates 30 | 31 | - Updated dependencies. 32 | 33 | ## 0.0.5 34 | 35 | #### ⚙️ Internal 36 | 37 | - Re-publish failed release. 38 | 39 | ## 0.0.4 40 | 41 | #### 🚀 Updates 42 | 43 | - Updated dependencies. 44 | 45 | ## 0.0.3 46 | 47 | #### 🚀 Updates 48 | 49 | - Updated dependencies. 50 | 51 | ## 0.0.2 52 | 53 | #### 🚀 Updates 54 | 55 | - Updated dependencies. 56 | 57 | ## 0.0.1 58 | 59 | #### 🚀 Updates 60 | 61 | - Initial release! 62 | -------------------------------------------------------------------------------- /extensions/download/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "download_extension" 3 | version = "0.0.10" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [lib] 9 | crate-type = ["cdylib"] 10 | 11 | [package.metadata.release] 12 | pre-release-replacements = [ 13 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 14 | ] 15 | 16 | [dependencies] 17 | extension_common = { path = "../../crates/extension-common" } 18 | extism-pdk = { workspace = true } 19 | moon_pdk = { workspace = true } 20 | moon_pdk_api = { workspace = true } 21 | 22 | [dev-dependencies] 23 | moon_pdk_test_utils = { workspace = true } 24 | starbase_sandbox = { workspace = true } 25 | tokio = { workspace = true } 26 | 27 | [features] 28 | default = ["wasm"] 29 | wasm = [] 30 | -------------------------------------------------------------------------------- /extensions/download/src/download_ext.rs: -------------------------------------------------------------------------------- 1 | use extension_common::download::download_from_url; 2 | use extension_common::format_virtual_path; 3 | use extism_pdk::*; 4 | use moon_pdk::*; 5 | use moon_pdk_api::{ExecuteExtensionInput, RegisterExtensionInput, RegisterExtensionOutput}; 6 | 7 | #[host_fn] 8 | extern "ExtismHost" { 9 | fn host_log(input: Json); 10 | fn to_virtual_path(path: String) -> String; 11 | } 12 | 13 | #[plugin_fn] 14 | pub fn register_extension( 15 | Json(_): Json, 16 | ) -> FnResult> { 17 | Ok(Json(RegisterExtensionOutput { 18 | name: "Download".into(), 19 | description: Some("Download a file from a URL into the current working directory.".into()), 20 | plugin_version: env!("CARGO_PKG_VERSION").into(), 21 | config_schema: None, 22 | })) 23 | } 24 | 25 | #[derive(Args)] 26 | pub struct DownloadExtensionArgs { 27 | #[arg(long, short = 'u', required = true)] 28 | pub url: String, 29 | 30 | #[arg(long, short = 'd')] 31 | pub dest: Option, 32 | 33 | #[arg(long)] 34 | pub name: Option, 35 | } 36 | 37 | #[plugin_fn] 38 | pub fn execute_extension(Json(input): Json) -> FnResult<()> { 39 | let args = parse_args::(&input.args)?; 40 | 41 | if !args.url.starts_with("http") { 42 | return Err(plugin_err!("A valid URL is required for downloading.")); 43 | } 44 | 45 | // Determine destination directory 46 | debug!("Determining destination directory"); 47 | 48 | let dest_dir = into_virtual_path( 49 | input 50 | .context 51 | .get_absolute_path(args.dest.as_deref().unwrap_or_default()), 52 | )?; 53 | 54 | if dest_dir.exists() && dest_dir.is_file() { 55 | return Err(plugin_err!( 56 | "Destination {} must be a directory, found a file.", 57 | format_virtual_path(&dest_dir), 58 | )); 59 | } 60 | 61 | debug!( 62 | "Destination {} will be used", 63 | format_virtual_path(&dest_dir), 64 | ); 65 | 66 | // Attempt to download the file 67 | host_log!(stdout, "Downloading {}", args.url); 68 | 69 | let dest_file = download_from_url(&args.url, &dest_dir, args.name.as_deref())?; 70 | 71 | host_log!( 72 | stdout, 73 | "Downloaded to {}", 74 | format_virtual_path(&dest_file), 75 | ); 76 | 77 | Ok(()) 78 | } 79 | -------------------------------------------------------------------------------- /extensions/download/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod download_ext; 3 | 4 | #[cfg(feature = "wasm")] 5 | pub use download_ext::*; 6 | -------------------------------------------------------------------------------- /extensions/migrate-nx/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.0.10 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.0.9 10 | 11 | #### 🚀 Updates 12 | 13 | - Will no longer delete Nx files by default. 14 | - Updated dependencies. 15 | 16 | ## 0.0.8 17 | 18 | #### 🚀 Updates 19 | 20 | - Switched to new toolchain system. 21 | - Updated dependencies. 22 | 23 | ## 0.0.7 24 | 25 | #### 🚀 Updates 26 | 27 | - Added `register_extension` API. 28 | 29 | ## 0.0.6 30 | 31 | #### 🚀 Updates 32 | 33 | - Added support for `defaultBase` from `nx.json`. 34 | - Added support for `metadata` from `project.json`. 35 | - Updated dependencies. 36 | 37 | ## 0.0.5 38 | 39 | #### ⚙️ Internal 40 | 41 | - Re-publish failed release. 42 | 43 | ## 0.0.4 44 | 45 | #### 🚀 Updates 46 | 47 | - Updated dependencies. 48 | 49 | ## 0.0.3 50 | 51 | #### 🐞 Fixes 52 | 53 | - Fixed invalid IDs when converting `package.json` names. 54 | 55 | ## 0.0.2 56 | 57 | #### 🚀 Updates 58 | 59 | - Initial release! 60 | -------------------------------------------------------------------------------- /extensions/migrate-nx/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "migrate_nx_extension" 3 | version = "0.0.10" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [lib] 9 | crate-type = ["cdylib"] 10 | 11 | [package.metadata.release] 12 | pre-release-replacements = [ 13 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 14 | ] 15 | 16 | [dependencies] 17 | extension_common = { path = "../../crates/extension-common" } 18 | extism-pdk = { workspace = true } 19 | moon_common = { workspace = true } 20 | moon_config = { workspace = true } 21 | moon_pdk = { workspace = true } 22 | moon_pdk_api = { workspace = true } 23 | moon_target = { workspace = true } 24 | rustc-hash = { workspace = true } 25 | serde = { workspace = true } 26 | serde_json = { workspace = true } 27 | starbase_utils = { workspace = true, features = ["glob", "json", "yaml"] } 28 | 29 | [dev-dependencies] 30 | moon_pdk_test_utils = { workspace = true } 31 | starbase_sandbox = { workspace = true } 32 | tokio = { workspace = true } 33 | 34 | [features] 35 | default = ["wasm"] 36 | wasm = [] 37 | -------------------------------------------------------------------------------- /extensions/migrate-nx/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod migrate_nx_ext; 3 | mod nx_json; 4 | mod nx_migrator; 5 | mod nx_project_json; 6 | 7 | #[cfg(feature = "wasm")] 8 | pub use migrate_nx_ext::*; 9 | -------------------------------------------------------------------------------- /extensions/migrate-nx/src/nx_project_json.rs: -------------------------------------------------------------------------------- 1 | // https://nx.dev/reference/project-configuration 2 | 3 | use crate::nx_json::{NxNamedInputs, NxTargetOptions}; 4 | use rustc_hash::FxHashMap; 5 | use serde::Deserialize; 6 | use std::collections::HashMap; 7 | 8 | #[derive(Default, Deserialize)] 9 | #[serde(rename_all = "camelCase")] 10 | pub struct NxProjectJson { 11 | pub implicit_dependencies: Option>, 12 | pub metadata: Option>, 13 | pub name: Option, 14 | pub named_inputs: Option, 15 | pub project_type: Option, 16 | // pub root: Option, 17 | // pub source_root: Option, 18 | pub tags: Option>, 19 | pub targets: Option>, 20 | } 21 | 22 | #[derive(Default, Deserialize)] 23 | #[serde(rename_all = "camelCase")] 24 | pub struct PackageJsonWithNx { 25 | pub nx: Option, 26 | } 27 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/nx-executors/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "targets": { 3 | "noop": { 4 | "executor": "nx:noop" 5 | }, 6 | "run-single": { 7 | "executor": "nx:run-commands", 8 | "options": { 9 | "command": "ls apps/frontend/src" 10 | } 11 | }, 12 | "run-multiple": { 13 | "executor": "nx:run-commands", 14 | "options": { 15 | "commands": [ 16 | "mkdir -p apps/frontend/scripts", 17 | "touch apps/frontend/scripts/my-script.sh", 18 | "chmod +x apps/frontend/scripts/my-script.sh" 19 | ], 20 | "parallel": false 21 | } 22 | }, 23 | "run-with-cwd": { 24 | "executor": "nx:run-commands", 25 | "outputs": ["scripts/**/*"], 26 | "options": { 27 | "cwd": "apps/frontend", 28 | "commands": ["mkdir -p scripts"] 29 | } 30 | }, 31 | "run-env-file": { 32 | "executor": "nx:run-commands", 33 | "options": { 34 | "envFile": ".env.production", 35 | "command": "echo 'foo'" 36 | } 37 | }, 38 | "run-env": { 39 | "executor": "nx:run-commands", 40 | "options": { 41 | "command": "echo 'foo'", 42 | "env": { 43 | "FOO": 123, 44 | "BAR": "abc", 45 | "BAZ": true 46 | } 47 | } 48 | }, 49 | "script": { 50 | "executor": "nx:run-script", 51 | "options": { 52 | "script": "build" 53 | } 54 | }, 55 | "script-alt": { 56 | "executor": "nx:run-script", 57 | "outputs": ["{projectRoot}/dist", "{projectRoot}/docs"], 58 | "options": { 59 | "script": "build" 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/nx-executors/yarn.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/extensions/migrate-nx/tests/__fixtures__/nx-executors/yarn.lock -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/project-inputs/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "namedInputs": { 3 | "empty": [], 4 | "variants": [ 5 | { "env": "FOO_BAR" }, 6 | { "fileset": "**/*" }, 7 | { "fileset": "{projectRoot}/**/*" }, 8 | { "fileset": "!{projectRoot}/**/*" }, 9 | { "fileset": "{workspaceRoot}/**/*" }, 10 | { "fileset": "!{workspaceRoot}/**/*" }, 11 | { "runtime": "node -v" }, 12 | "./src/file.ts", 13 | "./src/file.*", 14 | "./src", 15 | "group", 16 | "^group" 17 | ], 18 | "filtered": [ 19 | { 20 | "externalDependencies": ["webpack"] 21 | }, 22 | { 23 | "input": "*", 24 | "projects": ["a", "b", "c"] 25 | }, 26 | { 27 | "input": "*", 28 | "projects": "a" 29 | }, 30 | { 31 | "input": "*", 32 | "dependencies": true 33 | }, 34 | { 35 | "input": "*" 36 | }, 37 | { 38 | "dependentTasksOutputFiles": "out/**/*", 39 | "transitive": true 40 | }, 41 | { 42 | "dependentTasksOutputFiles": "out/**/*" 43 | } 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/project-name-deps/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom", 3 | "implicitDependencies": ["a", "b", "c"] 4 | } 5 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/project-targets/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "targets": { 3 | "serve": { 4 | "executor": "@nx/angular:dev-server", 5 | "configurations": { 6 | "production": { 7 | "buildTarget": "my-app:build:production" 8 | }, 9 | "development": { 10 | "buildTarget": "my-app:build:development" 11 | } 12 | }, 13 | "defaultConfiguration": "development" 14 | }, 15 | "e2e": { 16 | "executor": "cypress:cypress", 17 | "options": { 18 | "cypressConfig": "apps/app-e2e/cypres.config.ts", 19 | "devServerTarget": "my-react-app:serve", 20 | "testingType": "e2e" 21 | } 22 | }, 23 | "build": { 24 | "executor": "@nx/esbuild:esbuild", 25 | "options": { 26 | "main": "app", 27 | "tsConfig": "app/tsconfig.app.json", 28 | "outputPath": "dist/app" 29 | } 30 | }, 31 | "test": { 32 | "executor": "@scope/jest:jest", 33 | "options": { 34 | "jestConfig": "libs/my-lib/jest.config.ts", 35 | "passWithNoTests": true 36 | } 37 | }, 38 | "dev": { 39 | "executor": "@nx/next:server", 40 | "defaultConfiguration": "production", 41 | "options": { 42 | "buildTarget": "acme:build", 43 | "dev": true, 44 | "turbo": false 45 | } 46 | }, 47 | "noop": { 48 | "executor": "nx:noop" 49 | }, 50 | "ls-project-root": { 51 | "executor": "nx:run-commands", 52 | "options": { 53 | "command": "ls apps/frontend/src" 54 | } 55 | }, 56 | "create-script": { 57 | "executor": "nx:run-commands", 58 | "options": { 59 | "commands": [ 60 | "mkdir -p apps/frontend/scripts", 61 | "touch apps/frontend/scripts/my-script.sh", 62 | "chmod +x apps/frontend/scripts/my-script.sh" 63 | ], 64 | "parallel": false 65 | } 66 | }, 67 | "run-script": { 68 | "executor": "nx:run-script", 69 | "options": { 70 | "script": "build-my-project" 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/project-type-tags/app/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "tags": ["scope:client", "scope:server"] 4 | } 5 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/project-type-tags/lib/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "lib", 3 | "tags": ["foo-bar", "baz_qux"] 4 | } 5 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/projects/bar/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": "bar", 3 | "sourceRoot": "bar/src", 4 | "projectType": "application", 5 | "generators": {}, 6 | "targets": { 7 | "build": { 8 | "executor": "@nx/webpack:webpack", 9 | "options": { 10 | "outputPath": "dist/bar" 11 | } 12 | }, 13 | "test": { 14 | "executor": "@nx/jest:jest", 15 | "options": { 16 | "concurrency": 5, 17 | "passWithNoTests": true 18 | } 19 | }, 20 | "echo": { 21 | "command": "echo 'hello world'" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/projects/baz/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "namedInputs": { 3 | "default": ["{projectRoot}/**/*", "sharedGlobals"], 4 | "production": [ 5 | "default", 6 | "!{projectRoot}/jest.config.ts", 7 | "!{projectRoot}/**/?(*.)+(spec|test).ts" 8 | ] 9 | }, 10 | "targets": { 11 | "build": { 12 | "executor": "@nx/js:tsc", 13 | "outputs": ["{workspaceRoot}/dist/baz"], 14 | "dependsOn": ["^build"], 15 | "inputs": ["production", "^production"], 16 | "options": { 17 | "tsConfig": "baz/tsconfig.lib.json", 18 | "main": "baz/src/main.ts" 19 | }, 20 | "configurations": { 21 | "production": { 22 | "tsConfig": "baz/tsconfig-prod.lib.json" 23 | } 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/projects/foo/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "implicitDependencies": ["bar"], 3 | "targets": { 4 | "e2e": { 5 | "executor": "@nx/cypress:cypress", 6 | "options": { 7 | "cypressConfig": "foo/cypress.config.ts", 8 | "parallel": true, 9 | "debug": false 10 | }, 11 | "configurations": { 12 | "dev": { 13 | "devServerTarget": "my-app:serve" 14 | }, 15 | "qa": { 16 | "baseUrl": "https://some-internal-url.example.com" 17 | } 18 | }, 19 | "defaultConfiguration": "dev" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/projects/nx.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/root-inputs/nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "namedInputs": { 3 | "empty": [], 4 | "variants": [ 5 | { "env": "FOO_BAR" }, 6 | { "fileset": "**/*" }, 7 | { "fileset": "{projectRoot}/**/*" }, 8 | { "fileset": "!{projectRoot}/**/*" }, 9 | { "fileset": "{workspaceRoot}/**/*" }, 10 | { "fileset": "!{workspaceRoot}/**/*" }, 11 | { "runtime": "node -v" }, 12 | "./src/file.ts", 13 | "./src/file.*", 14 | "./src", 15 | "group", 16 | "^group" 17 | ], 18 | "filtered": [ 19 | { 20 | "externalDependencies": ["webpack"] 21 | }, 22 | { 23 | "input": "*", 24 | "projects": ["a", "b", "c"] 25 | }, 26 | { 27 | "input": "*", 28 | "projects": "a" 29 | }, 30 | { 31 | "input": "*", 32 | "dependencies": true 33 | }, 34 | { 35 | "input": "*" 36 | }, 37 | { 38 | "dependentTasksOutputFiles": "out/**/*", 39 | "transitive": true 40 | }, 41 | { 42 | "dependentTasksOutputFiles": "out/**/*" 43 | } 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/root/nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | { 4 | "plugin": "@nx/eslint/plugin", 5 | "options": { 6 | "targetName": "lint" 7 | } 8 | } 9 | ], 10 | "parallel": 4, 11 | "cacheDirectory": "tmp/my-nx-cache", 12 | "affected": { 13 | "defaultBase": "main" 14 | }, 15 | "namedInputs": { 16 | "default": [ 17 | "{projectRoot}/**/*", 18 | { "env": "FOO_BAR" }, 19 | { "runtime": "node -v" } 20 | ], 21 | "production": [ 22 | "!{projectRoot}/**/*.spec.tsx", 23 | { "fileset": "{workspaceRoot}/static" } 24 | ] 25 | }, 26 | "targetDefaults": { 27 | "build": { 28 | "inputs": ["production", "^production"], 29 | "dependsOn": ["^build"], 30 | "executor": "@nrwl/js:tsc", 31 | "options": { 32 | "main": "{projectRoot}/src/index.ts" 33 | }, 34 | "cache": true 35 | } 36 | }, 37 | "release": { 38 | "version": { 39 | "generatorOptions": { 40 | "currentVersionResolver": "git-tag", 41 | "specifierSource": "conventional-commits" 42 | } 43 | }, 44 | "changelog": { 45 | "git": { 46 | "commit": true, 47 | "tag": true 48 | }, 49 | "workspaceChangelog": { 50 | "createRelease": "github" 51 | }, 52 | "projectChangelogs": true 53 | } 54 | }, 55 | "generators": { 56 | "@nx/js:library": { 57 | "buildable": true 58 | } 59 | }, 60 | "extends": "nx/presets/npm.json" 61 | } 62 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/__fixtures__/root/workspace.json: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "client": "apps/client", 4 | "server": "apps/server", 5 | "shared": "libs/shared" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__converts_nx_builtin_executors.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"moon.yml\")).unwrap()" 4 | --- 5 | language: javascript 6 | tasks: 7 | noop: 8 | command: noop 9 | run-env: 10 | command: echo 'foo' 11 | env: 12 | BAR: abc 13 | FOO: '123' 14 | BAZ: 'true' 15 | toolchain: system 16 | run-env-file: 17 | command: echo 'foo' 18 | options: 19 | envFile: '.env.production' 20 | toolchain: system 21 | run-multiple: 22 | command: mkdir -p apps/frontend/scripts && touch apps/frontend/scripts/my-script.sh && chmod +x apps/frontend/scripts/my-script.sh 23 | toolchain: system 24 | run-single: 25 | command: ls apps/frontend/src 26 | toolchain: system 27 | run-with-cwd: 28 | command: mkdir -p scripts 29 | env: 30 | CWD: apps/frontend 31 | outputs: 32 | - scripts/**/* 33 | toolchain: system 34 | script: 35 | command: yarn run build 36 | script-alt: 37 | command: yarn run build 38 | outputs: 39 | - dist 40 | - docs 41 | toolchain: 42 | default: node 43 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__converts_root_files-2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\".moon/workspace.yml\")).unwrap()" 4 | --- 5 | projects: 6 | client: apps/client 7 | server: apps/server 8 | shared: libs/shared 9 | vcs: 10 | defaultBranch: main 11 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__converts_root_files.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\".moon/tasks/node.yml\")).unwrap()" 4 | --- 5 | fileGroups: 6 | default: 7 | - '**/*' 8 | - $FOO_BAR 9 | production: 10 | - '!**/*.spec.tsx' 11 | - /static 12 | tasks: 13 | build: 14 | command: js tsc 15 | args: 16 | - '--main' 17 | - $projectRoot/src/index.ts 18 | deps: 19 | - ^:build 20 | inputs: 21 | - '@group(production)' 22 | options: 23 | cache: true 24 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__nx_json__converts_named_inputs.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\".moon/tasks/node.yml\")).unwrap()" 4 | --- 5 | fileGroups: 6 | variants: 7 | - $FOO_BAR 8 | - '**/*' 9 | - '**/*' 10 | - '!**/*' 11 | - /**/* 12 | - '!/**/*' 13 | - src/file.ts 14 | - src/file.* 15 | - src 16 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__projects__converts_name_and_implicit_deps.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"moon.yml\")).unwrap()" 4 | --- 5 | dependsOn: 6 | - a 7 | - b 8 | - c 9 | id: custom 10 | language: javascript 11 | toolchain: 12 | default: node 13 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__projects__converts_named_inputs.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"moon.yml\")).unwrap()" 4 | --- 5 | fileGroups: 6 | variants: 7 | - $FOO_BAR 8 | - '**/*' 9 | - '**/*' 10 | - '!**/*' 11 | - /**/* 12 | - '!/**/*' 13 | - src/file.ts 14 | - src/file.* 15 | - src 16 | language: javascript 17 | toolchain: 18 | default: node 19 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__projects__converts_project_json-2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"baz/moon.yml\")).unwrap()" 4 | --- 5 | fileGroups: 6 | default: 7 | - '**/*' 8 | production: 9 | - '!jest.config.ts' 10 | - '!**/?(*.)+(spec|test).ts' 11 | language: javascript 12 | tasks: 13 | build: 14 | command: js tsc 15 | args: 16 | - '--main' 17 | - $workspaceRoot/baz/src/main.ts 18 | - '--tsConfig' 19 | - $workspaceRoot/baz/tsconfig.lib.json 20 | deps: 21 | - ^:build 22 | inputs: 23 | - '@group(production)' 24 | outputs: 25 | - /dist/baz 26 | build.production: 27 | extends: build 28 | args: 29 | - '--tsConfig' 30 | - $workspaceRoot/baz/tsconfig-prod.lib.json 31 | toolchain: 32 | default: node 33 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__projects__converts_project_json-3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"foo/moon.yml\")).unwrap()" 4 | --- 5 | dependsOn: 6 | - bar 7 | language: javascript 8 | tasks: 9 | e2e: 10 | command: cypress 11 | args: 12 | - '--cypressConfig' 13 | - $workspaceRoot/foo/cypress.config.ts 14 | - '--no-debug' 15 | - '--parallel' 16 | e2e.dev: 17 | extends: e2e 18 | args: 19 | - '--devServerTarget' 20 | - my-app:serve 21 | e2e.qa: 22 | extends: e2e 23 | args: 24 | - '--baseUrl' 25 | - https://some-internal-url.example.com 26 | toolchain: 27 | default: node 28 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__projects__converts_project_json.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"bar/moon.yml\")).unwrap()" 4 | --- 5 | language: javascript 6 | tasks: 7 | build: 8 | command: webpack 9 | args: 10 | - '--outputPath' 11 | - $workspaceRoot/dist/bar 12 | echo: 13 | command: echo 'hello world' 14 | test: 15 | command: jest 16 | args: 17 | - '--concurrency' 18 | - '5' 19 | - '--passWithNoTests' 20 | toolchain: 21 | default: node 22 | type: application 23 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__projects__converts_targets.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"moon.yml\")).unwrap()" 4 | --- 5 | language: javascript 6 | tasks: 7 | build: 8 | command: esbuild 9 | args: 10 | - '--main' 11 | - app 12 | - '--tsConfig' 13 | - $workspaceRoot/app/tsconfig.app.json 14 | - '--outputPath' 15 | - $workspaceRoot/dist/app 16 | create-script: 17 | command: mkdir -p apps/frontend/scripts && touch apps/frontend/scripts/my-script.sh && chmod +x apps/frontend/scripts/my-script.sh 18 | toolchain: system 19 | dev: 20 | command: next server 21 | args: 22 | - '--buildTarget' 23 | - acme:build 24 | - '--no-turbo' 25 | - '--dev' 26 | e2e: 27 | command: cypress 28 | args: 29 | - '--cypressConfig' 30 | - $workspaceRoot/apps/app-e2e/cypres.config.ts 31 | - '--devServerTarget' 32 | - my-react-app:serve 33 | - '--testingType' 34 | - e2e 35 | ls-project-root: 36 | command: ls apps/frontend/src 37 | toolchain: system 38 | noop: 39 | command: noop 40 | run-script: 41 | command: npm run build-my-project 42 | serve: 43 | command: angular dev-server 44 | serve.development: 45 | extends: serve 46 | args: 47 | - '--buildTarget' 48 | - my-app:build:development 49 | serve.production: 50 | extends: serve 51 | args: 52 | - '--buildTarget' 53 | - my-app:build:production 54 | test: 55 | command: jest 56 | args: 57 | - '--passWithNoTests' 58 | - '--jestConfig' 59 | - $workspaceRoot/libs/my-lib/jest.config.ts 60 | toolchain: 61 | default: node 62 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__projects__converts_type_and_tags-2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"lib/moon.yml\")).unwrap()" 4 | --- 5 | language: javascript 6 | tags: 7 | - foo-bar 8 | - baz_qux 9 | toolchain: 10 | default: node 11 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__projects__converts_type_and_tags.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"app/moon.yml\")).unwrap()" 4 | --- 5 | language: javascript 6 | tags: 7 | - scope.client 8 | - scope.server 9 | toolchain: 10 | default: node 11 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__workspace_projects__inherits_layout.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\".moon/workspace.yml\")).unwrap()" 4 | --- 5 | projects: 6 | - applications/* 7 | - libraries/* 8 | -------------------------------------------------------------------------------- /extensions/migrate-nx/tests/snapshots/migrate_nx_test__migrate_nx_extension__workspace_projects__uses_defaults.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-nx/tests/migrate_nx_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\".moon/workspace.yml\")).unwrap()" 4 | --- 5 | projects: 6 | - apps/* 7 | - packages/* 8 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.1.7 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.1.6 10 | 11 | #### 🚀 Updates 12 | 13 | - Will no longer delete Turborepo files by default. 14 | - Updated dependencies. 15 | 16 | ## 0.1.5 17 | 18 | #### 🚀 Updates 19 | 20 | - Switched to new toolchain system. 21 | - Switched to `preset` from `local`. 22 | - Updated dependencies. 23 | 24 | ## 0.1.4 25 | 26 | #### 🚀 Updates 27 | 28 | - Added `register_extension` API. 29 | 30 | ## 0.1.3 31 | 32 | #### 🚀 Updates 33 | 34 | - Added support for `interactive` task option. 35 | - Updated dependencies. 36 | 37 | ## 0.1.2 38 | 39 | #### ⚙️ Internal 40 | 41 | - Re-publish failed release. 42 | 43 | ## 0.1.1 44 | 45 | #### 🚀 Updates 46 | 47 | - Added support for Turborepo v2. 48 | - Updated dependencies. 49 | 50 | ## 0.1.0 51 | 52 | #### 🚀 Updates 53 | 54 | - Removed the requirement of moon's project graph. Will now scan for `turbo.json`s instead. 55 | - Cleaned up the migration code to be more readable and maintainable. 56 | 57 | ## 0.0.2 58 | 59 | #### 🚀 Updates 60 | 61 | - Updated to allow a missing or empty `pipeline` in `turbo.json`. 62 | 63 | ## 0.0.1 64 | 65 | #### 🚀 Updates 66 | 67 | - Initial release! 68 | - New features from moon migration: 69 | - Bun support behind a new `--bun` flag. 70 | - Runs scripts through a package manager, instead of `moon node run-script`. 71 | - Root-level tasks will now create a root config, instead of warning. 72 | - Supports `globalDotEnv`, `dotEnv`, and `outputMode`. 73 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "migrate_turborepo_extension" 3 | version = "0.1.7" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [lib] 9 | crate-type = ["cdylib"] 10 | 11 | [package.metadata.release] 12 | pre-release-replacements = [ 13 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 14 | ] 15 | 16 | [dependencies] 17 | extension_common = { path = "../../crates/extension-common" } 18 | extism-pdk = { workspace = true } 19 | moon_common = { workspace = true } 20 | moon_config = { workspace = true } 21 | moon_pdk = { workspace = true } 22 | moon_pdk_api = { workspace = true } 23 | moon_target = { workspace = true } 24 | rustc-hash = { workspace = true } 25 | serde = { workspace = true } 26 | starbase_utils = { workspace = true, features = ["glob", "json", "yaml"] } 27 | 28 | [dev-dependencies] 29 | moon_pdk_test_utils = { workspace = true } 30 | starbase_sandbox = { workspace = true } 31 | tokio = { workspace = true } 32 | 33 | [features] 34 | default = ["wasm"] 35 | wasm = [] 36 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod migrate_turborepo_ext; 3 | mod turbo_json; 4 | mod turbo_migrator; 5 | 6 | #[cfg(feature = "wasm")] 7 | pub use migrate_turborepo_ext::*; 8 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/src/migrate_turborepo_ext.rs: -------------------------------------------------------------------------------- 1 | use crate::turbo_migrator::TurboMigrator; 2 | use extism_pdk::*; 3 | use moon_pdk::*; 4 | use moon_pdk_api::{ExecuteExtensionInput, RegisterExtensionInput, RegisterExtensionOutput}; 5 | use starbase_utils::{fs, glob, json}; 6 | 7 | #[host_fn] 8 | extern "ExtismHost" { 9 | fn host_log(input: Json); 10 | } 11 | 12 | #[plugin_fn] 13 | pub fn register_extension( 14 | Json(_): Json, 15 | ) -> FnResult> { 16 | Ok(Json(RegisterExtensionOutput { 17 | name: "Migrate Turborepo".into(), 18 | description: Some("Migrate a Turborepo repository to moon by converting all turbo.json files into moon configuration files.".into()), 19 | plugin_version: env!("CARGO_PKG_VERSION").into(), 20 | config_schema: None, 21 | })) 22 | } 23 | 24 | #[derive(Args)] 25 | pub struct MigrateTurborepoExtensionArgs { 26 | #[arg(long)] 27 | pub bun: bool, 28 | #[arg(long)] 29 | pub cleanup: bool, 30 | } 31 | 32 | #[plugin_fn] 33 | pub fn execute_extension(Json(input): Json) -> FnResult<()> { 34 | let args = parse_args::(&input.args)?; 35 | let workspace_root = &input.context.workspace_root; 36 | let mut migrator = TurboMigrator::new(&input.context, args.bun)?; 37 | 38 | // Migrate the workspace root config first 39 | let root_config_path = workspace_root.join("turbo.json"); 40 | 41 | if root_config_path.exists() { 42 | host_log!(stdout, "Migrating root config turbo.json"); 43 | 44 | migrator.migrate_root_config(json::read_file(&root_config_path)?)?; 45 | 46 | if args.cleanup { 47 | fs::remove(root_config_path)?; 48 | } 49 | } 50 | 51 | // Then migrate project configs 52 | for project_config_path in 53 | glob::walk_files(workspace_root, ["**/*/turbo.json", "!**/node_modules/**/*"])? 54 | { 55 | let rel_config_path = project_config_path.strip_prefix(workspace_root).unwrap(); 56 | let project_source = rel_config_path.parent().unwrap().to_string_lossy(); 57 | 58 | host_log!( 59 | stdout, 60 | "Migrating project config {}", 61 | rel_config_path.display() 62 | ); 63 | 64 | migrator.migrate_project_config(&project_source, json::read_file(&project_config_path)?)?; 65 | 66 | if args.cleanup { 67 | fs::remove(project_config_path)?; 68 | } 69 | } 70 | 71 | // Write the new config files 72 | migrator.inner.save_configs()?; 73 | 74 | host_log!(stdout, "Successfully migrated from Turborepo to moon!"); 75 | 76 | Ok(()) 77 | } 78 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/src/turbo_json.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use rustc_hash::FxHashMap; 4 | use serde::Deserialize; 5 | 6 | #[derive(Default, Deserialize)] 7 | #[serde(rename_all = "kebab-case")] 8 | pub enum TurboEnvMode { 9 | Loose, 10 | #[default] 11 | Strict, 12 | } 13 | 14 | #[derive(Default, Deserialize)] 15 | #[serde(rename_all = "kebab-case")] 16 | pub enum TurboOutputMode { 17 | #[default] 18 | Full, 19 | HashOnly, 20 | NewOnly, 21 | ErrorsOnly, 22 | None, 23 | } 24 | 25 | #[derive(Default, Deserialize)] 26 | #[serde(rename_all = "kebab-case")] 27 | pub enum TurboUi { 28 | #[default] 29 | Stream, 30 | Tui, 31 | } 32 | 33 | #[derive(Default, Deserialize)] 34 | #[serde(rename_all = "camelCase")] 35 | pub struct TurboTask { 36 | pub cache: Option, 37 | pub depends_on: Option>, 38 | pub env: Option>, 39 | pub inputs: Option>, 40 | pub outputs: Option>, 41 | pub pass_through_env: Option>, 42 | pub persistent: Option, 43 | // v2 44 | pub interactive: Option, 45 | pub output_logs: Option, 46 | // v1 (removed) 47 | pub dot_env: Option>, 48 | pub output_mode: Option, 49 | } 50 | 51 | #[derive(Default, Deserialize)] 52 | #[serde(rename_all = "camelCase")] 53 | pub struct TurboJson { 54 | pub extends: Option>, 55 | pub global_dependencies: Option>, 56 | pub global_env: Option>, 57 | pub global_pass_through_env: Option>, 58 | // v2 59 | pub cache_dir: Option, 60 | pub daemon: Option, 61 | pub dangerously_disable_package_manager_check: Option, 62 | pub env_mode: Option, 63 | pub tasks: Option>, 64 | pub ui: Option, 65 | // v1 (removed) 66 | pub global_dot_env: Option>, 67 | pub pipeline: Option>, 68 | } 69 | 70 | #[derive(Default, Deserialize)] 71 | pub struct PackageJson { 72 | pub name: Option, 73 | } 74 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/error-missing-project-deps/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "pipeline": { 4 | "build": { 5 | "dependsOn": ["client#build"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/error-missing-project/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "tasks": { 4 | "client#build": { 5 | "dependsOn": ["^build"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/missing-pipeline/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json" 3 | } 4 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/monorepo/.moon/toolchain.yml: -------------------------------------------------------------------------------- 1 | node: {} 2 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/monorepo/.moon/workspace.yml: -------------------------------------------------------------------------------- 1 | projects: 2 | - "client" 3 | - "server" 4 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/monorepo/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client" 3 | } 4 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/monorepo/client/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "pipeline": { 4 | "typecheck": { 5 | "dependsOn": ["build"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/monorepo/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server" 3 | } 4 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/monorepo/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/monorepo/server/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "pipeline": { 4 | "lint": { 5 | "outputMode": "errors-only" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/monorepo/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "pipeline": { 4 | "build": { 5 | "dependsOn": ["^build"], 6 | "outputs": ["dist/**"] 7 | }, 8 | "client#build": { 9 | "dependsOn": ["^build"], 10 | "outputs": ["client/**"] 11 | }, 12 | "server#build": { 13 | "dependsOn": ["^build"], 14 | "outputs": ["server/**"] 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/monorepo/yarn.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/extensions/migrate-turborepo/tests/__fixtures__/monorepo/yarn.lock -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/root-merge-existing/.moon/tasks/node.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | lint: 3 | command: "eslint" 4 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/root-merge-existing/.moon/workspace.yml: -------------------------------------------------------------------------------- 1 | projects: 2 | - "packages/*" 3 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/root-merge-existing/pnpm-lock.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/extensions/migrate-turborepo/tests/__fixtures__/root-merge-existing/pnpm-lock.yaml -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/root-merge-existing/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "tasks": { 4 | "build": { 5 | "dependsOn": ["^build"], 6 | "outputs": ["dist/**"] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/root-only/.moon/workspace.yml: -------------------------------------------------------------------------------- 1 | projects: 2 | - "packages/*" 3 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/root-only/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "pipeline": { 4 | "build": { 5 | "dependsOn": ["^build"], 6 | "outputs": ["dist/**"], 7 | "dotEnv": [".env.local", ".env"] 8 | }, 9 | "test": { 10 | "dependsOn": ["build"], 11 | "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts"], 12 | "outputLogs": "full" 13 | }, 14 | "dev": { 15 | "cache": false, 16 | "persistent": true, 17 | "env": ["SECRET_KEY"] 18 | } 19 | }, 20 | 21 | "globalDependencies": [".env", "tsconfig.json"], 22 | "globalEnv": ["GITHUB_TOKEN"], 23 | "globalPassThroughEnv": ["AWS_SECRET_KEY", "GITHUB_TOKEN"], 24 | "globalDotEnv": [".env.local", ".env"] 25 | } 26 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/root-project/.moon/workspace.yml: -------------------------------------------------------------------------------- 1 | projects: 2 | - "packages/*" 3 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/__fixtures__/root-project/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "pipeline": { 4 | "//#build": { 5 | "cache": true, 6 | "persistent": false 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/snapshots/migrate_turborepo_test__migrate_turborepo_extension__can_force_bun_instead_of_node-2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-turborepo/tests/migrate_turborepo_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"client/moon.yml\")).unwrap()" 4 | --- 5 | language: javascript 6 | tasks: 7 | build: 8 | command: bun run build 9 | deps: 10 | - ^:build 11 | outputs: 12 | - client/**/* 13 | typecheck: 14 | command: bun run typecheck 15 | deps: 16 | - ~:build 17 | toolchain: 18 | default: bun 19 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/snapshots/migrate_turborepo_test__migrate_turborepo_extension__can_force_bun_instead_of_node-3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-turborepo/tests/migrate_turborepo_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"server/moon.yml\")).unwrap()" 4 | --- 5 | language: typescript 6 | tasks: 7 | build: 8 | command: bun run build 9 | deps: 10 | - ^:build 11 | outputs: 12 | - server/**/* 13 | lint: 14 | command: bun run lint 15 | options: 16 | outputStyle: buffer-only-failure 17 | toolchain: 18 | default: bun 19 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/snapshots/migrate_turborepo_test__migrate_turborepo_extension__can_force_bun_instead_of_node.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-turborepo/tests/migrate_turborepo_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\".moon/tasks/bun.yml\")).unwrap()" 4 | --- 5 | tasks: 6 | build: 7 | command: bun run build 8 | deps: 9 | - ^:build 10 | outputs: 11 | - dist/**/* 12 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/snapshots/migrate_turborepo_test__migrate_turborepo_extension__converts_basic_root_file.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-turborepo/tests/migrate_turborepo_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\".moon/tasks/node.yml\")).unwrap()" 4 | --- 5 | implicitInputs: 6 | - '.env' 7 | - tsconfig.json 8 | - '.env.local' 9 | - '.env' 10 | - $GITHUB_TOKEN 11 | tasks: 12 | build: 13 | command: npm run build 14 | deps: 15 | - ^:build 16 | outputs: 17 | - dist/**/* 18 | options: 19 | envFile: true 20 | dev: 21 | command: npm run dev 22 | inputs: 23 | - $SECRET_KEY 24 | options: 25 | cache: false 26 | preset: server 27 | test: 28 | command: npm run test 29 | deps: 30 | - ~:build 31 | inputs: 32 | - src/**/*.tsx 33 | - src/**/*.ts 34 | - test/**/*.ts 35 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/snapshots/migrate_turborepo_test__migrate_turborepo_extension__converts_project_files-2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-turborepo/tests/migrate_turborepo_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"client/moon.yml\")).unwrap()" 4 | --- 5 | language: javascript 6 | tasks: 7 | build: 8 | command: yarn run build 9 | deps: 10 | - ^:build 11 | outputs: 12 | - client/**/* 13 | typecheck: 14 | command: yarn run typecheck 15 | deps: 16 | - ~:build 17 | toolchain: 18 | default: node 19 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/snapshots/migrate_turborepo_test__migrate_turborepo_extension__converts_project_files-3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-turborepo/tests/migrate_turborepo_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"server/moon.yml\")).unwrap()" 4 | --- 5 | language: typescript 6 | tasks: 7 | build: 8 | command: yarn run build 9 | deps: 10 | - ^:build 11 | outputs: 12 | - server/**/* 13 | lint: 14 | command: yarn run lint 15 | options: 16 | outputStyle: buffer-only-failure 17 | toolchain: 18 | default: node 19 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/snapshots/migrate_turborepo_test__migrate_turborepo_extension__converts_project_files.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-turborepo/tests/migrate_turborepo_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\".moon/tasks/node.yml\")).unwrap()" 4 | --- 5 | tasks: 6 | build: 7 | command: yarn run build 8 | deps: 9 | - ^:build 10 | outputs: 11 | - dist/**/* 12 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/snapshots/migrate_turborepo_test__migrate_turborepo_extension__converts_to_a_root_project.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-turborepo/tests/migrate_turborepo_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\"moon.yml\")).unwrap()" 4 | --- 5 | language: javascript 6 | tasks: 7 | build: 8 | command: npm run build 9 | toolchain: 10 | default: node 11 | -------------------------------------------------------------------------------- /extensions/migrate-turborepo/tests/snapshots/migrate_turborepo_test__migrate_turborepo_extension__merges_with_existing_root_tasks.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: extensions/migrate-turborepo/tests/migrate_turborepo_test.rs 3 | expression: "fs::read_to_string(sandbox.path().join(\".moon/tasks/node.yml\")).unwrap()" 4 | --- 5 | tasks: 6 | build: 7 | command: pnpm run build 8 | deps: 9 | - ^:build 10 | outputs: 11 | - dist/**/* 12 | lint: 13 | command: eslint 14 | -------------------------------------------------------------------------------- /extensions/unpack/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.0.6 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.0.5 10 | 11 | #### 🚀 Updates 12 | 13 | - Updated dependencies. 14 | 15 | ## 0.0.4 16 | 17 | #### 🚀 Updates 18 | 19 | - Updated dependencies. 20 | 21 | ## 0.0.3 22 | 23 | #### 🚀 Updates 24 | 25 | - Added `register_extension` API. 26 | 27 | ## 0.0.2 28 | 29 | #### 🚀 Updates 30 | 31 | - Updated dependencies. 32 | 33 | ## 0.0.1 34 | 35 | #### 🚀 Updates 36 | 37 | - Initial release! 38 | -------------------------------------------------------------------------------- /extensions/unpack/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "unpack_extension" 3 | version = "0.0.6" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [lib] 9 | crate-type = ["cdylib"] 10 | 11 | [package.metadata.release] 12 | pre-release-replacements = [ 13 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 14 | ] 15 | 16 | [dependencies] 17 | extension_common = { path = "../../crates/extension-common" } 18 | extism-pdk = { workspace = true } 19 | moon_pdk = { workspace = true } 20 | moon_pdk_api = { workspace = true } 21 | starbase_archive = { workspace = true, features = ["tar-gz", "zip"] } 22 | 23 | [dev-dependencies] 24 | moon_pdk_test_utils = { workspace = true } 25 | starbase_sandbox = { workspace = true } 26 | tokio = { workspace = true } 27 | 28 | [features] 29 | default = ["wasm"] 30 | wasm = [] 31 | -------------------------------------------------------------------------------- /extensions/unpack/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod unpack_ext; 3 | 4 | #[cfg(feature = "wasm")] 5 | pub use unpack_ext::*; 6 | -------------------------------------------------------------------------------- /extensions/unpack/tests/__fixtures__/tar/archive.tar: -------------------------------------------------------------------------------- 1 | ./dir/000755 000765 000024 00000000000 14554255201 012250 5ustar00milesstaff000000 000000 ./dir/file.txt000644 000765 000024 00000000030 14554255205 013725 0ustar00milesstaff000000 000000 This is in the archive! 2 | -------------------------------------------------------------------------------- /extensions/unpack/tests/__fixtures__/tar/archive.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/extensions/unpack/tests/__fixtures__/tar/archive.tar.gz -------------------------------------------------------------------------------- /extensions/unpack/tests/__fixtures__/zip/archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/extensions/unpack/tests/__fixtures__/zip/archive.zip -------------------------------------------------------------------------------- /justfile: -------------------------------------------------------------------------------- 1 | set windows-shell := ["pwsh.exe", "-Command"] 2 | 3 | init: 4 | cargo install cargo-binstall 5 | cargo binstall cargo-insta cargo-nextest cargo-wasi cargo-release 6 | 7 | build: 8 | moon run :build 9 | 10 | check: 11 | moon run :check 12 | 13 | lint: 14 | moon run :lint 15 | 16 | test name="": 17 | just build 18 | cargo nextest run --workspace {{name}} 19 | -------------------------------------------------------------------------------- /moon.yml: -------------------------------------------------------------------------------- 1 | id: root 2 | 3 | tasks: 4 | format: 5 | command: "cargo fmt --all --check" 6 | inputs: [] 7 | 8 | format-write: 9 | extends: "format" 10 | command: "cargo fmt --all -- --emit=files" 11 | options: 12 | runInCI: false 13 | 14 | build-all: 15 | command: "just build" 16 | inputs: [] 17 | options: 18 | runInCI: false 19 | 20 | test-all: 21 | command: "cargo nextest run --workspace" 22 | inputs: [] 23 | deps: 24 | - "build-all" 25 | options: 26 | runInCI: false 27 | 28 | workspace: 29 | inheritedTasks: 30 | include: [] 31 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "1.87.0" 3 | profile = "default" 4 | -------------------------------------------------------------------------------- /scripts/computeCiJobs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | raw=$(moon query tasks --affected --upstream deep --downstream deep) 5 | 6 | echo "Tasks:" 7 | echo "$raw" 8 | echo "" 9 | 10 | data=$(moon query tasks --affected --upstream deep --downstream deep --json) 11 | taskCount=$(echo "$data" | jq '.tasks | length') 12 | taskPerJob=10 13 | jobTotal=1 14 | 15 | if [[ $taskCount == 0 ]]; then 16 | jobTotal=0 17 | elif [[ $taskCount -gt 10 ]]; then 18 | ((jobTotal = (taskCount + taskPerJob - 1) / taskPerJob)) 19 | fi 20 | 21 | jobsArray="[" 22 | 23 | if [[ $jobTotal -gt 0 ]]; then 24 | for i in $(seq 1 $jobTotal); 25 | do 26 | jobIndex=$((i - 1)) 27 | jobsArray+="$jobIndex" 28 | 29 | if [[ $i -ne $jobTotal ]]; then 30 | jobsArray+="," 31 | fi 32 | done 33 | fi 34 | 35 | jobsArray+="]" 36 | 37 | echo "Task count: $taskCount" 38 | echo "Job total: $jobTotal" 39 | echo "Job array: $jobsArray" 40 | 41 | echo "job-total=$jobTotal" >> "$GITHUB_OUTPUT" 42 | echo "jobs-array=$jobsArray" >> "$GITHUB_OUTPUT" 43 | -------------------------------------------------------------------------------- /toolchains/node/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "node_toolchain" 3 | version = "0.0.1" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | node_tool = { path = "../../tools/node", default-features = false } 18 | extism-pdk = { workspace = true } 19 | moon_pdk = { workspace = true } 20 | moon_pdk_api = { workspace = true } 21 | schematic = { workspace = true } 22 | serde = { workspace = true } 23 | 24 | [features] 25 | default = ["wasm"] 26 | wasm = ["node_tool/wasm"] 27 | -------------------------------------------------------------------------------- /toolchains/node/src/config.rs: -------------------------------------------------------------------------------- 1 | use moon_pdk_api::config_struct; 2 | use schematic::Schematic; 3 | 4 | config_struct!( 5 | /// Configures and enables the Node.js toolchain. 6 | /// Docs: https://moonrepo.dev/docs/config/toolchain#node 7 | #[derive(Default, Schematic)] 8 | pub struct NodeConfig { 9 | /// When `version` is defined, syncs the version as a constraint to 10 | /// `package.json` engines. 11 | #[schema(default = true)] 12 | pub add_engines_constraint: bool, 13 | 14 | /// Arguments to automatically pass to all tasks that execute the 15 | /// `node` binary. 16 | pub bin_exec_args: Vec, 17 | 18 | /// Automatically dedupes the lockfile when dependencies have changed. 19 | #[schema(default = true)] 20 | pub dedupe_on_lockfile_change: bool, 21 | 22 | /// Automatically infer moon tasks from `package.json` scripts. 23 | pub infer_tasks_from_scripts: bool, 24 | 25 | /// The relative root of the packages workspace. Defaults to moon's 26 | /// workspace root, but should be defined when nested. 27 | #[schema(default = ".", skip)] 28 | pub packages_root: String, 29 | 30 | /// Assumes only the root `package.json` is used for dependencies. 31 | /// Can be used to support the "one version policy" pattern. 32 | pub root_package_only: bool, 33 | 34 | /// Automatically syncs the configured package manager version 35 | /// to the root `packageManager` field in `package.json`. 36 | #[schema(default = true)] 37 | pub sync_package_manager_field: bool, 38 | 39 | /// Automatically syncs moon project-to-project relationships as 40 | /// dependencies for each `package.json` in the workspace. 41 | #[schema(default = true)] 42 | pub sync_project_workspace_dependencies: bool, 43 | } 44 | ); 45 | -------------------------------------------------------------------------------- /toolchains/node/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod config; 2 | #[cfg(feature = "wasm")] 3 | mod moon; 4 | 5 | #[cfg(feature = "wasm")] 6 | pub use moon::*; 7 | #[cfg(feature = "wasm")] 8 | pub use node_tool::*; 9 | -------------------------------------------------------------------------------- /toolchains/node/src/moon.rs: -------------------------------------------------------------------------------- 1 | use extism_pdk::*; 2 | use moon_pdk_api::*; 3 | 4 | #[plugin_fn] 5 | pub fn register_toolchain( 6 | Json(_): Json, 7 | ) -> FnResult> { 8 | Ok(Json(RegisterToolchainOutput { 9 | // config_schema: Some(SchemaBuilder::build_root::()), 10 | plugin_version: env!("CARGO_PKG_VERSION").into(), 11 | ..RegisterToolchainOutput::default() 12 | })) 13 | } 14 | -------------------------------------------------------------------------------- /toolchains/rust/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.1.1 4 | 5 | #### 🐞 Fixes 6 | 7 | - Fixed Cargo/Rustup home directory detection. 8 | 9 | ## 0.1.0 10 | 11 | #### 🚀 Updates 12 | 13 | - Initial release! 14 | -------------------------------------------------------------------------------- /toolchains/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_toolchain" 3 | version = "0.1.1" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "lib"] 15 | 16 | [dependencies] 17 | rust_tool = { path = "../../tools/rust", default-features = false } 18 | cargo-lock = "10.1.0" 19 | cargo_toml = "0.22.1" 20 | extism-pdk = { workspace = true } 21 | moon_config = { workspace = true } 22 | moon_pdk = { workspace = true, features = ["schematic"] } 23 | moon_pdk_api = { workspace = true } 24 | rustc-hash = { workspace = true } 25 | schematic = { workspace = true, features = ["config"] } 26 | semver = { workspace = true } 27 | serde = { workspace = true } 28 | starbase_utils = { workspace = true, features = ["editor-config", "toml"] } 29 | 30 | [dev-dependencies] 31 | moon_pdk_test_utils = { workspace = true } 32 | serde_json = { workspace = true } 33 | starbase_sandbox = { workspace = true } 34 | tokio = { workspace = true } 35 | 36 | [features] 37 | default = ["wasm"] 38 | wasm = ["rust_tool/wasm"] 39 | -------------------------------------------------------------------------------- /toolchains/rust/src/cargo_metadata.rs: -------------------------------------------------------------------------------- 1 | // `cargo metadata` 2 | 3 | use serde::Deserialize; 4 | use std::path::PathBuf; 5 | 6 | #[derive(Default, Deserialize)] 7 | #[serde(default)] 8 | pub struct CargoMetadata { 9 | pub packages: Vec, 10 | pub target_directory: PathBuf, 11 | pub workspace_root: PathBuf, 12 | } 13 | 14 | #[derive(Default, Deserialize)] 15 | #[serde(default)] 16 | pub struct PackageMetadata { 17 | pub name: String, 18 | pub version: String, 19 | pub targets: Vec, 20 | } 21 | 22 | #[derive(Default, Deserialize)] 23 | #[serde(default)] 24 | pub struct PackageTarget { 25 | pub name: String, 26 | pub kind: Vec, 27 | pub crate_types: Vec, 28 | pub src_path: PathBuf, 29 | } 30 | 31 | #[derive(Deserialize, PartialEq)] 32 | #[serde(rename_all = "lowercase")] 33 | pub enum PackageTargetKind { 34 | Bin, 35 | Lib, 36 | Test, 37 | } 38 | 39 | #[derive(Deserialize, PartialEq)] 40 | #[serde(rename_all = "lowercase")] 41 | pub enum PackageTargetCrateType { 42 | Bin, 43 | Lib, 44 | RLib, 45 | DyLib, 46 | CdyLib, 47 | StaticLib, 48 | #[serde(rename = "proc-macro")] 49 | ProcMacro, 50 | } 51 | -------------------------------------------------------------------------------- /toolchains/rust/src/config.rs: -------------------------------------------------------------------------------- 1 | use moon_config::BinEntry; 2 | use moon_pdk_api::{UnresolvedVersionSpec, Version, config_struct}; 3 | use schematic::Config; 4 | 5 | config_struct!( 6 | /// Configures and enables the Rust toolchain. 7 | /// Docs: https://moonrepo.dev/docs/config/toolchain#rust 8 | #[derive(Config)] 9 | pub struct RustToolchainConfig { 10 | /// When `version` is defined, syncs the version as a constraint to 11 | /// `Cargo.toml` under the `workspace.package.rust-version` or 12 | /// `package.rust-version` fields. 13 | pub add_msrv_constraint: bool, 14 | 15 | /// List of binaries to install into the environment using `cargo binstall`. 16 | #[setting(nested)] 17 | pub bins: Vec, 18 | 19 | /// The version of `cargo-binstall` to install. Defaults to "latest" if not defined. 20 | pub binstall_version: Option, 21 | 22 | /// List of Rust components to automatically install with `rustup`. 23 | pub components: Vec, 24 | 25 | /// When `version` is defined, syncs the version to `rust-toolchain.toml` 26 | /// under the `toolchain.channel` field. 27 | pub sync_toolchain_config: bool, 28 | 29 | /// List of Rust targets to automatically install with `rustup`. 30 | pub targets: Vec, 31 | 32 | /// Configured version (channel) to download and install with `rustup`. 33 | pub version: Option, 34 | } 35 | ); 36 | -------------------------------------------------------------------------------- /toolchains/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod cargo_metadata; 2 | pub mod cargo_toml; 3 | pub mod config; 4 | pub mod toolchain_toml; 5 | 6 | #[cfg(feature = "wasm")] 7 | mod tier1; 8 | #[cfg(feature = "wasm")] 9 | mod tier2; 10 | #[cfg(feature = "wasm")] 11 | mod tier2_env; 12 | #[cfg(feature = "wasm")] 13 | mod tier3; 14 | 15 | #[cfg(feature = "wasm")] 16 | pub use tier1::*; 17 | #[cfg(feature = "wasm")] 18 | pub use tier2::*; 19 | #[cfg(feature = "wasm")] 20 | pub use tier2_env::*; 21 | #[cfg(feature = "wasm")] 22 | pub use tier3::*; 23 | -------------------------------------------------------------------------------- /toolchains/rust/src/tier3.rs: -------------------------------------------------------------------------------- 1 | pub use rust_tool::*; 2 | -------------------------------------------------------------------------------- /toolchains/rust/src/toolchain_toml.rs: -------------------------------------------------------------------------------- 1 | // `rust-toolchain.toml` 2 | 3 | #[cfg(feature = "wasm")] 4 | use extism_pdk::*; 5 | #[cfg(feature = "wasm")] 6 | use moon_pdk::host_log; 7 | use moon_pdk_api::{AnyResult, toml_config}; 8 | pub use rust_tool::{ToolchainSection, ToolchainToml as BaseToolchainToml}; 9 | use starbase_utils::toml::{TomlTable, TomlValue}; 10 | 11 | #[cfg(feature = "wasm")] 12 | #[host_fn] 13 | extern "ExtismHost" { 14 | fn host_log(input: Json); 15 | } 16 | 17 | toml_config!(ToolchainToml, BaseToolchainToml); 18 | 19 | impl ToolchainToml { 20 | pub fn save_field(&self, field: &str, config: &mut TomlValue) -> AnyResult<()> { 21 | let Some(root) = config.as_table_mut() else { 22 | return Ok(()); 23 | }; 24 | 25 | if field == "toolchain.channel" { 26 | if let Some(channel) = &self.toolchain.channel { 27 | let toolchain = root 28 | .entry("toolchain") 29 | .or_insert_with(|| TomlValue::Table(TomlTable::new())); 30 | 31 | if let Some(inner) = toolchain.as_table_mut() { 32 | inner.insert("channel".into(), TomlValue::String(channel.to_owned())); 33 | } 34 | } 35 | }; 36 | 37 | Ok(()) 38 | } 39 | } 40 | 41 | impl ToolchainToml { 42 | pub fn set_channel(&mut self, channel: impl AsRef) -> AnyResult { 43 | let channel = channel.as_ref(); 44 | 45 | if channel.is_empty() 46 | || self 47 | .toolchain 48 | .channel 49 | .as_ref() 50 | .is_some_and(|ch| ch == channel) 51 | { 52 | return Ok(false); 53 | } 54 | 55 | #[cfg(feature = "wasm")] 56 | { 57 | host_log!( 58 | "Setting toolchain.channel in {}", 59 | self.path, 60 | ); 61 | } 62 | 63 | self.toolchain.channel = Some(channel.into()); 64 | self.dirty.push("toolchain.channel".into()); 65 | 66 | Ok(true) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/files/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | # Standard 6 | [[package]] 7 | name = "base64" 8 | version = "0.21.7" 9 | source = "registry+https://github.com/rust-lang/crates.io-index" 10 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 11 | 12 | # Different version 13 | [[package]] 14 | name = "base64" 15 | version = "0.22.1" 16 | source = "registry+https://github.com/rust-lang/crates.io-index" 17 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 18 | 19 | # No checksum/source 20 | [[package]] 21 | name = "moon_pdk_api" 22 | version = "0.1.6" 23 | dependencies = [] 24 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/files/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = ["*"] 4 | 5 | [workspace.dependencies] 6 | a = "1.2.3" 7 | b = { version = "4.5.6" } 8 | c = { version = "7.8.9", default-features = false, features = ["on"] } 9 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/files/package/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "package" 3 | version = "1.0.0" 4 | publish = true 5 | 6 | [dependencies] 7 | a = "1.2.3" 8 | e = { version = "7.8.9", default-features = false, features = ["on"] } 9 | 10 | [dev-dependencies] 11 | b = { version = "4.5.6" } 12 | f = { path = "../other" } 13 | 14 | [build-dependencies] 15 | c.workspace = true 16 | d = { workspace = true, features = ["off"] } 17 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/locate/package-with-lock/Cargo.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/locate/package-with-lock/Cargo.lock -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/locate/package-with-lock/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pkg" 3 | version = "1.0.0" 4 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/locate/package/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pkg" 3 | version = "1.0.0" 4 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/locate/workspace-with-lock/Cargo.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/locate/workspace-with-lock/Cargo.lock -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/locate/workspace-with-lock/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = ["crates/*"] 4 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/locate/workspace-with-lock/crates/a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "a" 3 | version = "1.0.0" 4 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/locate/workspace/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = ["crates/*"] 4 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/locate/workspace/crates/a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "a" 3 | version = "1.0.0" 4 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/projects/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = ["a", "b", "c"] 4 | 5 | [workspace.dependencies] 6 | serde = { version = "1", features = ["derive"] } 7 | serde_json = "1" 8 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/projects/a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "a" 3 | version = "1.0.0" 4 | 5 | [dependencies] 6 | serde_json = { workspace = true } 7 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/projects/a/src/lib.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/projects/a/src/lib.rs -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/projects/b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "b" 3 | version = "1.0.0" 4 | 5 | [dependencies] 6 | a = "1.0.0" # Not using `path` 7 | serde.workspace = true 8 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/projects/b/src/lib.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/projects/b/src/lib.rs -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/projects/c/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "c" 3 | version = "1.0.0" 4 | 5 | [dependencies] 6 | a = { path = "../a" } 7 | 8 | [dev-dependencies] 9 | b = { path = "../b" } 10 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/projects/c/src/lib.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/projects/c/src/lib.rs -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/projects/no-manifest/file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/projects/no-manifest/file -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/prune/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_toolchain_test" 3 | version = "1.0.0" 4 | 5 | [[bin]] 6 | name = "rust_tc_test" 7 | path = "src/main.rs" 8 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/prune/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() {} 2 | -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/prune/target/other-file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/prune/target/other-file -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/prune/target/release/rust_tc_test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/prune/target/release/rust_tc_test -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/prune/target/release/rust_tc_test.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/prune/target/release/rust_tc_test.exe -------------------------------------------------------------------------------- /toolchains/rust/tests/__fixtures__/tc-cfg/rust-toolchain.toml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/rust/tests/__fixtures__/tc-cfg/rust-toolchain.toml -------------------------------------------------------------------------------- /toolchains/rust/tests/toolchain_toml_test.rs: -------------------------------------------------------------------------------- 1 | use cargo_toml::Value; 2 | use moon_pdk_api::VirtualPath; 3 | use rust_toolchain::toolchain_toml::*; 4 | use std::path::PathBuf; 5 | 6 | mod toolchain_toml { 7 | use super::*; 8 | 9 | mod set_channel { 10 | use super::*; 11 | 12 | #[test] 13 | fn adds_if_not_set() { 14 | let mut tc = ToolchainToml { 15 | path: VirtualPath::Real(PathBuf::from("/base/rust-toolchain.toml")), 16 | ..Default::default() 17 | }; 18 | 19 | assert_eq!(tc.data.toolchain.channel, None); 20 | 21 | assert!(tc.set_channel("stable").unwrap()); 22 | 23 | assert_eq!(tc.data.toolchain.channel.unwrap(), "stable"); 24 | assert_eq!(tc.dirty, ["toolchain.channel"]); 25 | } 26 | 27 | #[test] 28 | fn doesnt_add_if_empty() { 29 | let mut tc = ToolchainToml { 30 | path: VirtualPath::Real(PathBuf::from("/base/rust-toolchain.toml")), 31 | ..Default::default() 32 | }; 33 | 34 | assert_eq!(tc.data.toolchain.channel, None); 35 | 36 | assert!(!tc.set_channel("").unwrap()); 37 | 38 | assert_eq!(tc.data.toolchain.channel, None); 39 | assert!(tc.dirty.is_empty()); 40 | } 41 | 42 | #[test] 43 | fn doesnt_add_if_same_value() { 44 | let mut tc = ToolchainToml { 45 | path: VirtualPath::Real(PathBuf::from("/base/rust-toolchain.toml")), 46 | data: BaseToolchainToml { 47 | toolchain: ToolchainSection { 48 | channel: Some("stable".into()), 49 | }, 50 | }, 51 | ..Default::default() 52 | }; 53 | 54 | assert_eq!(tc.data.toolchain.channel.as_ref().unwrap(), "stable"); 55 | 56 | assert!(!tc.set_channel("stable").unwrap()); 57 | 58 | assert_eq!(tc.data.toolchain.channel.unwrap(), "stable"); 59 | assert!(tc.dirty.is_empty()); 60 | } 61 | 62 | #[test] 63 | fn saves_field_if_set() { 64 | let mut tc = ToolchainToml { 65 | path: VirtualPath::Real(PathBuf::from("/base/rust-toolchain.toml")), 66 | ..Default::default() 67 | }; 68 | 69 | tc.set_channel("stable").unwrap(); 70 | 71 | let mut root = Value::Table(Default::default()); 72 | 73 | tc.save_field("toolchain.channel", &mut root).unwrap(); 74 | 75 | assert_eq!(root["toolchain"]["channel"], Value::String("stable".into())); 76 | } 77 | 78 | #[test] 79 | fn doesnt_save_field_if_not_set() { 80 | let tc = ToolchainToml { 81 | path: VirtualPath::Real(PathBuf::from("/base/rust-toolchain.toml")), 82 | ..Default::default() 83 | }; 84 | 85 | let mut root = Value::Table(Default::default()); 86 | 87 | tc.save_field("toolchain.channel", &mut root).unwrap(); 88 | 89 | assert!(root.as_table().unwrap().is_empty()); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /toolchains/typescript/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.2.0 4 | 5 | #### 🚀 Updates 6 | 7 | - Support new toolchain APIs. 8 | 9 | #### ⚙️ Internal 10 | 11 | - Updated dependencies. 12 | 13 | ## 0.1.4 14 | 15 | #### ⚙️ Internal 16 | 17 | - Updated dependencies. 18 | 19 | ## 0.1.3 20 | 21 | #### 🐞 Fixes 22 | 23 | - Updated tsconfig parsing to not fail if an `extends` file is missing in the chain. 24 | 25 | ## 0.1.2 26 | 27 | #### 🐞 Fixes 28 | 29 | - Fixed some issues when tsconfig paths don't end with `.json`. 30 | 31 | ## 0.1.1 32 | 33 | #### 🚀 Updates 34 | 35 | - Added `initialize_toolchain` support. 36 | 37 | ## 0.1.0 38 | 39 | #### 🚀 Updates 40 | 41 | - Initial release! 42 | -------------------------------------------------------------------------------- /toolchains/typescript/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "typescript_toolchain" 3 | version = "0.2.0" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "lib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | moon_common = { workspace = true } 19 | moon_config = { workspace = true } 20 | moon_pdk = { workspace = true } 21 | moon_pdk_api = { workspace = true } 22 | moon_project = { workspace = true } 23 | # rustc-hash = { workspace = true } 24 | schematic = { workspace = true } 25 | serde = { workspace = true } 26 | starbase_utils = { workspace = true, features = ["editor-config", "json"] } 27 | typescript_tsconfig_json = { workspace = true } 28 | 29 | [dev-dependencies] 30 | moon_pdk_test_utils = { workspace = true } 31 | moon_target = { workspace = true } 32 | serde_json = { workspace = true } 33 | starbase_sandbox = { workspace = true } 34 | tokio = { workspace = true } 35 | 36 | [features] 37 | default = ["wasm"] 38 | wasm = [] 39 | -------------------------------------------------------------------------------- /toolchains/typescript/src/config.rs: -------------------------------------------------------------------------------- 1 | use moon_pdk_api::config_struct; 2 | use schematic::Schematic; 3 | 4 | config_struct!( 5 | /// Configures and enables the TypeScript toolchain. 6 | /// Docs: https://moonrepo.dev/docs/config/toolchain#typescript 7 | #[derive(Schematic)] 8 | pub struct TypeScriptToolchainConfig { 9 | /// When `syncProjectReferences` is enabled, will create a `tsconfig.json` 10 | /// in referenced projects if it does not exist. 11 | #[schema(default = true)] 12 | pub create_missing_config: bool, 13 | 14 | /// Appends sources of project reference to `include` in `tsconfig.json`, 15 | /// for each project. 16 | pub include_project_reference_sources: bool, 17 | 18 | /// Appends shared types to `include` in `tsconfig.json`, for each project. 19 | pub include_shared_types: bool, 20 | 21 | /// Name of the `tsconfig.json` file within each project. 22 | #[schema(default = "tsconfig.json")] 23 | pub project_config_file_name: String, 24 | 25 | /// The relative root to the TypeScript root. Primarily used for 26 | /// resolving project references. 27 | #[schema(default = ".")] 28 | pub root: String, 29 | 30 | /// Name of the `tsconfig.json` file at the workspace root. 31 | #[schema(default = "tsconfig.json")] 32 | pub root_config_file_name: String, 33 | 34 | /// Name of the shared compiler options `tsconfig.json` file 35 | /// at the workspace root. 36 | #[schema(default = "tsconfig.options.json")] 37 | pub root_options_config_file_name: String, 38 | 39 | /// Updates and routes `outDir` in `tsconfig.json` to moon's cache, 40 | /// for each project. 41 | pub route_out_dir_to_cache: bool, 42 | 43 | /// Syncs all project dependencies as `references` in `tsconfig.json`, 44 | /// for each project. 45 | #[schema(default = true)] 46 | pub sync_project_references: bool, 47 | 48 | /// Syncs all project dependencies as `paths` in `tsconfig.json`, 49 | /// for each project. 50 | pub sync_project_references_to_paths: bool, 51 | } 52 | ); 53 | 54 | impl Default for TypeScriptToolchainConfig { 55 | fn default() -> Self { 56 | Self { 57 | create_missing_config: true, 58 | include_project_reference_sources: false, 59 | include_shared_types: false, 60 | project_config_file_name: "tsconfig.json".into(), 61 | root: ".".into(), 62 | root_config_file_name: "tsconfig.json".into(), 63 | root_options_config_file_name: "tsconfig.options.json".into(), 64 | route_out_dir_to_cache: false, 65 | sync_project_references: true, 66 | sync_project_references_to_paths: false, 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /toolchains/typescript/src/context.rs: -------------------------------------------------------------------------------- 1 | use crate::config::TypeScriptToolchainConfig; 2 | use moon_pdk::VirtualPath; 3 | use moon_pdk_api::MoonContext; 4 | use moon_project::ProjectFragment; 5 | use std::path::PathBuf; 6 | use typescript_tsconfig_json::CompilerPath; 7 | 8 | #[derive(Debug)] 9 | pub struct TypeScriptContext { 10 | pub root_config: VirtualPath, 11 | pub root_options_config: VirtualPath, 12 | pub project_config: VirtualPath, 13 | pub workspace_root: VirtualPath, 14 | } 15 | 16 | fn create_virtual_path(base: &VirtualPath, path: PathBuf) -> VirtualPath { 17 | match base { 18 | VirtualPath::Real(_) => VirtualPath::Real(path), 19 | VirtualPath::Virtual { 20 | virtual_prefix, 21 | real_prefix, 22 | .. 23 | } => VirtualPath::Virtual { 24 | path, 25 | virtual_prefix: virtual_prefix.to_owned(), 26 | real_prefix: real_prefix.to_owned(), 27 | }, 28 | } 29 | } 30 | 31 | pub fn create_typescript_context( 32 | base: &MoonContext, 33 | config: &TypeScriptToolchainConfig, 34 | project: &ProjectFragment, 35 | ) -> TypeScriptContext { 36 | let root_config = CompilerPath::resolve( 37 | base.workspace_root 38 | .join(&config.root) 39 | .join(&config.root_config_file_name) 40 | .to_path_buf(), 41 | ); 42 | let root_options_config = CompilerPath::resolve( 43 | base.workspace_root 44 | .join(&config.root) 45 | .join(&config.root_options_config_file_name) 46 | .to_path_buf(), 47 | ); 48 | let project_config = CompilerPath::resolve( 49 | base.workspace_root 50 | .join(&project.source) 51 | .join(&config.project_config_file_name) 52 | .to_path_buf(), 53 | ); 54 | 55 | TypeScriptContext { 56 | root_config: create_virtual_path(&base.workspace_root, root_config), 57 | root_options_config: create_virtual_path(&base.workspace_root, root_options_config), 58 | project_config: create_virtual_path(&base.workspace_root, project_config), 59 | workspace_root: base.workspace_root.clone(), 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /toolchains/typescript/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod tsconfig_json; 3 | 4 | #[cfg(feature = "wasm")] 5 | mod context; 6 | #[cfg(feature = "wasm")] 7 | mod tier1; 8 | #[cfg(feature = "wasm")] 9 | mod tier1_sync; 10 | #[cfg(feature = "wasm")] 11 | mod tier2; 12 | 13 | #[cfg(feature = "wasm")] 14 | pub use tier1::*; 15 | #[cfg(feature = "wasm")] 16 | pub use tier2::*; 17 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/configs/a/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.inherits.json", 3 | "compilerOptions": { 4 | "traceResolution": false, 5 | "declaration": true, 6 | "jsx": "react-native", 7 | "moduleResolution": "node" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/configs/b/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "useDefineForClassFields": false, 4 | "traceResolution": true, 5 | "jsx": "preserve", 6 | "module": "esnext" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/configs/tsconfig.inherits.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./b/tsconfig.json", 3 | "compilerOptions": { 4 | "traceResolution": false, 5 | "declaration": true, 6 | "jsx": "react-jsxdev", 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/configs/tsconfig.multi-inherits.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["./a/tsconfig.json", "./b/tsconfig.json"], 3 | "compilerOptions": { 4 | "traceResolution": false, 5 | "declaration": true, 6 | "moduleResolution": "bundler" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/create-custom/no-config/empty: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/create-custom/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "nodenext" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/create-custom/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "no-options" } 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/hashing/no-config/empty: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/hashing/no-options/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/hashing/only-extend-root-options/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.options.json" 3 | } 4 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/hashing/out-dir/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./out" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/hashing/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "no-options" } 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/hashing/tsconfig.options.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "nodenext" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/hashing/with-options/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.options.json", 3 | "compilerOptions": { 4 | "target": "es2020" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-custom/no-refs/tsconfig.ref.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-custom/tsconfig.root.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/a/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/typescript/tests/__fixtures__/refs-paths/a/index.ts -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "a" 3 | } 4 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/a/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/b/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "b" 3 | } 4 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/b/src/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/typescript/tests/__fixtures__/refs-paths/b/src/index.ts -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/b/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/c/index.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/typescript/tests/__fixtures__/refs-paths/c/index.tsx -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/c/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@org/c" 3 | } 4 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/c/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/d/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/other/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-paths/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-root-level/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-root-level/tsconfig.project.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-sibling-root/no-refs/tsconfig.ref.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs-sibling-root/root/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs/a/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs/all-refs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "references": [{ "path": "../a" }, { "path": "../b" }, { "path": "../c" }] 3 | } 4 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs/b/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs/c/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs/d/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moonrepo/plugins/b895f28eac1b0234c47b114d0ab407318dc13c01/toolchains/typescript/tests/__fixtures__/refs/d/empty -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs/no-refs/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs/some-refs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "references": [{ "path": "../b" }] 3 | } 4 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/__fixtures__/refs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [] 4 | } 5 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__create_missing_config__creates_if_missing.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(cfg_path).unwrap()" 4 | --- 5 | { 6 | "extends": "../tsconfig.options.json", 7 | "include": [ 8 | "**/*" 9 | ], 10 | "references": [] 11 | } 12 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__create_missing_config__creates_if_missing_with_custom_options.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(cfg_path).unwrap()" 4 | --- 5 | { 6 | "extends": "../tsconfig.base.json", 7 | "include": [ 8 | "**/*" 9 | ], 10 | "references": [] 11 | } 12 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__include_project_reference_sources__adds_includes_from_refs.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"no-refs/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "references": [ 7 | { 8 | "path": "../a" 9 | }, 10 | { 11 | "path": "../b" 12 | }, 13 | { 14 | "path": "../c" 15 | } 16 | ], 17 | "include": [ 18 | "../a/**/*", 19 | "../b/**/*", 20 | "../c/**/*" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__include_shared_types__adds_if_folder_exists.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"no-refs/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "include": [ 7 | "../types/**/*" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__route_out_dir_to_cache__adds_when_has_options.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"with-options/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "extends": "../tsconfig.options.json", 7 | "compilerOptions": { 8 | "target": "es2020", 9 | "outDir": "../.moon/cache/types/with-options" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__route_out_dir_to_cache__adds_when_no_options.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"no-options/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "compilerOptions": { 7 | "outDir": "../.moon/cache/types/no-options" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__route_out_dir_to_cache__overrides_out_dir.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"out-dir/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "compilerOptions": { 7 | "outDir": "../.moon/cache/types/out-dir" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__sync_project_references__adds_deps_as_refs.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"no-refs/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "references": [ 7 | { 8 | "path": "../a" 9 | }, 10 | { 11 | "path": "../b" 12 | }, 13 | { 14 | "path": "../c" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__sync_project_references__doesnt_dupe_add_refs.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"some-refs/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "references": [ 7 | { 8 | "path": "../a" 9 | }, 10 | { 11 | "path": "../b" 12 | }, 13 | { 14 | "path": "../c" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__sync_project_references_to_paths__adds_paths_for_refs.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"other/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "references": [ 7 | { 8 | "path": "../a" 9 | }, 10 | { 11 | "path": "../b" 12 | }, 13 | { 14 | "path": "../c" 15 | }, 16 | { 17 | "path": "../d" 18 | } 19 | ], 20 | "compilerOptions": { 21 | "paths": { 22 | "a": [ 23 | "../a/index.ts" 24 | ], 25 | "a/*": [ 26 | "../a/*" 27 | ], 28 | "b": [ 29 | "../b/src/index.ts" 30 | ], 31 | "b/*": [ 32 | "../b/src/*" 33 | ], 34 | "@org/c": [ 35 | "../c/index.tsx" 36 | ], 37 | "@org/c/*": [ 38 | "../c/*" 39 | ] 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__sync_project_references_to_paths__doesnt_add_if_paths_sync_disabled.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"other/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "references": [ 7 | { 8 | "path": "../a" 9 | }, 10 | { 11 | "path": "../b" 12 | }, 13 | { 14 | "path": "../c" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__sync_root_project_reference__adds_project_as_ref.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "files": [], 7 | "references": [ 8 | { 9 | "path": "no-refs" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__sync_root_project_reference__adds_project_as_ref_with_custom_options.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"tsconfig.root.json\")).unwrap()" 4 | --- 5 | { 6 | "files": [], 7 | "references": [ 8 | { 9 | "path": "no-refs/tsconfig.ref.json" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__sync_root_project_reference__works_with_root_dir.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"root/tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "files": [], 7 | "references": [ 8 | { 9 | "path": "../no-refs" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/snapshots/tier1_sync_test__typescript_toolchain_tier1__sync_root_project_reference__works_with_root_level_project.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: toolchains/typescript/tests/tier1_sync_test.rs 3 | expression: "fs::read_file(sandbox.path().join(\"tsconfig.json\")).unwrap()" 4 | --- 5 | { 6 | "files": [], 7 | "references": [ 8 | { 9 | "path": "tsconfig.project.json" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /toolchains/typescript/tests/utils.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use moon_common::Id; 4 | use moon_pdk_api::{ProjectFragment, SyncOutput, TaskFragment}; 5 | use moon_target::Target; 6 | 7 | pub fn create_project(id: &str) -> ProjectFragment { 8 | ProjectFragment { 9 | alias: None, 10 | dependency_scope: None, 11 | id: Id::raw(id), 12 | source: id.into(), 13 | toolchains: vec![Id::raw("typescript"), Id::raw("javascript")], 14 | } 15 | } 16 | 17 | pub fn create_project_dependencies() -> Vec { 18 | vec![ 19 | create_project("a"), 20 | create_project("b"), 21 | create_project("c"), 22 | ] 23 | } 24 | 25 | pub fn create_task(target: &str) -> TaskFragment { 26 | TaskFragment { 27 | target: Target::parse(target).unwrap(), 28 | toolchains: vec![Id::raw("typescript"), Id::raw("javascript")], 29 | } 30 | } 31 | 32 | pub fn has_changed_file(output: &SyncOutput, name: &str) -> bool { 33 | output 34 | .changed_files 35 | .iter() 36 | .any(|file| file.as_os_str() == name) 37 | } 38 | -------------------------------------------------------------------------------- /tools/bun/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bun_tool" 3 | version = "0.15.2" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | schematic = { workspace = true } 20 | serde = { workspace = true } 21 | 22 | [dev-dependencies] 23 | proto_pdk_test_utils = { workspace = true } 24 | starbase_sandbox = { workspace = true } 25 | tokio = { workspace = true } 26 | 27 | [features] 28 | default = ["wasm"] 29 | wasm = [] 30 | -------------------------------------------------------------------------------- /tools/bun/README.md: -------------------------------------------------------------------------------- 1 | # Bun plugin 2 | 3 | [Bun](https://bun.sh/) WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 8 | 9 | ```toml 10 | [plugins] 11 | bun = "https://github.com/moonrepo/plugins/releases/download/bun_tool-vX.Y.Z/bun_tool.wasm" 12 | ``` 13 | 14 | ## Configuration 15 | 16 | Bun plugin can be configured with a `.prototools` file. 17 | 18 | - `dist-url` (string) - The distribution URL to download Bun archives from. Supports `{version}` and `{file}` tokens. 19 | 20 | ```toml 21 | [tools.bun] 22 | dist-url = "https://..." 23 | ``` 24 | 25 | ## Hooks 26 | 27 | Bun plugin does not support hooks. 28 | 29 | ## Caveats 30 | 31 | Bun supports a `bunx` executable, which is a shortcut for `bun x` (note the space). It achieves this through some file name magic, as the `bunx` file is exactly the same as the `bun` file, jsut the exec functionality is toggled on/off based on the file name (derived from `args[0]`). 32 | 33 | Supporting this in proto is tricky. For symlinked binaries, we can easily support this, as we symlink the `bun` binary to `~/.proto/bin/bunx`. However, for the shim `~/.proto/shims/bunx`, we can't do this, as we execute `bun` as a child process, as there's no `bunx` file to execute (Bun doesn't provide it), and the file name magic doesn't happen. So for the shim, we execute `bun x` under the hood instead. 34 | 35 | This caveat only really matters in regards to the `--bun` flag, which works for bins, _but not_ for shims. 36 | 37 | ## Contributing 38 | 39 | Build the plugin: 40 | 41 | ```shell 42 | cargo build --target wasm32-wasip1 43 | ``` 44 | 45 | Test the plugin by running `proto` commands. 46 | 47 | ```shell 48 | proto install bun-test 49 | proto versions bun-test 50 | ``` 51 | -------------------------------------------------------------------------------- /tools/bun/src/config.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, schematic::Schematic, serde::Deserialize, serde::Serialize)] 2 | #[serde(default, deny_unknown_fields, rename_all = "kebab-case")] 3 | pub struct BunPluginConfig { 4 | pub dist_url: String, 5 | } 6 | 7 | impl Default for BunPluginConfig { 8 | fn default() -> Self { 9 | Self { 10 | dist_url: "https://github.com/oven-sh/bun/releases/download/bun-v{version}/{file}" 11 | .into(), 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tools/bun/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod config; 2 | 3 | #[cfg(feature = "wasm")] 4 | mod proto; 5 | 6 | #[cfg(feature = "wasm")] 7 | pub use proto::*; 8 | -------------------------------------------------------------------------------- /tools/bun/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod bun_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn registers_metadata() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let plugin = sandbox.create_plugin("bun-test").await; 10 | 11 | let metadata = plugin.register_tool(RegisterToolInput::default()).await; 12 | 13 | assert_eq!(metadata.name, "Bun"); 14 | assert_eq!(metadata.self_upgrade_commands, vec!["upgrade"]); 15 | assert_eq!( 16 | metadata.plugin_version.unwrap().to_string(), 17 | env!("CARGO_PKG_VERSION") 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tools/bun/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod bun_tool { 4 | use super::*; 5 | 6 | #[cfg(not(windows))] 7 | generate_shims_test!("bun-test", ["bun", "bunx"]); 8 | } 9 | -------------------------------------------------------------------------------- /tools/bun/tests/snapshots/shims_test__bun_tool__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/bun/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "bun": {}, 7 | "bunx": { 8 | "parent": "bun-test", 9 | "before_args": [ 10 | "x" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tools/bun/tests/versions_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod bun_tool { 4 | use super::*; 5 | 6 | generate_resolve_versions_tests!("bun-test", { 7 | "0.4" => "0.4.0", 8 | "0.5.1" => "0.5.1", 9 | "1.1.0" => "1.1.0", 10 | }); 11 | 12 | #[tokio::test(flavor = "multi_thread")] 13 | async fn loads_versions_from_git() { 14 | let sandbox = create_empty_proto_sandbox(); 15 | let plugin = sandbox.create_plugin("bun-test").await; 16 | 17 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 18 | 19 | assert!(!output.versions.is_empty()); 20 | } 21 | 22 | #[tokio::test(flavor = "multi_thread")] 23 | async fn sets_latest_alias() { 24 | let sandbox = create_empty_proto_sandbox(); 25 | let plugin = sandbox.create_plugin("bun-test").await; 26 | 27 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 28 | 29 | assert!(output.latest.is_some()); 30 | assert!(output.aliases.contains_key("latest")); 31 | assert_eq!(output.aliases.get("latest"), output.latest.as_ref()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tools/deno/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "deno_tool" 3 | version = "0.15.4" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | schematic = { workspace = true } 20 | serde = { workspace = true } 21 | 22 | [dev-dependencies] 23 | proto_pdk_test_utils = { workspace = true } 24 | starbase_sandbox = { workspace = true } 25 | tokio = { workspace = true } 26 | 27 | [features] 28 | default = ["wasm"] 29 | wasm = [] 30 | -------------------------------------------------------------------------------- /tools/deno/README.md: -------------------------------------------------------------------------------- 1 | # Deno plugin 2 | 3 | [Deno](https://deno.land/) WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 8 | 9 | ```toml 10 | [plugins] 11 | deno = "https://github.com/moonrepo/plugins/releases/download/deno_tool-vX.Y.Z/deno_tool.wasm" 12 | ``` 13 | 14 | ## Configuration 15 | 16 | Deno plugin can be configured with a `.prototools` file. 17 | 18 | - `dist-url` (string) - The distribution URL to download Deno archives from. Supports `{version}` and `{file}` tokens. 19 | 20 | ```toml 21 | [tools.deno] 22 | dist-url = "https://..." 23 | ``` 24 | 25 | ## Hooks 26 | 27 | Deno plugin does not support hooks. 28 | 29 | ## Contributing 30 | 31 | Build the plugin: 32 | 33 | ```shell 34 | cargo build --target wasm32-wasip1 35 | ``` 36 | 37 | Test the plugin by running `proto` commands. 38 | 39 | ```shell 40 | proto install deno-test 41 | proto versions deno-test 42 | ``` 43 | -------------------------------------------------------------------------------- /tools/deno/src/config.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, schematic::Schematic, serde::Deserialize, serde::Serialize)] 2 | #[serde(default, deny_unknown_fields, rename_all = "kebab-case")] 3 | pub struct DenoPluginConfig { 4 | pub dist_url: String, 5 | } 6 | 7 | impl Default for DenoPluginConfig { 8 | fn default() -> Self { 9 | Self { 10 | dist_url: "https://github.com/denoland/deno/releases/download/v{version}/{file}".into(), 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tools/deno/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod config; 2 | 3 | #[cfg(feature = "wasm")] 4 | mod proto; 5 | 6 | #[cfg(feature = "wasm")] 7 | pub use proto::*; 8 | -------------------------------------------------------------------------------- /tools/deno/tests/build_test.rs: -------------------------------------------------------------------------------- 1 | // use proto_pdk_test_utils::*; 2 | 3 | // mod deno_tool { 4 | // use super::*; 5 | 6 | // generate_build_install_tests!("deno-test", "2.0.0"); 7 | // } 8 | -------------------------------------------------------------------------------- /tools/deno/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod deno_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn registers_metadata() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let plugin = sandbox.create_plugin("deno-test").await; 10 | 11 | let metadata = plugin.register_tool(RegisterToolInput::default()).await; 12 | 13 | assert_eq!(metadata.name, "Deno"); 14 | assert_eq!(metadata.self_upgrade_commands, vec!["upgrade"]); 15 | assert_eq!( 16 | metadata.plugin_version.unwrap().to_string(), 17 | env!("CARGO_PKG_VERSION") 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tools/deno/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod deno_tool { 4 | use super::*; 5 | 6 | #[cfg(not(windows))] 7 | generate_shims_test!("deno-test", ["deno"]); 8 | } 9 | -------------------------------------------------------------------------------- /tools/deno/tests/snapshots/shims_test__deno_tool__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/deno/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "deno": {} 7 | } 8 | -------------------------------------------------------------------------------- /tools/deno/tests/versions_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod deno_tool { 4 | use super::*; 5 | 6 | generate_resolve_versions_tests!("deno-test", { 7 | "1.19" => "1.19.3", 8 | "1.11" => "1.11.5", 9 | "1.9.2" => "1.9.2", 10 | }); 11 | 12 | #[tokio::test(flavor = "multi_thread")] 13 | async fn loads_versions_from_git() { 14 | let sandbox = create_empty_proto_sandbox(); 15 | let plugin = sandbox.create_plugin("deno-test").await; 16 | 17 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 18 | 19 | assert!(!output.versions.is_empty()); 20 | } 21 | 22 | #[tokio::test(flavor = "multi_thread")] 23 | async fn sets_latest_alias() { 24 | let sandbox = create_empty_proto_sandbox(); 25 | let plugin = sandbox.create_plugin("deno-test").await; 26 | 27 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 28 | 29 | assert!(output.latest.is_some()); 30 | assert!(output.aliases.contains_key("latest")); 31 | assert_eq!(output.aliases.get("latest"), output.latest.as_ref()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tools/go/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "go_tool" 3 | version = "0.16.2" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | schematic = { workspace = true } 20 | serde = { workspace = true } 21 | 22 | [dev-dependencies] 23 | proto_pdk_test_utils = { workspace = true } 24 | starbase_sandbox = { workspace = true } 25 | tokio = { workspace = true } 26 | 27 | [features] 28 | default = ["wasm"] 29 | wasm = [] 30 | -------------------------------------------------------------------------------- /tools/go/README.md: -------------------------------------------------------------------------------- 1 | # Go plugin 2 | 3 | [Go](https://go.dev/) WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | ```shell 8 | proto install go 9 | ``` 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | go = "https://github.com/moonrepo/plugins/releases/download/go_tool-vX.Y.Z/go_tool.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | Go plugin can be configured with a `.prototools` file. 21 | 22 | - `dist-url` (string) - The distribution URL to download Go archives from. Supports `{version}` and `{file}` tokens. 23 | - `gobin` (bool) - When enabled, will inject a `GOBIN` environment variable into your shell. Defaults to `false`. 24 | 25 | ```toml 26 | [tools.go] 27 | dist-url = "https://..." 28 | gobin = false 29 | ``` 30 | 31 | ## Hooks 32 | 33 | ### Post-install 34 | 35 | After installation, we'll inject a `GOBIN` environment variable into your shell, pointing to 36 | `~/go/bin`, if it does not already exist. This variable will be used to locate Go binaries across 37 | all installed versions. This functionality can be skipped by passing `--no-gobin` during 38 | installation, or setting the `gobin` configuration to `false`. 39 | 40 | ```shell 41 | proto install go -- --no-gobin 42 | ``` 43 | 44 | ## Contributing 45 | 46 | Build the plugin: 47 | 48 | ```shell 49 | cargo build --target wasm32-wasip1 50 | ``` 51 | 52 | Test the plugin by running `proto` commands. 53 | 54 | ```shell 55 | proto install go-test 56 | proto versions go-test 57 | ``` 58 | -------------------------------------------------------------------------------- /tools/go/src/config.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, schematic::Schematic, serde::Deserialize, serde::Serialize)] 2 | #[serde(default, deny_unknown_fields, rename_all = "kebab-case")] 3 | pub struct GoPluginConfig { 4 | pub dist_url: String, 5 | pub gobin: bool, 6 | } 7 | 8 | impl Default for GoPluginConfig { 9 | fn default() -> Self { 10 | Self { 11 | dist_url: "https://dl.google.com/go/{file}".into(), 12 | gobin: false, 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tools/go/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod config; 2 | #[cfg(feature = "wasm")] 3 | mod proto; 4 | #[cfg(feature = "wasm")] 5 | mod version; 6 | 7 | #[cfg(feature = "wasm")] 8 | pub use proto::*; 9 | -------------------------------------------------------------------------------- /tools/go/tests/build_test.rs: -------------------------------------------------------------------------------- 1 | // NOTE: Doesn't work in GitHub CI. 2 | 3 | // use proto_pdk_test_utils::*; 4 | 5 | // mod go_tool { 6 | // use super::*; 7 | 8 | // generate_build_install_tests!("go-test", "1.21.0"); 9 | // } 10 | -------------------------------------------------------------------------------- /tools/go/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod go_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn registers_metadata() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let plugin = sandbox.create_plugin("go-test").await; 10 | 11 | let metadata = plugin.register_tool(RegisterToolInput::default()).await; 12 | 13 | assert_eq!(metadata.name, "Go"); 14 | assert_eq!( 15 | metadata.plugin_version.unwrap().to_string(), 16 | env!("CARGO_PKG_VERSION") 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tools/go/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod go_tool { 4 | use super::*; 5 | 6 | #[cfg(not(windows))] 7 | generate_shims_test!("go-test", ["go"]); 8 | } 9 | -------------------------------------------------------------------------------- /tools/go/tests/snapshots/shims_test__go_tool__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/go/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "go": {}, 7 | "gofmt": { 8 | "alt_bin": true, 9 | "parent": "go-test" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tools/internal-schema/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "schema_tool" 3 | version = "0.17.3" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | regex = { workspace = true, features = ["unicode-perl"] } 20 | serde = { workspace = true } 21 | serde_json = { workspace = true } 22 | 23 | [dev-dependencies] 24 | proto_pdk_test_utils = { workspace = true, features = ["schema"] } 25 | starbase_sandbox = { workspace = true } 26 | tokio = { workspace = true } 27 | 28 | [features] 29 | default = ["wasm"] 30 | wasm = [] 31 | -------------------------------------------------------------------------------- /tools/internal-schema/README.md: -------------------------------------------------------------------------------- 1 | # Schema-based plugin 2 | 3 | A WASM plugin that powers [proto](https://github.com/moonrepo/proto)'s [TOML plugin](https://moonrepo.dev/docs/proto/toml-plugin) pattern. This plugin is responsible for parsing the TOML schema file and providing the necessary information to proto by implementing the applicable WASM functions. 4 | 5 | ## Installation 6 | 7 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 8 | 9 | ```toml 10 | [plugins] 11 | internal-schema = "https://github.com/moonrepo/plugins/releases/download/schema_tool-vX.Y.Z/schema_tool.wasm" 12 | ``` 13 | 14 | ## Configuration 15 | 16 | This plugin does not support configuration. 17 | 18 | ## Hooks 19 | 20 | This plugin does not support hooks. 21 | 22 | ## Contributing 23 | 24 | Build the plugin: 25 | 26 | ```shell 27 | cargo build --target wasm32-wasip1 28 | ``` 29 | 30 | Test the plugin by running `proto` commands. 31 | 32 | ```shell 33 | proto install moon-test 34 | proto versions moon-test 35 | ``` 36 | 37 | > Since this plugin requires an external schema file, its testing uses moon: https://moonrepo.dev/docs/install#proto 38 | -------------------------------------------------------------------------------- /tools/internal-schema/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod proto; 3 | mod schema; 4 | 5 | #[cfg(feature = "wasm")] 6 | pub use proto::*; 7 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/__fixtures__/schemas/base.toml: -------------------------------------------------------------------------------- 1 | bin = "moon-test" 2 | name = "moon-test" 3 | type = "cli" 4 | 5 | [platform.linux] 6 | download-file = "moon-{arch}-unknown-linux-{libc}" 7 | 8 | [platform.macos] 9 | download-file = "moon-{arch}-apple-darwin" 10 | 11 | [platform.windows] 12 | download-file = "moon-{arch}-pc-windows-msvc.exe" 13 | 14 | [install] 15 | download-url = "https://github.com/moonrepo/moon/releases/download/v{version}/{download_file}" 16 | unpack = false 17 | 18 | [resolve] 19 | git-url = "https://github.com/moonrepo/moon" 20 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/__fixtures__/schemas/bins.toml: -------------------------------------------------------------------------------- 1 | bin = "moon-test" 2 | name = "moon-test" 3 | type = "cli" 4 | 5 | [platform.linux] 6 | archive-prefix = "moon-linux-{arch}-{version}" 7 | download-file = "moon-{arch}-unknown-linux-gnu" 8 | exe-path = "lin/moon" 9 | 10 | [platform.macos] 11 | checksum-file = "SHASUM256.txt" 12 | download-file = "moon-{arch}-apple-darwin" 13 | # Use deprecated field 14 | bin-path = "mac/moon" 15 | 16 | [platform.windows] 17 | download-file = "moon-{arch}-pc-windows-msvc.exe" 18 | exe-path = "win/moon.exe" 19 | 20 | [install] 21 | download-url = "https://github.com/moonrepo/moon/releases/download/v{version}/{download_file}" 22 | 23 | [resolve] 24 | git-url = "https://github.com/moonrepo/moon" 25 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/__fixtures__/schemas/primary-platform.toml: -------------------------------------------------------------------------------- 1 | bin = "moon-test" 2 | name = "moon-test" 3 | type = "cli" 4 | 5 | [platform.linux] 6 | exe-path = "lin/moon" 7 | 8 | [platform.macos] 9 | # Use deprecated field 10 | bin-path = "mac/moon" 11 | 12 | [platform.windows] 13 | exe-path = "win/moon.exe" 14 | 15 | [install.primary] 16 | exe-path = "bin/moon" 17 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/__fixtures__/schemas/primary.toml: -------------------------------------------------------------------------------- 1 | bin = "moon-test" 2 | name = "moon-test" 3 | type = "cli" 4 | 5 | [platform.linux] 6 | download-file = "moon-{arch}-unknown-linux-{libc}" 7 | 8 | [platform.macos] 9 | download-file = "moon-{arch}-apple-darwin" 10 | 11 | [platform.windows] 12 | download-file = "moon-{arch}-pc-windows-msvc.exe" 13 | 14 | [install.primary] 15 | exe-path = "bin/moon" 16 | no-shim = true 17 | shim-before-args = ["-v"] 18 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/__fixtures__/schemas/secondary.toml: -------------------------------------------------------------------------------- 1 | bin = "moon-test" 2 | name = "moon-test" 3 | type = "cli" 4 | 5 | [platform.linux] 6 | download-file = "moon-{arch}-unknown-linux-{libc}" 7 | 8 | [platform.macos] 9 | download-file = "moon-{arch}-apple-darwin" 10 | 11 | [platform.windows] 12 | download-file = "moon-{arch}-pc-windows-msvc.exe" 13 | 14 | [install.secondary.foo] 15 | exe-path = "bin/foo" 16 | 17 | [install.secondary.bar] 18 | exe-path = "bin/bar" 19 | no-bin = true 20 | shim-env-vars = { "BAR" = "bar" } 21 | 22 | [install.secondary.baz] 23 | exe-path = "bin/baz" 24 | exe-link-path = "bin/baz-link" 25 | no-shim = true 26 | 27 | [install.secondary.qux] 28 | exe-path = "bin/qux.js" 29 | parent-exe-name = "node" 30 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/__fixtures__/schemas/version-pattern.toml: -------------------------------------------------------------------------------- 1 | bin = "moon-test" 2 | name = "moon-test" 3 | type = "cli" 4 | 5 | [platform.linux] 6 | download-file = "moon-{arch}-unknown-linux-{libc}" 7 | 8 | [platform.macos] 9 | download-file = "moon-{arch}-apple-darwin" 10 | 11 | [platform.windows] 12 | download-file = "moon-{arch}-pc-windows-msvc.exe" 13 | 14 | [install] 15 | download-url = "https://github.com/moonrepo/moon/releases/download/v{version}/{download_file}" 16 | unpack = false 17 | 18 | [resolve] 19 | git-url = "https://github.com/moonrepo/moon" 20 | version-pattern = "^v((?\\d+)\\.(?\\d+)\\.(?\\d+))" 21 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | use starbase_sandbox::locate_fixture; 3 | 4 | mod schema_tool { 5 | use super::*; 6 | 7 | #[tokio::test(flavor = "multi_thread")] 8 | async fn registers_metadata() { 9 | let sandbox = create_empty_proto_sandbox(); 10 | let plugin = sandbox 11 | .create_schema_plugin("schema-test", locate_fixture("schemas").join("base.toml")) 12 | .await; 13 | 14 | let metadata = plugin.register_tool(RegisterToolInput::default()).await; 15 | 16 | assert_eq!(metadata.name, "moon-test"); 17 | assert_eq!( 18 | metadata.plugin_version.unwrap().to_string(), 19 | env!("CARGO_PKG_VERSION") 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | use starbase_sandbox::locate_fixture; 3 | 4 | mod schema_tool { 5 | use super::*; 6 | 7 | #[cfg(not(windows))] 8 | generate_shims_test!( 9 | "schema-test", 10 | ["schema-test"], 11 | Some(locate_fixture("schemas").join("base.toml")) 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/snapshots/shims_test__schema_tool__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/internal-schema/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "schema-test": {} 7 | } 8 | -------------------------------------------------------------------------------- /tools/internal-schema/tests/versions_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | use starbase_sandbox::locate_fixture; 3 | 4 | mod schema_tool { 5 | use super::*; 6 | 7 | generate_resolve_versions_tests!( 8 | "schema-test", 9 | { 10 | "1.0.3" => "1.0.3", 11 | "1.4" => "1.4.0", 12 | "1.5" => "1.5.1", 13 | }, 14 | Some(locate_fixture("schemas").join("base.toml")) 15 | ); 16 | 17 | #[tokio::test(flavor = "multi_thread")] 18 | async fn loads_versions_from_git_tags() { 19 | let sandbox = create_empty_proto_sandbox(); 20 | let plugin = sandbox 21 | .create_schema_plugin("schema-test", locate_fixture("schemas").join("base.toml")) 22 | .await; 23 | 24 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 25 | 26 | assert!(!output.versions.is_empty()); 27 | } 28 | 29 | #[tokio::test(flavor = "multi_thread")] 30 | async fn sets_latest_alias() { 31 | let sandbox = create_empty_proto_sandbox(); 32 | let plugin = sandbox 33 | .create_schema_plugin("schema-test", locate_fixture("schemas").join("base.toml")) 34 | .await; 35 | 36 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 37 | 38 | assert!(output.latest.is_some()); 39 | assert!(output.aliases.contains_key("latest")); 40 | assert_eq!(output.aliases.get("latest"), output.latest.as_ref()); 41 | } 42 | 43 | #[tokio::test(flavor = "multi_thread")] 44 | async fn version_pattern_supports_common_classes() { 45 | let sandbox = create_empty_proto_sandbox(); 46 | let plugin = sandbox 47 | .create_schema_plugin( 48 | "schema-test", 49 | locate_fixture("schemas").join("version-pattern.toml"), 50 | ) 51 | .await; 52 | 53 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 54 | 55 | assert!(!output.versions.is_empty()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tools/moon/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.3.2 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.3.1 10 | 11 | #### 🚀 Updates 12 | 13 | - Updated to support proto v0.47 release. 14 | 15 | ## 0.3.0 16 | 17 | #### 🐞 Fixes 18 | 19 | - Fixed the wrong binary name being used when building from source. 20 | 21 | ## 0.2.0 22 | 23 | #### 🚀 Updates 24 | 25 | - Updated to support proto v0.46 release. 26 | 27 | ## 0.1.0 28 | 29 | #### 🚀 Updates 30 | 31 | - Added build from source support. 32 | 33 | ## 0.0.2 34 | 35 | #### 🎉 Release 36 | 37 | - Initial release! 38 | -------------------------------------------------------------------------------- /tools/moon/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "moon_tool" 3 | version = "0.3.2" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | serde = { workspace = true } 20 | 21 | [dev-dependencies] 22 | proto_pdk_test_utils = { workspace = true } 23 | starbase_sandbox = { workspace = true } 24 | tokio = { workspace = true } 25 | 26 | [features] 27 | default = ["wasm"] 28 | wasm = [] 29 | -------------------------------------------------------------------------------- /tools/moon/README.md: -------------------------------------------------------------------------------- 1 | # moon plugin 2 | 3 | moon WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | ```shell 8 | proto install moon 9 | ``` 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | moon = "https://github.com/moonrepo/plugins/releases/download/moon_tool-vX.Y.Z/moon_tool.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | moon plugin does not support configuration. 21 | 22 | ## Hooks 23 | 24 | moon plugin does not support hooks. 25 | 26 | ## Contributing 27 | 28 | Build the plugins: 29 | 30 | ```shell 31 | cargo build --target wasm32-wasip1 32 | ``` 33 | 34 | Test the plugins by running `proto` commands. 35 | 36 | ```shell 37 | proto install moon-test 38 | proto versions moon-test 39 | ``` 40 | -------------------------------------------------------------------------------- /tools/moon/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod proto; 3 | 4 | #[cfg(feature = "wasm")] 5 | pub use proto::*; 6 | -------------------------------------------------------------------------------- /tools/moon/tests/build_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod moon_tool { 4 | use super::*; 5 | 6 | generate_build_install_tests!("moon-test", "1.30.0"); 7 | } 8 | -------------------------------------------------------------------------------- /tools/moon/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod moon_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn registers_metadata() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let plugin = sandbox.create_plugin("moon-test").await; 10 | 11 | let metadata = plugin.register_tool(RegisterToolInput::default()).await; 12 | 13 | assert_eq!(metadata.name, "moon"); 14 | assert_eq!(metadata.self_upgrade_commands, vec!["upgrade"]); 15 | assert_eq!( 16 | metadata.plugin_version.unwrap().to_string(), 17 | env!("CARGO_PKG_VERSION") 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tools/moon/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod moon_tool { 4 | use super::*; 5 | 6 | #[cfg(not(windows))] 7 | generate_shims_test!("moon-test", ["moon"]); 8 | } 9 | -------------------------------------------------------------------------------- /tools/moon/tests/snapshots/shims_test__moon_tool__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/moon/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "moon": {} 7 | } 8 | -------------------------------------------------------------------------------- /tools/moon/tests/versions_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod moon_tool { 4 | use super::*; 5 | 6 | generate_resolve_versions_tests!("moon-test", { 7 | "1.0" => "1.0.3", 8 | "1.22" => "1.22.10", 9 | "1.31.0" => "1.31.0", 10 | }); 11 | 12 | #[tokio::test(flavor = "multi_thread")] 13 | async fn loads_versions_from_git() { 14 | let sandbox = create_empty_proto_sandbox(); 15 | let plugin = sandbox.create_plugin("moon-test").await; 16 | 17 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 18 | 19 | assert!(!output.versions.is_empty()); 20 | } 21 | 22 | #[tokio::test(flavor = "multi_thread")] 23 | async fn sets_latest_alias() { 24 | let sandbox = create_empty_proto_sandbox(); 25 | let plugin = sandbox.create_plugin("moon-test").await; 26 | 27 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 28 | 29 | assert!(output.latest.is_some()); 30 | assert!(output.aliases.contains_key("latest")); 31 | assert_eq!(output.aliases.get("latest"), output.latest.as_ref()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tools/node-depman/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "node_depman_tool" 3 | version = "0.15.2" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | lang_node_common = { path = "../../crates/lang-node-common" } 18 | extism-pdk = { workspace = true } 19 | nodejs_package_json = { workspace = true } 20 | proto_pdk = { workspace = true } 21 | regex = { workspace = true, features = ["unicode"] } 22 | schematic = { workspace = true } 23 | serde = { workspace = true } 24 | 25 | [dev-dependencies] 26 | proto_pdk_api = { workspace = true } 27 | proto_pdk_test_utils = { workspace = true } 28 | serde_json = { workspace = true } 29 | starbase_sandbox = { workspace = true } 30 | tokio = { workspace = true } 31 | 32 | [features] 33 | default = ["wasm"] 34 | wasm = [] 35 | -------------------------------------------------------------------------------- /tools/node-depman/README.md: -------------------------------------------------------------------------------- 1 | # Node.js package manager plugins 2 | 3 | npm, pnpm, and yarn WASM plugins for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | ```shell 8 | proto install npm|pnpm|yarn 9 | ``` 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | npm|pnpm|yarn = "https://github.com/moonrepo/plugins/releases/download/node_depman_tool-vX.Y.Z/node_depman_tool.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | All plugins can be configured with a `.prototools` file. 21 | 22 | - `dist-url` (string) - The distribution URL to download npm registry archives from. Supports `{package}`, `{package_without_scope}`, `{version}`, and `{file}` tokens. 23 | - `shared-globals-dir` (bool) - EXPERIMENTAL: Global npm, pnpm, or yarn packages are installed to a shared location: `~/.proto/tools/node/globals`. Defaults to `false`. 24 | 25 | ```toml 26 | [tools.npm] 27 | dist-url = "https://..." 28 | shared-globals-dir = true 29 | 30 | # [tools.pnpm] 31 | # [tools.yarn] 32 | ``` 33 | 34 | > To execute the shared globals, you'll need to add `~/.proto/tools/node/globals/bin` to `PATH` in your shell. 35 | 36 | ## Hooks 37 | 38 | ### Pre-run 39 | 40 | Before a npm/pnpm/yarn command is ran and `shared-globals-dir` is enabled, this hook will modify the arguments or environment variables of the command when installing/removing/etc a global package. Is a no-op for other commands. 41 | 42 | npm and yarn will set the `PREFIX` environment variable, while pnpm will set `--global-dir` and `--global-bin-dir` arguments. 43 | 44 | ## Contributing 45 | 46 | Build the plugins: 47 | 48 | ```shell 49 | cargo build --target wasm32-wasip1 50 | ``` 51 | 52 | Test the plugins by running `proto` commands. 53 | 54 | ```shell 55 | proto install npm-test 56 | proto versions npm-test 57 | ``` 58 | -------------------------------------------------------------------------------- /tools/node-depman/src/config.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, schematic::Schematic, serde::Deserialize, serde::Serialize)] 2 | #[serde(default, deny_unknown_fields, rename_all = "kebab-case")] 3 | pub struct NodeDepmanPluginConfig { 4 | pub dist_url: String, 5 | pub shared_globals_dir: bool, 6 | } 7 | 8 | impl Default for NodeDepmanPluginConfig { 9 | fn default() -> Self { 10 | Self { 11 | dist_url: 12 | "https://registry.npmjs.org/{package}/-/{package_without_scope}-{version}.tgz" 13 | .into(), 14 | shared_globals_dir: false, 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tools/node-depman/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod config; 2 | #[cfg(feature = "wasm")] 3 | mod npm_registry; 4 | #[cfg(feature = "wasm")] 5 | mod package_manager; 6 | #[cfg(feature = "wasm")] 7 | mod proto; 8 | 9 | pub use config::*; 10 | #[cfg(feature = "wasm")] 11 | pub use proto::*; 12 | -------------------------------------------------------------------------------- /tools/node-depman/src/npm_registry.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use extism_pdk::{Error, json}; 4 | use serde::Deserialize; 5 | use std::collections::HashMap; 6 | 7 | #[derive(Deserialize)] 8 | pub struct RegistryVersion { 9 | pub version: String, // No v prefix 10 | } 11 | 12 | #[derive(Deserialize)] 13 | pub struct RegistryResponse { 14 | pub name: String, 15 | #[serde(rename = "dist-tags")] 16 | pub dist_tags: HashMap, 17 | pub versions: HashMap, 18 | } 19 | 20 | pub fn parse_registry_response(res_text: String, is_yarn: bool) -> Result { 21 | if !is_yarn { 22 | return Ok(json::from_str(&res_text)?); 23 | } 24 | 25 | // https://github.com/moonrepo/proto/issues/257 26 | let pattern = regex::bytes::Regex::new("[\u{0000}-\u{001F}]+").unwrap(); 27 | let body = res_text.as_bytes(); 28 | 29 | Ok(json::from_slice(&pattern.replace_all(body, b""))?) 30 | } 31 | -------------------------------------------------------------------------------- /tools/node-depman/src/package_manager.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use extism_pdk::Error; 4 | use proto_pdk::{UnresolvedVersionSpec, get_plugin_id}; 5 | use std::fmt; 6 | 7 | #[derive(PartialEq)] 8 | pub enum PackageManager { 9 | Npm, 10 | Pnpm, 11 | Yarn, 12 | } 13 | 14 | impl PackageManager { 15 | pub fn detect() -> Result { 16 | let id = get_plugin_id()?; 17 | 18 | Ok(if id.to_lowercase().contains("yarn") { 19 | PackageManager::Yarn 20 | } else if id.to_lowercase().contains("pnpm") { 21 | PackageManager::Pnpm 22 | } else { 23 | PackageManager::Npm 24 | }) 25 | } 26 | 27 | pub fn get_package_name(&self, version: impl AsRef) -> String { 28 | let version = version.as_ref(); 29 | 30 | if matches!(self, PackageManager::Yarn) { 31 | if let UnresolvedVersionSpec::Semantic(inner) = &version { 32 | // Version 2.4.3 was published to the wrong package. It should 33 | // have been published to `@yarnpkg/cli-dist` but was published 34 | // to `yarn`. So... we need to manually fix it. 35 | // https://www.npmjs.com/package/yarn?activeTab=versions 36 | if inner.major == 2 && inner.minor == 4 && inner.patch == 3 { 37 | return "yarn".into(); 38 | } 39 | } 40 | 41 | if self.is_yarn_berry(version) { 42 | return "@yarnpkg/cli-dist".into(); 43 | } 44 | } 45 | 46 | self.to_string() 47 | } 48 | 49 | pub fn is_yarn_classic(&self, version: impl AsRef) -> bool { 50 | matches!(self, PackageManager::Yarn) 51 | && match version.as_ref() { 52 | UnresolvedVersionSpec::Alias(alias) => alias == "legacy" || alias == "classic", 53 | UnresolvedVersionSpec::Semantic(ver) => ver.major == 1, 54 | UnresolvedVersionSpec::Req(req) => req.comparators.iter().any(|c| c.major == 1), 55 | _ => false, 56 | } 57 | } 58 | 59 | pub fn is_yarn_berry(&self, version: impl AsRef) -> bool { 60 | matches!(self, PackageManager::Yarn) 61 | && match version.as_ref() { 62 | UnresolvedVersionSpec::Alias(alias) => alias == "berry" || alias == "latest", 63 | UnresolvedVersionSpec::Semantic(ver) => ver.major > 1, 64 | UnresolvedVersionSpec::Req(req) => req.comparators.iter().any(|c| c.major > 1), 65 | _ => false, 66 | } 67 | } 68 | } 69 | 70 | impl fmt::Display for PackageManager { 71 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 72 | match self { 73 | PackageManager::Npm => write!(f, "npm"), 74 | PackageManager::Pnpm => write!(f, "pnpm"), 75 | PackageManager::Yarn => write!(f, "yarn"), 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tools/node-depman/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | fn create_metadata(id: &str) -> RegisterToolInput { 4 | RegisterToolInput { id: id.into() } 5 | } 6 | 7 | mod node_depman_tool { 8 | use super::*; 9 | 10 | mod npm { 11 | use super::*; 12 | 13 | #[tokio::test(flavor = "multi_thread")] 14 | async fn registers_metadata() { 15 | let sandbox = create_empty_proto_sandbox(); 16 | let plugin = sandbox.create_plugin("npm-test").await; 17 | 18 | let metadata = plugin.register_tool(create_metadata("npm-test")).await; 19 | 20 | assert_eq!(metadata.name, "npm"); 21 | assert_eq!(metadata.type_of, PluginType::DependencyManager); 22 | assert_eq!( 23 | metadata.plugin_version.unwrap().to_string(), 24 | env!("CARGO_PKG_VERSION") 25 | ); 26 | } 27 | } 28 | 29 | mod pnpm { 30 | use super::*; 31 | 32 | #[tokio::test(flavor = "multi_thread")] 33 | async fn registers_metadata() { 34 | let sandbox = create_empty_proto_sandbox(); 35 | let plugin = sandbox.create_plugin("pnpm-test").await; 36 | 37 | let metadata = plugin.register_tool(create_metadata("pnpm-test")).await; 38 | 39 | assert_eq!(metadata.name, "pnpm"); 40 | assert_eq!(metadata.type_of, PluginType::DependencyManager); 41 | assert_eq!( 42 | metadata.plugin_version.unwrap().to_string(), 43 | env!("CARGO_PKG_VERSION") 44 | ); 45 | } 46 | } 47 | 48 | mod yarn { 49 | use super::*; 50 | 51 | #[tokio::test(flavor = "multi_thread")] 52 | async fn registers_metadata() { 53 | let sandbox = create_empty_proto_sandbox(); 54 | let plugin = sandbox.create_plugin("yarn-test").await; 55 | 56 | let metadata = plugin.register_tool(create_metadata("yarn-test")).await; 57 | 58 | assert_eq!(metadata.name, "yarn"); 59 | assert_eq!(metadata.type_of, PluginType::DependencyManager); 60 | assert_eq!( 61 | metadata.plugin_version.unwrap().to_string(), 62 | env!("CARGO_PKG_VERSION") 63 | ); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tools/node-depman/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(windows))] 2 | mod node_depman_tool { 3 | use proto_pdk_test_utils::*; 4 | 5 | mod npm { 6 | use super::*; 7 | 8 | generate_shims_test!("npm-test", ["npm", "npx", "node-gyp"]); 9 | } 10 | 11 | mod pnpm { 12 | use super::*; 13 | 14 | generate_shims_test!("pnpm-test", ["pnpm", "pnpx"]); 15 | } 16 | 17 | mod yarn { 18 | use super::*; 19 | 20 | generate_shims_test!("yarn-test", ["yarn", "yarnpkg"]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tools/node-depman/tests/snapshots/shims_test__node_depman_tool__npm__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/node-depman/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "node-gyp": { 7 | "alt_bin": true, 8 | "parent": "npm-test" 9 | }, 10 | "npm": {}, 11 | "npx": { 12 | "alt_bin": true, 13 | "parent": "npm-test" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tools/node-depman/tests/snapshots/shims_test__node_depman_tool__pnpm__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/node-depman/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "pnpm": {}, 7 | "pnpx": { 8 | "parent": "pnpm-test", 9 | "before_args": [ 10 | "dlx" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tools/node-depman/tests/snapshots/shims_test__node_depman_tool__yarn__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/node-depman/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "yarn": {}, 7 | "yarnpkg": { 8 | "alt_bin": true, 9 | "parent": "yarn-test" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tools/node/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "node_tool" 3 | version = "0.16.4" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "lib"] 15 | 16 | [dependencies] 17 | lang_node_common = { path = "../../crates/lang-node-common" } 18 | extism-pdk = { workspace = true } 19 | nodejs_package_json = { workspace = true } 20 | proto_pdk = { workspace = true } 21 | schematic = { workspace = true } 22 | serde = { workspace = true } 23 | 24 | [dev-dependencies] 25 | proto_pdk_test_utils = { workspace = true } 26 | serial_test = { workspace = true } 27 | starbase_sandbox = { workspace = true } 28 | tokio = { workspace = true } 29 | 30 | [features] 31 | default = ["wasm"] 32 | wasm = [] 33 | -------------------------------------------------------------------------------- /tools/node/README.md: -------------------------------------------------------------------------------- 1 | # Node.js plugin 2 | 3 | Node.js WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | ```shell 8 | proto install node 9 | ``` 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | node = "https://github.com/moonrepo/plugins/releases/download/node_tool-vX.Y.Z/node_tool.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | All plugins can be configured with a `.prototools` file. 21 | 22 | - `bundled-npm` (bool) - When `node` is installed, also install `npm` with the version of npm that came bundled with Node.js. Defaults to `false`. 23 | - `dist-url` (string) - The distribution URL to download Node.js archives from. Supports `{version}` and `{file}` tokens. 24 | 25 | ```toml 26 | [tools.node] 27 | bundled-npm = true 28 | dist-url = "https://..." 29 | ``` 30 | 31 | ## Hooks 32 | 33 | ### Post-install 34 | 35 | After Node.js is installed and `bundled-npm` is enabled, the version of npm that came bundled with Node.js will also be installed. This functionality can also be skipped by passing `--no-bundled-npm` during installation. 36 | 37 | ```shell 38 | proto install node -- --no-bundled-npm 39 | ``` 40 | 41 | ## Contributing 42 | 43 | Build the plugins: 44 | 45 | ```shell 46 | cargo build --target wasm32-wasip1 47 | ``` 48 | 49 | Test the plugins by running `proto` commands. 50 | 51 | ```shell 52 | proto install node-test 53 | proto versions node-test 54 | ``` 55 | -------------------------------------------------------------------------------- /tools/node/src/config.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, schematic::Schematic, serde::Deserialize, serde::Serialize)] 2 | #[serde(default, deny_unknown_fields, rename_all = "kebab-case")] 3 | pub struct NodePluginConfig { 4 | pub bundled_npm: bool, 5 | pub dist_url: String, 6 | } 7 | 8 | impl Default for NodePluginConfig { 9 | fn default() -> Self { 10 | Self { 11 | bundled_npm: false, 12 | dist_url: "https://nodejs.org/download/release/v{version}/{file}".into(), 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tools/node/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod config; 2 | #[cfg(feature = "wasm")] 3 | mod proto; 4 | 5 | pub use config::*; 6 | #[cfg(feature = "wasm")] 7 | pub use proto::*; 8 | -------------------------------------------------------------------------------- /tools/node/tests/build_test.rs: -------------------------------------------------------------------------------- 1 | // use proto_pdk_test_utils::*; 2 | 3 | // mod node_tool { 4 | // use super::*; 5 | 6 | // generate_build_install_tests!("node-test", "22.0.0"); 7 | // } 8 | -------------------------------------------------------------------------------- /tools/node/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod node_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn registers_metadata() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let plugin = sandbox.create_plugin("node-test").await; 10 | 11 | let metadata = plugin.register_tool(RegisterToolInput::default()).await; 12 | 13 | assert_eq!(metadata.name, "Node.js"); 14 | assert_eq!( 15 | metadata.plugin_version.unwrap().to_string(), 16 | env!("CARGO_PKG_VERSION") 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tools/node/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(windows))] 2 | use proto_pdk_test_utils::*; 3 | 4 | #[cfg(not(windows))] 5 | mod node_tool { 6 | use super::*; 7 | 8 | generate_shims_test!("node-test", ["node"]); 9 | } 10 | -------------------------------------------------------------------------------- /tools/node/tests/snapshots/shims_test__node_tool__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/node/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "node": {} 7 | } 8 | -------------------------------------------------------------------------------- /tools/proto/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.5.4 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.5.3 10 | 11 | #### 🐞 Fixes 12 | 13 | - Reverted shims support. 14 | 15 | ## 0.5.2 16 | 17 | #### 🚀 Updates 18 | 19 | - Updated to support proto v0.47 release. 20 | 21 | ## 0.5.1 22 | 23 | #### 🚀 Updates 24 | 25 | - Enabled shims support. 26 | 27 | ## 0.5.0 28 | 29 | #### 🚀 Updates 30 | 31 | - Updated to support proto v0.46 release. 32 | 33 | ## 0.4.0 34 | 35 | #### 🚀 Updates 36 | 37 | - Added build from source support. 38 | 39 | ## 0.3.1 40 | 41 | #### 🚀 Updates 42 | 43 | - Updated dependencies. 44 | 45 | ## 0.3.0 46 | 47 | #### 🚀 Updates 48 | 49 | - Updated to support proto v0.42 release. 50 | 51 | ## 0.2.0 52 | 53 | #### 🚀 Updates 54 | 55 | - Updated to support proto v0.40 release. 56 | 57 | ## 0.1.1 58 | 59 | #### 🐞 Fixes 60 | 61 | - Filter out `version_spec` tags from versions list. 62 | - Don't link bins/shims as it collides with the default install. 63 | 64 | ## 0.1.0 65 | 66 | #### 🎉 Release 67 | 68 | - Initial release! 69 | -------------------------------------------------------------------------------- /tools/proto/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "proto_tool" 3 | version = "0.5.4" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | serde = { workspace = true } 20 | 21 | [features] 22 | default = ["wasm"] 23 | wasm = [] 24 | -------------------------------------------------------------------------------- /tools/proto/README.md: -------------------------------------------------------------------------------- 1 | # proto plugin 2 | 3 | An internal-only plugin for managing proto. This should not be used directly. 4 | -------------------------------------------------------------------------------- /tools/proto/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod proto; 3 | 4 | #[cfg(feature = "wasm")] 5 | pub use proto::*; 6 | -------------------------------------------------------------------------------- /tools/python-poetry/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.1.3 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.1.2 10 | 11 | #### 🚀 Updates 12 | 13 | - Updated to support proto v0.47 release. 14 | 15 | ## 0.1.1 16 | 17 | #### 🐞 Fixes 18 | 19 | - Fixed an install error on Linux. 20 | 21 | ## 0.1.0 22 | 23 | #### 🎉 Release 24 | 25 | - Initial release! 26 | -------------------------------------------------------------------------------- /tools/python-poetry/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "python_poetry_tool" 3 | version = "0.1.3" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | serde = { workspace = true } 20 | 21 | [dev-dependencies] 22 | proto_pdk_test_utils = { workspace = true } 23 | starbase_sandbox = { workspace = true } 24 | tokio = { workspace = true } 25 | 26 | [features] 27 | default = ["wasm"] 28 | wasm = [] 29 | -------------------------------------------------------------------------------- /tools/python-poetry/README.md: -------------------------------------------------------------------------------- 1 | # Python Poetry plugin 2 | 3 | Poetry WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | ```shell 8 | proto install poetry 9 | ``` 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | poetry = "https://github.com/moonrepo/plugins/releases/download/python_poetry_tool-vX.Y.Z/python_poetry_tool.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | Poetry plugin does not support configuration. 21 | 22 | ## Hooks 23 | 24 | Poetry plugin does not support hooks. 25 | 26 | ## Contributing 27 | 28 | Build the plugins: 29 | 30 | ```shell 31 | cargo build --target wasm32-wasip1 32 | ``` 33 | 34 | Test the plugins by running `proto` commands. 35 | 36 | ```shell 37 | proto install poetry-test 38 | proto versions poetry-test 39 | ``` 40 | -------------------------------------------------------------------------------- /tools/python-poetry/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod proto; 3 | 4 | #[cfg(feature = "wasm")] 5 | pub use proto::*; 6 | -------------------------------------------------------------------------------- /tools/python-poetry/tests/download_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_poetry_tool { 4 | use super::*; 5 | 6 | generate_native_install_tests!("poetry-test", "2.1.0"); 7 | 8 | #[tokio::test(flavor = "multi_thread")] 9 | async fn locates_unix_bin() { 10 | let sandbox = create_empty_proto_sandbox(); 11 | let plugin = sandbox 12 | .create_plugin_with_config("poetry-test", |config| { 13 | config.host(HostOS::Linux, HostArch::Arm64); 14 | }) 15 | .await; 16 | 17 | assert_eq!( 18 | plugin 19 | .locate_executables(LocateExecutablesInput { 20 | context: ToolContext { 21 | version: VersionSpec::parse("1.2.0").unwrap(), 22 | ..Default::default() 23 | }, 24 | ..Default::default() 25 | }) 26 | .await 27 | .exes 28 | .get("poetry") 29 | .unwrap() 30 | .exe_path, 31 | Some("bin/poetry".into()) 32 | ); 33 | } 34 | 35 | #[tokio::test(flavor = "multi_thread")] 36 | async fn locates_windows_bin() { 37 | let sandbox = create_empty_proto_sandbox(); 38 | let plugin = sandbox 39 | .create_plugin_with_config("poetry-test", |config| { 40 | config.host(HostOS::Windows, HostArch::X64); 41 | }) 42 | .await; 43 | 44 | assert_eq!( 45 | plugin 46 | .locate_executables(LocateExecutablesInput { 47 | context: ToolContext { 48 | version: VersionSpec::parse("1.2.0").unwrap(), 49 | ..Default::default() 50 | }, 51 | ..Default::default() 52 | }) 53 | .await 54 | .exes 55 | .get("poetry") 56 | .unwrap() 57 | .exe_path, 58 | Some("bin/poetry.exe".into()) 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tools/python-poetry/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_poetry_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn registers_metadata() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let plugin = sandbox.create_plugin("poetry-test").await; 10 | 11 | let metadata = plugin.register_tool(RegisterToolInput::default()).await; 12 | 13 | assert_eq!(metadata.name, "Poetry"); 14 | assert_eq!(metadata.self_upgrade_commands, vec!["self update"]); 15 | assert_eq!( 16 | metadata.plugin_version.unwrap().to_string(), 17 | env!("CARGO_PKG_VERSION") 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tools/python-poetry/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(unix)] 2 | mod python_poetry_tool { 3 | use proto_pdk_test_utils::*; 4 | 5 | generate_shims_test!("poetry-test", ["poetry"]); 6 | } 7 | -------------------------------------------------------------------------------- /tools/python-poetry/tests/snapshots/shims_test__python_poetry_tool__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/python-poetry/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "poetry": {} 7 | } 8 | -------------------------------------------------------------------------------- /tools/python-poetry/tests/versions_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_poetry_tool { 4 | use super::*; 5 | 6 | generate_resolve_versions_tests!("poetry-test", { 7 | "1.8" => "1.8.5", 8 | "2.1.1" => "2.1.1", 9 | }); 10 | 11 | #[tokio::test(flavor = "multi_thread")] 12 | async fn loads_versions_from_git() { 13 | let sandbox = create_empty_proto_sandbox(); 14 | let plugin = sandbox.create_plugin("poetry-test").await; 15 | 16 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 17 | 18 | assert!(!output.versions.is_empty()); 19 | } 20 | 21 | #[tokio::test(flavor = "multi_thread")] 22 | async fn sets_latest_alias() { 23 | let sandbox = create_empty_proto_sandbox(); 24 | let plugin = sandbox.create_plugin("poetry-test").await; 25 | 26 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 27 | 28 | assert!(output.latest.is_some()); 29 | assert!(output.aliases.contains_key("latest")); 30 | assert_eq!(output.aliases.get("latest"), output.latest.as_ref()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tools/python-uv/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.2.2 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.2.1 10 | 11 | #### 🚀 Updates 12 | 13 | - Updated to support proto v0.47 release. 14 | 15 | ## 0.2.0 16 | 17 | #### 🚀 Updates 18 | 19 | - Updated to support proto v0.46 release. 20 | 21 | ## 0.1.0 22 | 23 | #### 🎉 Release 24 | 25 | - Initial release! 26 | -------------------------------------------------------------------------------- /tools/python-uv/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "python_uv_tool" 3 | version = "0.2.2" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | serde = { workspace = true } 20 | 21 | [dev-dependencies] 22 | proto_pdk_test_utils = { workspace = true } 23 | starbase_sandbox = { workspace = true } 24 | tokio = { workspace = true } 25 | 26 | [features] 27 | default = ["wasm"] 28 | wasm = [] 29 | -------------------------------------------------------------------------------- /tools/python-uv/README.md: -------------------------------------------------------------------------------- 1 | # Python uv plugin 2 | 3 | uv WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | ```shell 8 | proto install uv 9 | ``` 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | uv = "https://github.com/moonrepo/plugins/releases/download/python_uv_tool-vX.Y.Z/python_uv_tool.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | uv plugin does not support configuration. 21 | 22 | ## Hooks 23 | 24 | uv plugin does not support hooks. 25 | 26 | ## Contributing 27 | 28 | Build the plugins: 29 | 30 | ```shell 31 | cargo build --target wasm32-wasip1 32 | ``` 33 | 34 | Test the plugins by running `proto` commands. 35 | 36 | ```shell 37 | proto install uv-test 38 | proto versions uv-test 39 | ``` 40 | -------------------------------------------------------------------------------- /tools/python-uv/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod proto; 3 | 4 | #[cfg(feature = "wasm")] 5 | pub use proto::*; 6 | -------------------------------------------------------------------------------- /tools/python-uv/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_uv_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn registers_metadata() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let plugin = sandbox.create_plugin("uv-test").await; 10 | 11 | let metadata = plugin.register_tool(RegisterToolInput::default()).await; 12 | 13 | assert_eq!(metadata.name, "uv"); 14 | assert_eq!(metadata.self_upgrade_commands, vec!["self upgrade"]); 15 | assert_eq!( 16 | metadata.plugin_version.unwrap().to_string(), 17 | env!("CARGO_PKG_VERSION") 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tools/python-uv/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_uv_tool { 4 | use super::*; 5 | 6 | #[cfg(not(windows))] 7 | generate_shims_test!("uv-test", ["uv", "uvx"]); 8 | } 9 | -------------------------------------------------------------------------------- /tools/python-uv/tests/snapshots/shims_test__python_uv_tool__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/python-uv/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "uv": {}, 7 | "uvx": { 8 | "alt_bin": true, 9 | "parent": "uv-test" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tools/python-uv/tests/versions_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_uv_tool { 4 | use super::*; 5 | 6 | generate_resolve_versions_tests!("uv-test", { 7 | "0.3" => "0.3.5", 8 | "0.5.21" => "0.5.21", 9 | }); 10 | 11 | #[tokio::test(flavor = "multi_thread")] 12 | async fn loads_versions_from_git() { 13 | let sandbox = create_empty_proto_sandbox(); 14 | let plugin = sandbox.create_plugin("uv-test").await; 15 | 16 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 17 | 18 | assert!(!output.versions.is_empty()); 19 | } 20 | 21 | #[tokio::test(flavor = "multi_thread")] 22 | async fn sets_latest_alias() { 23 | let sandbox = create_empty_proto_sandbox(); 24 | let plugin = sandbox.create_plugin("uv-test").await; 25 | 26 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 27 | 28 | assert!(output.latest.is_some()); 29 | assert!(output.aliases.contains_key("latest")); 30 | assert_eq!(output.aliases.get("latest"), output.latest.as_ref()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tools/python/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "python_tool" 3 | version = "0.14.2" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | regex = { workspace = true } 20 | serde = { workspace = true } 21 | 22 | [dev-dependencies] 23 | proto_pdk_test_utils = { workspace = true } 24 | starbase_sandbox = { workspace = true } 25 | tokio = { workspace = true } 26 | 27 | [features] 28 | default = ["wasm"] 29 | wasm = [] 30 | -------------------------------------------------------------------------------- /tools/python/README.md: -------------------------------------------------------------------------------- 1 | # Python plugin 2 | 3 | [Python](https://www.python.org/) WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | ```shell 8 | proto install python 9 | ``` 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | python = "https://github.com/moonrepo/plugins/releases/download/python_tool-vX.Y.Z/python_tool.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | Python plugin does not support configuration. 21 | 22 | ## Hooks 23 | 24 | Python plugin does not support hooks. 25 | 26 | ## Caveats 27 | 28 | This will install a pre-built version from [astral-sh/python-build-standalone](https://github.com/astral-sh/python-build-standalone), which doesn't support all versions, only Python 3. 29 | 30 | ## Contributing 31 | 32 | Build the plugin: 33 | 34 | ```shell 35 | cargo build --target wasm32-wasip1 36 | ``` 37 | 38 | Test the plugin by running `proto` commands. 39 | 40 | ```shell 41 | proto install python-test 42 | proto versions python-test 43 | ``` 44 | -------------------------------------------------------------------------------- /tools/python/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod proto; 3 | mod version; 4 | 5 | #[cfg(feature = "wasm")] 6 | pub use proto::*; 7 | -------------------------------------------------------------------------------- /tools/python/src/version.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use regex::Regex; 4 | 5 | pub fn from_python_version(version: String, regex: &Regex) -> Option { 6 | let caps = regex.captures(&version)?; 7 | 8 | let mut version = format!( 9 | "{}.{}.{}", 10 | &caps["major"], 11 | &caps["minor"], 12 | caps.name("patch").map(|c| c.as_str()).unwrap_or("0"), 13 | ); 14 | 15 | if let Some(pre) = caps.name("pre") { 16 | let preid = format!("-{}.{}", pre.as_str(), &caps["preid"]); 17 | version.push_str(&preid); 18 | } 19 | 20 | Some(version) 21 | } 22 | -------------------------------------------------------------------------------- /tools/python/tests/build_test.rs: -------------------------------------------------------------------------------- 1 | #[cfg(unix)] 2 | mod python_tool { 3 | use proto_pdk_test_utils::*; 4 | 5 | generate_build_install_tests!("python-test", "3.12.0"); 6 | } 7 | -------------------------------------------------------------------------------- /tools/python/tests/download_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_tool { 4 | use super::*; 5 | 6 | generate_download_install_tests!("python-test", "3.10.0"); 7 | } 8 | -------------------------------------------------------------------------------- /tools/python/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn registers_metadata() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let plugin = sandbox.create_plugin("python-test").await; 10 | 11 | let metadata = plugin.register_tool(RegisterToolInput::default()).await; 12 | 13 | assert_eq!(metadata.name, "Python"); 14 | assert_eq!( 15 | metadata.plugin_version.unwrap().to_string(), 16 | env!("CARGO_PKG_VERSION") 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tools/python/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_tool { 4 | use super::*; 5 | 6 | #[cfg(not(windows))] 7 | generate_shims_test!("python-test", ["python", "pip"]); 8 | } 9 | -------------------------------------------------------------------------------- /tools/python/tests/snapshots/shims_test__python_tool__creates_shims.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tools/python/tests/shims_test.rs 3 | expression: "std :: fs ::\nread_to_string(sandbox.path().join(\".proto/shims/registry.json\")).unwrap()" 4 | --- 5 | { 6 | "pip": { 7 | "parent": "python-test", 8 | "before_args": [ 9 | "-m", 10 | "pip" 11 | ] 12 | }, 13 | "python": {} 14 | } 15 | -------------------------------------------------------------------------------- /tools/python/tests/versions_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod python_tool { 4 | use super::*; 5 | 6 | generate_resolve_versions_tests!("python-test", { 7 | "2.3" => "2.3.7", 8 | "3.10.1" => "3.10.1", 9 | "3.10" => "3.10.17", 10 | // "3" => "3.12.4", 11 | }); 12 | 13 | #[tokio::test(flavor = "multi_thread")] 14 | async fn loads_versions_from_git() { 15 | let sandbox = create_empty_proto_sandbox(); 16 | let plugin = sandbox.create_plugin("python-test").await; 17 | 18 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 19 | 20 | assert!(!output.versions.is_empty()); 21 | } 22 | 23 | #[tokio::test(flavor = "multi_thread")] 24 | async fn sets_latest_alias() { 25 | let sandbox = create_empty_proto_sandbox(); 26 | let plugin = sandbox.create_plugin("python-test").await; 27 | 28 | let output = plugin.load_versions(LoadVersionsInput::default()).await; 29 | 30 | assert!(output.latest.is_some()); 31 | assert!(output.aliases.contains_key("latest")); 32 | assert_eq!(output.aliases.get("latest"), output.latest.as_ref()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tools/ruby/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.2.2 4 | 5 | #### ⚙️ Internal 6 | 7 | - Updated dependencies. 8 | 9 | ## 0.2.1 10 | 11 | #### 🚀 Updates 12 | 13 | - Updated to support proto v0.47 release. 14 | 15 | ## 0.2.0 16 | 17 | #### 🚀 Updates 18 | 19 | - Updated to support proto v0.46 release. 20 | 21 | ## 0.1.0 22 | 23 | #### 🎉 Release 24 | 25 | - Initial release! 26 | -------------------------------------------------------------------------------- /tools/ruby/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ruby_tool" 3 | version = "0.2.2" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | serde = { workspace = true } 20 | 21 | [dev-dependencies] 22 | proto_pdk_test_utils = { workspace = true } 23 | starbase_sandbox = { workspace = true } 24 | tokio = { workspace = true } 25 | 26 | [features] 27 | default = ["wasm"] 28 | wasm = [] 29 | -------------------------------------------------------------------------------- /tools/ruby/README.md: -------------------------------------------------------------------------------- 1 | # Ruby plugin 2 | 3 | Ruby WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | ```shell 8 | proto install ruby 9 | ``` 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | ruby = "https://github.com/moonrepo/plugins/releases/download/ruby_tool-vX.Y.Z/ruby_tool.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | Ruby plugin does not support configuration. 21 | 22 | ## Hooks 23 | 24 | Ruby plugin does not support hooks. 25 | 26 | ## Contributing 27 | 28 | Build the plugins: 29 | 30 | ```shell 31 | cargo build --target wasm32-wasip1 32 | ``` 33 | 34 | Test the plugins by running `proto` commands. 35 | 36 | ```shell 37 | proto install ruby-test 38 | proto versions ruby-test 39 | ``` 40 | -------------------------------------------------------------------------------- /tools/ruby/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod proto; 3 | 4 | #[cfg(feature = "wasm")] 5 | pub use proto::*; 6 | -------------------------------------------------------------------------------- /tools/ruby/tests/build_test.rs: -------------------------------------------------------------------------------- 1 | // NOTE: Doesn't work in GitHub CI. 2 | // 3 | // #[cfg(unix)] 4 | // mod ruby_tool { 5 | // use proto_pdk_test_utils::*; 6 | 7 | // generate_build_install_tests!("ruby-test", "3.4.0"); 8 | // } 9 | -------------------------------------------------------------------------------- /tools/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_tool" 3 | version = "0.13.4" 4 | edition = "2024" 5 | license = "MIT" 6 | publish = false 7 | 8 | [package.metadata.release] 9 | pre-release-replacements = [ 10 | { file = "./CHANGELOG.md", search = "Unreleased", replace = "{{version}}" }, 11 | ] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "lib"] 15 | 16 | [dependencies] 17 | extism-pdk = { workspace = true } 18 | proto_pdk = { workspace = true } 19 | serde = { workspace = true } 20 | toml = { workspace = true } 21 | 22 | [dev-dependencies] 23 | proto_pdk_test_utils = { workspace = true } 24 | starbase_sandbox = { workspace = true } 25 | tokio = { workspace = true } 26 | 27 | [features] 28 | default = ["wasm"] 29 | wasm = [] 30 | -------------------------------------------------------------------------------- /tools/rust/README.md: -------------------------------------------------------------------------------- 1 | # Rust plugin 2 | 3 | [Rust](https://www.rust-lang.org/) WASM plugin for [proto](https://github.com/moonrepo/proto). 4 | 5 | ## Installation 6 | 7 | ```shell 8 | proto install rust 9 | ``` 10 | 11 | This plugin is built-in to proto, but if you want to override it with an explicit version, add the following to `.prototools`. 12 | 13 | ```toml 14 | [plugins] 15 | rust = "https://github.com/moonrepo/plugins/releases/download/rust_tool-vX.Y.Z/rust_tool.wasm" 16 | ``` 17 | 18 | ## Configuration 19 | 20 | Rust plugin does not support configuration. 21 | 22 | ## Hooks 23 | 24 | Rust plugin does not support hooks. 25 | 26 | ## Caveats 27 | 28 | If you're familiar with Rust, you most likely use [rustup](https://rustup.rs), a Rust specific toolchain manager. This overlaps heavily with how proto works, so instead of proto reinventing the wheel here, we simply call `rustup` under the hood. Because of this, be aware of the following when using Rust in proto: 29 | 30 | - The `~/.cargo/bin` directory must be in your `PATH`. 31 | - We don't install Rust to `~/.proto/tools/rust` but instead reference `~/.rustup/toolchains`. 32 | - We don't create shims for `cargo`, `rustup`, etc. 33 | 34 | Since we don't create shims for `cargo`, `rustup`, etc, we can't detect Rust versions at runtime. However, `rustup` supports this through the 35 | [`rust-toolchain.toml`](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file) file. We suggest using this file. 36 | 37 | ## Contributing 38 | 39 | Build the plugin: 40 | 41 | ```shell 42 | cargo build --target wasm32-wasip1 43 | ``` 44 | 45 | Test the plugin by running `proto` commands. 46 | 47 | ```shell 48 | proto install rust-test 49 | proto versions rust-test 50 | ``` 51 | -------------------------------------------------------------------------------- /tools/rust/src/helpers.rs: -------------------------------------------------------------------------------- 1 | use extism_pdk::*; 2 | use proto_pdk::*; 3 | 4 | #[host_fn] 5 | extern "ExtismHost" { 6 | fn get_env_var(name: String) -> String; 7 | fn to_virtual_path(input: String) -> String; 8 | } 9 | 10 | fn get_home_env(key: &str) -> Result, Error> { 11 | match get_host_env_var(key)? { 12 | Some(value) => Ok(if value.is_empty() { 13 | None 14 | } else { 15 | into_virtual_path(value).ok() 16 | }), 17 | None => Ok(None), 18 | } 19 | } 20 | 21 | pub fn get_cargo_home(env: &HostEnvironment) -> Result { 22 | Ok(get_home_env("CARGO_HOME")?.unwrap_or_else(|| env.home_dir.join(".cargo"))) 23 | } 24 | 25 | pub fn get_rustup_home(env: &HostEnvironment) -> Result { 26 | // Cargo sets the RUSTUP_HOME env var when running tests, 27 | // which causes a ton of issues, so intercept it here! 28 | if let Some(test_env) = get_test_environment()? { 29 | return Ok(test_env.sandbox.join(".home/.rustup")); 30 | } 31 | 32 | Ok(get_home_env("RUSTUP_HOME")?.unwrap_or_else(|| env.home_dir.join(".rustup"))) 33 | } 34 | 35 | pub fn get_channel_from_version(spec: &VersionSpec) -> String { 36 | if spec.is_canary() { 37 | "nightly".to_owned() 38 | } else { 39 | spec.to_string() 40 | } 41 | } 42 | 43 | pub fn is_non_version_channel(spec: &UnresolvedVersionSpec) -> bool { 44 | match spec { 45 | UnresolvedVersionSpec::Canary => true, 46 | UnresolvedVersionSpec::Alias(value) => { 47 | value == "stable" 48 | || value == "beta" 49 | || value == "nightly" 50 | || value.starts_with("nightly") 51 | } 52 | _ => false, 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tools/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "wasm")] 2 | mod helpers; 3 | #[cfg(feature = "wasm")] 4 | mod proto; 5 | mod toolchain_toml; 6 | 7 | #[cfg(feature = "wasm")] 8 | pub use proto::*; 9 | pub use toolchain_toml::*; 10 | -------------------------------------------------------------------------------- /tools/rust/src/toolchain_toml.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] 4 | #[serde(default)] 5 | pub struct ToolchainSection { 6 | pub channel: Option, 7 | } 8 | 9 | #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] 10 | #[serde(default)] 11 | pub struct ToolchainToml { 12 | pub toolchain: ToolchainSection, 13 | } 14 | -------------------------------------------------------------------------------- /tools/rust/tests/download_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | // We use a fake home directory but rustup requires a real one! 4 | // generate_download_install_tests!("rust-test", "1.70.0"); 5 | 6 | mod rust_tool { 7 | use super::*; 8 | 9 | #[tokio::test(flavor = "multi_thread")] 10 | async fn locates_linux_bin() { 11 | let sandbox = create_empty_proto_sandbox(); 12 | let plugin = sandbox 13 | .create_plugin_with_config("rust-test", |config| { 14 | config.host(HostOS::Linux, HostArch::Arm64); 15 | }) 16 | .await; 17 | 18 | assert_eq!( 19 | plugin 20 | .locate_executables(LocateExecutablesInput { 21 | context: ToolContext { 22 | version: VersionSpec::parse("1.69.0").unwrap(), 23 | ..Default::default() 24 | }, 25 | ..Default::default() 26 | }) 27 | .await 28 | .exes 29 | .get("cargo") 30 | .unwrap() 31 | .exe_path, 32 | Some("bin/cargo".into()) 33 | ); 34 | } 35 | 36 | #[tokio::test(flavor = "multi_thread")] 37 | async fn locates_macos_bin() { 38 | let sandbox = create_empty_proto_sandbox(); 39 | let plugin = sandbox 40 | .create_plugin_with_config("rust-test", |config| { 41 | config.host(HostOS::MacOS, HostArch::X64); 42 | }) 43 | .await; 44 | 45 | assert_eq!( 46 | plugin 47 | .locate_executables(LocateExecutablesInput { 48 | context: ToolContext { 49 | version: VersionSpec::parse("1.69.0").unwrap(), 50 | ..Default::default() 51 | }, 52 | ..Default::default() 53 | }) 54 | .await 55 | .exes 56 | .get("cargo") 57 | .unwrap() 58 | .exe_path, 59 | Some("bin/cargo".into()) 60 | ); 61 | } 62 | 63 | #[tokio::test(flavor = "multi_thread")] 64 | async fn locates_windows_bin() { 65 | let sandbox = create_empty_proto_sandbox(); 66 | let plugin = sandbox 67 | .create_plugin_with_config("rust-test", |config| { 68 | config.host(HostOS::Windows, HostArch::X86); 69 | }) 70 | .await; 71 | 72 | assert_eq!( 73 | plugin 74 | .locate_executables(LocateExecutablesInput { 75 | context: ToolContext { 76 | version: VersionSpec::parse("1.69.0").unwrap(), 77 | ..Default::default() 78 | }, 79 | ..Default::default() 80 | }) 81 | .await 82 | .exes 83 | .get("cargo") 84 | .unwrap() 85 | .exe_path, 86 | Some("bin/cargo.exe".into()) 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tools/rust/tests/metadata_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod rust_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn registers_metadata() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let plugin = sandbox.create_plugin("rust-test").await; 10 | 11 | let metadata = plugin 12 | .register_tool(RegisterToolInput { 13 | id: "rust-test".into(), 14 | }) 15 | .await; 16 | 17 | assert_eq!(metadata.name, "Rust"); 18 | assert_eq!( 19 | metadata.default_version, 20 | Some(UnresolvedVersionSpec::parse("stable").unwrap()) 21 | ); 22 | assert!(metadata.inventory.override_dir.is_some()); 23 | assert!(metadata.inventory.version_suffix.is_some()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tools/rust/tests/shims_test.rs: -------------------------------------------------------------------------------- 1 | use proto_pdk_test_utils::*; 2 | 3 | mod rust_tool { 4 | use super::*; 5 | 6 | #[tokio::test(flavor = "multi_thread")] 7 | async fn doesnt_create_global_shims() { 8 | let sandbox = create_empty_proto_sandbox(); 9 | let mut plugin = sandbox.create_plugin("rust-test").await; 10 | 11 | plugin.tool.generate_shims(false).await.unwrap(); 12 | 13 | assert!(!sandbox.path().join(".proto/bin/rustc").exists()); 14 | assert!(!sandbox.path().join(".proto/bin/cargo").exists()); 15 | assert!(!sandbox.path().join(".proto/shims/rustc").exists()); 16 | assert!(!sandbox.path().join(".proto/shims/cargo").exists()); 17 | } 18 | } 19 | --------------------------------------------------------------------------------