diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f2b507d..5abc352 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,8 +11,11 @@ name: Release # A tag is the release, and THE TAG IS THE VERSION. Every package file in the # tree carries the placeholder `0.0.0`; each job checks out the tagged commit # and stamps what the tag names into its own throwaway checkout before it builds -# [release.version]. Nothing commits, nothing pushes, and no job checks out a -# branch. The stamped tree is a pure function of (tagged commit, tag), so +# [release.version]. Nothing pushes and no job checks out a branch; the pub.dev +# job alone commits, into its own throwaway checkout and only because pub +# refuses to validate an archive with uncommitted changes beside it. The +# repository is never written to. The stamped tree is a pure function of +# (tagged commit, tag), so # `make version VERSION=1.2.3` on the tagged commit reproduces what shipped — # nobody bumps a number before tagging, and no tag is ever refused for a file # somebody forgot. @@ -50,10 +53,40 @@ jobs: name: Preflight runs-on: ubuntu-22.04 timeout-minutes: 10 + # The publishing credentials are scoped to this environment, and an + # environment's secrets are readable ONLY by a job that declares it — so the + # check below is meaningless anywhere else. It reported both as absent while + # they were set correctly, which is the one way a guard can be worse than no + # guard: refusing the release it was added to protect. + environment: release outputs: version: ${{ steps.version.outputs.version }} publishing: ${{ github.event_name == 'push' }} steps: + # FIRST, before a checkout even. `publish` and `publish-pub` are held to + # the same gates but run in PARALLEL, so a Marketplace credential that + # turns out to be missing at publish time is discovered with pub.dev + # already published — and a pub version cannot be withdrawn, only + # retracted. The credentials are therefore proven to EXIST here, where the + # whole cost of being wrong is a red tag. Presence only: a value is never + # printed, compared, or logged. + - name: The publishing credentials exist + if: github.event_name == 'push' + env: + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + run: | + set -euo pipefail + missing="" + [ -n "${AZURE_CLIENT_ID:-}" ] || missing="${missing} AZURE_CLIENT_ID" + [ -n "${AZURE_TENANT_ID:-}" ] || missing="${missing} AZURE_TENANT_ID" + if [ -n "${missing}" ]; then + echo "::error::Release refused: no value for${missing}. The Marketplace publish exchanges GitHub OIDC for an Entra session and cannot run without them, and pub.dev publishes alongside it — so releasing now would burn a pub.dev version with no extension beside it [release.authentication]." + exit 1 + fi + echo "AZURE_CLIENT_ID: present" + echo "AZURE_TENANT_ID: present" + - uses: actions/checkout@v4 with: # The tagged commit, never a branch — `github.sha` on a tag push IS @@ -112,8 +145,16 @@ jobs: name: Verify needs: preflight uses: ./.github/workflows/ci.yml + # A called workflow may not request more than its caller grants, and GitHub + # checks that STATICALLY, before any job runs — an `if` that will never be + # true does not excuse the job from the check. ci.yml's `security` job asks + # for `pull-requests: write` to comment on a PR, so withholding it here does + # not skip that job, it refuses the whole run with `startup_failure` and no + # release starts at all. Granted, therefore, and unused: `security` is + # `if: github.event_name == 'pull_request'`, which a tag push never is. permissions: contents: read + pull-requests: write with: ref: ${{ inputs.ref || github.sha }} @@ -186,10 +227,7 @@ jobs: rust: x86_64-pc-windows-gnu apt: gcc-mingw-w64-x86-64 cc: x86_64-w64-mingw32-gcc - - vsix: darwin-x64 - os: macos-15-intel - rust: x86_64-apple-darwin - native: true + linker: x86_64-w64-mingw32-gcc - vsix: darwin-arm64 os: macos-14 rust: aarch64-apple-darwin @@ -213,14 +251,22 @@ jobs: if: matrix.apt != '' run: sudo apt-get update && sudo apt-get install --yes ${{ matrix.apt }} - - name: Point cargo and cc at it + # The C compiler and the LINKER are set separately because musl wants one + # and not the other. Rust ships its own musl libc and links that target + # self-contained; pointing the linker at Ubuntu's `musl-gcc` instead + # produced an x86_64 static-PIE that segfaulted (exit 139) the instant it + # was executed, so the binary was built, packaged, and dead. tree-sitter is + # still C and still needs CC_. Only a genuine cross-link — mingw — + # names a linker. + - name: Point cc at the cross toolchain if: matrix.cc != '' + run: echo "CC_${{ matrix.rust }}=${{ matrix.cc }}" >> "$GITHUB_ENV" + + - name: Point cargo's linker at it + if: matrix.linker != '' run: | triple=$(echo "${{ matrix.rust }}" | tr 'a-z-' 'A-Z_') - { - echo "CC_${{ matrix.rust }}=${{ matrix.cc }}" - echo "CARGO_TARGET_${triple}_LINKER=${{ matrix.cc }}" - } >> "$GITHUB_ENV" + echo "CARGO_TARGET_${triple}_LINKER=${{ matrix.linker }}" >> "$GITHUB_ENV" # VERSION stamps the bundle and reaches the compiler as DMX_VERSION, so # the manifest, the changelog the marketplace page shows, and the binary's @@ -330,7 +376,7 @@ jobs: # The complete set, named once. A platform missing from here is a platform # that silently stops being published. BUNDLES: >- - dmx-darwin-arm64.vsix dmx-darwin-x64.vsix + dmx-darwin-arm64.vsix dmx-linux-arm64.vsix dmx-linux-x64.vsix dmx-alpine-arm64.vsix dmx-alpine-x64.vsix dmx-win32-x64.vsix dmx-universal.vsix @@ -368,18 +414,15 @@ jobs: set -euo pipefail npm ci --prefix src/editors/vscode - # Azure DevOps' fixed first-party resource is what `vsce` authenticates - # against. Despite the environment variable name required by `vsce`, - # this is a short-lived OIDC-derived access token, not a stored PAT. - marketplace_token="$(az account get-access-token \ - --resource 499b84ac-1321-427f-aa17-267ca6975798 \ - --query accessToken -o tsv)" - echo "::add-mask::${marketplace_token}" - export VSCE_PAT="${marketplace_token}" - + # `--azure-credential` hands vsce the Entra session `azure/login` + # established from this job's OIDC token, and vsce acquires what it + # needs itself. Nothing mints, masks, exports or stores a token: there + # is no VSCE_PAT in this release, and no Marketplace PAT exists to + # expire, leak or rotate [release.authentication]. for bundle in $BUNDLES; do echo "Publishing bundles/$bundle" npx --prefix src/editors/vscode vsce publish \ + --azure-credential \ --skip-duplicate \ --packagePath "bundles/$bundle" done @@ -475,21 +518,6 @@ jobs: working-directory: src/dart_packages/dmx run: dart pub get - # The archive pub would receive, before it receives it. `--dry-run` fails - # on anything that would fail the real publish — a missing licence, a file - # the package cannot carry, an unresolvable constraint. - # - # BEFORE the stamp, deliberately. `--dry-run` exits non-zero on any - # warning, and one of pub's warnings is "you have uncommitted changes" — - # which the stamp is, by design. So the archive's SHAPE is proven here on - # the clean tagged checkout, where that warning cannot fire, and the - # version it carries is proven by the steps below. Nothing about - # publishability depends on which version string is in the file. - - name: Prove the archive is publishable - if: steps.published.outputs.skip != 'true' - working-directory: src/dart_packages/dmx - run: dart pub publish --dry-run - # `lib/src/version.dart` is GENERATED from the pubspec by this package's # own macro worker, so stamping the pubspec means regenerating it — a # package whose `DmxPackage.version` names the previous release is a @@ -518,12 +546,30 @@ jobs: make version VERSION="$VERSION" make dart-package-version VERSION="$VERSION" DMX="$PWD/bundle/dmx" git diff --stat + # Committed into this throwaway checkout, never pushed and never on a + # branch. `--dry-run` below exits non-zero on ANY warning, and "you + # have uncommitted changes" is one of them — so the stamp has to land + # in a commit for the archive to be provable at all. + git -c user.email=actions@github.com -c user.name="github-actions" \ + commit -qam "stamp $VERSION" + + # The archive pub is about to receive, exactly as it will receive it: + # stamped, so the version pub validates against is the version being + # published. `--dry-run` fails on anything that would fail the real + # publish — a missing licence, a file the package cannot carry, an + # unresolvable constraint, a changelog that never mentions this version. + # + # It ran BEFORE the stamp until v0.2.0, on the reasoning that nothing + # about publishability depends on the version string. It does: pub checks + # the changelog against the CURRENT version, so the `0.0.0` placeholder + # failed it every time, and the step could never once have passed. + - name: Prove the archive is publishable + if: steps.published.outputs.skip != 'true' + working-directory: src/dart_packages/dmx + run: dart pub publish --dry-run - # `--force` rather than a second `--dry-run`: the tree is deliberately - # dirty now, and pub treats that as a warning, not an error. Proven by - # `scripts/version.test.mjs` and `test/stamp_version_test.dart`, which - # cover what was written; proven again by the `--version` check above, - # which is the released binary reporting the released number. + # `--force` only to skip the interactive confirmation: the tree is clean + # and the archive is the one proven directly above. - name: Publish if: steps.published.outputs.skip != 'true' working-directory: src/dart_packages/dmx diff --git a/.gitignore b/.gitignore index 92ef957..388186f 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,4 @@ examples/dmx_sqlite_example/tool/dmx/app.db # "autoMemoryEnabled": false setting ([AGENT-AUTOMEMORY]). Claude Code auto-ignores # this file by default, so re-include it explicitly. Keep this LAST so it wins. !.claude/settings.local.json +.mcp.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 54f0bfe..c456f76 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,18 +6,22 @@ "rust-analyzer.testExplorer": true, "rust-analyzer.check.command": "clippy", "rust-analyzer.check.allTargets": true, - // The Dart tests live in the example package, not at the workspace root. "dart.testAdditionalArgs": [], - // The Dart in this repo is the example package [editor.extension.autostart]. - "dmx.paths": ["examples/storefront/lib"], + "dmx.paths": [ + "examples/storefront/lib" + ], // Off *here only*: the `dmx: watch` task above already starts a watcher on // folder open, and this repo is the one place both mechanisms are present. // Consumers get `true`, which is the whole point of the extension. To try the // auto-start, stop that task and run "dmx: Restart Watcher". "dmx.autoStart": false, - - "[rust]": { "editor.formatOnSave": true }, - "files.watcherExclude": { "**/target/**": true } -} + "[rust]": { + "editor.formatOnSave": true + }, + "files.watcherExclude": { + "**/target/**": true + }, + "deslop.topOffenders.groupBy": "type" +} \ No newline at end of file diff --git a/Makefile b/Makefile index f227377..85b9866 100644 --- a/Makefile +++ b/Makefile @@ -420,6 +420,12 @@ vsix-universal: extension version ## Package the no-binary VSIX every other plat @# with one would hand every unmatched platform the wrong architecture. $(RM) $(EXTENSION_DIR)/bin cp LICENSE $(EXTENSION_DIR)/LICENSE + @# `vsce` opens the --out path, it does not create the directory holding it. + @# `vsix` gets that directory for free from `build`; this target carries no + @# binary and so builds nothing, which on a fresh checkout — a release + @# runner, every time — means target/ does not exist and packaging dies with + @# ENOENT after the bundle was assembled. + @$(MKDIR) $(CURDIR)/$(TARGET_DIR) cd $(EXTENSION_DIR) && npx vsce package --out $(CURDIR)/$(TARGET_DIR)/dmx-universal.vsix # Full clean rebuild-and-reinstall cycle for the VS Code extension @@ -450,6 +456,6 @@ rebuild: ## From nothing: clean, rebuild the binary, and package the VSIX corpus: ## Generate every golden sample and prove it is valid Dart @$(RM) $(CORPUS_DIR) && $(MKDIR) $(CORPUS_DIR)/lib @cp $(GOLDEN_DIR)/*.dart $(CORPUS_DIR)/lib/ - @printf 'name: dmx_corpus\nenvironment:\n sdk: ^3.0.0\ndependencies:\n dmx:\n path: $(CURDIR)/src/dart_packages/dmx\n' > $(CORPUS_DIR)/pubspec.yaml + @printf 'name: dmx_corpus\nenvironment:\n sdk: ^3.0.0\ndependencies:\n dmx: ^0.3.0\n' > $(CORPUS_DIR)/pubspec.yaml cargo run $(CRATE) --quiet -- build $(CORPUS_DIR)/lib --insert-regions cd $(CORPUS_DIR) && dart pub get && dart analyze --fatal-infos diff --git a/README.md b/README.md index 34fbb62..8968522 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Neither input leaves the tab. ## Install **VS Code** — install **dmx — Dart code generation** from the -[Marketplace](https://marketplace.visualstudio.com/items?itemName=nimblesite.dmx), +[Marketplace](https://marketplace.visualstudio.com/items?itemName=Nimblesite.dmx), or from a terminal: ```bash diff --git a/docs/messaging.md b/docs/messaging.md index e31ad7b..bbd74a4 100644 --- a/docs/messaging.md +++ b/docs/messaging.md @@ -110,6 +110,8 @@ Version control is the team's choice. Commit generated files when a checkout sho ## Calls to action - **[Try dmx in your browser—no install](https://dmx.dev/playground.html)** +- **[Install the VS Code extension](vscode:extension/Nimblesite.dmx)** — the `vscode:` link opens the extension in the editor. Pair it with the Marketplace link below rather than using either alone: the `vscode:` link does nothing for a reader who has no VS Code installed, and the Marketplace page is the only one a browser can render. +- **[View on the Marketplace](https://marketplace.visualstudio.com/items?itemName=Nimblesite.dmx)** — the publisher is `Nimblesite`, capitalised. The lowercase `nimblesite.dmx` form is what the gallery API accepts and the web page 404s on, so it must never appear in a link. - **See code generation on every save** - **Shape your team's model template** - **Build a custom Dart macro** diff --git a/examples/dmx_openapi_example/pubspec.yaml b/examples/dmx_openapi_example/pubspec.yaml index 6481e39..af96c73 100644 --- a/examples/dmx_openapi_example/pubspec.yaml +++ b/examples/dmx_openapi_example/pubspec.yaml @@ -6,8 +6,7 @@ environment: sdk: ^3.0.0 dependencies: - dmx: - path: ../../src/dart_packages/dmx + dmx: ^0.3.0 dev_dependencies: test: ^1.25.0 diff --git a/examples/dmx_sqlite_example/pubspec.yaml b/examples/dmx_sqlite_example/pubspec.yaml index 03feebd..bb5f29c 100644 --- a/examples/dmx_sqlite_example/pubspec.yaml +++ b/examples/dmx_sqlite_example/pubspec.yaml @@ -6,8 +6,7 @@ environment: sdk: ^3.0.0 dependencies: - dmx: - path: ../../src/dart_packages/dmx + dmx: ^0.3.0 dev_dependencies: test: ^1.25.0 diff --git a/examples/storefront/.dart_tool/package_config.json b/examples/storefront/.dart_tool/package_config.json deleted file mode 100644 index b17db18..0000000 --- a/examples/storefront/.dart_tool/package_config.json +++ /dev/null @@ -1,304 +0,0 @@ -{ - "configVersion": 2, - "packages": [ - { - "name": "_fe_analyzer_shared", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-105.0.0", - "packageUri": "lib/", - "languageVersion": "3.11" - }, - { - "name": "analyzer", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/analyzer-14.1.0", - "packageUri": "lib/", - "languageVersion": "3.11" - }, - { - "name": "args", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/args-2.7.0", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "async", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/async-2.13.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "boolean_selector", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/boolean_selector-2.1.2", - "packageUri": "lib/", - "languageVersion": "3.1" - }, - { - "name": "cli_config", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/cli_config-0.2.0", - "packageUri": "lib/", - "languageVersion": "3.0" - }, - { - "name": "collection", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/collection-1.19.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "convert", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/convert-3.1.2", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "coverage", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/coverage-1.15.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "crypto", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/crypto-3.0.7", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "dmx", - "rootUri": "../../../src/dart_packages/dmx", - "packageUri": "lib/", - "languageVersion": "3.0" - }, - { - "name": "file", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/file-7.0.1", - "packageUri": "lib/", - "languageVersion": "3.0" - }, - { - "name": "frontend_server_client", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/frontend_server_client-4.0.0", - "packageUri": "lib/", - "languageVersion": "3.0" - }, - { - "name": "glob", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/glob-2.1.3", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "http_multi_server", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/http_multi_server-3.2.2", - "packageUri": "lib/", - "languageVersion": "3.2" - }, - { - "name": "http_parser", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/http_parser-4.1.2", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "io", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/io-1.0.5", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "logging", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/logging-1.3.0", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "matcher", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/matcher-0.12.20", - "packageUri": "lib/", - "languageVersion": "3.10" - }, - { - "name": "meta", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/meta-1.19.0", - "packageUri": "lib/", - "languageVersion": "3.5" - }, - { - "name": "mime", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/mime-2.0.0", - "packageUri": "lib/", - "languageVersion": "3.2" - }, - { - "name": "node_preamble", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/node_preamble-2.0.2", - "packageUri": "lib/", - "languageVersion": "2.12" - }, - { - "name": "package_config", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/package_config-3.0.0", - "packageUri": "lib/", - "languageVersion": "3.11" - }, - { - "name": "path", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/path-1.9.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "pool", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/pool-1.5.2", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "pub_semver", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/pub_semver-2.2.0", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "shelf", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/shelf-1.4.2", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "shelf_packages_handler", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/shelf_packages_handler-3.0.2", - "packageUri": "lib/", - "languageVersion": "2.17" - }, - { - "name": "shelf_static", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/shelf_static-1.1.3", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "shelf_web_socket", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/shelf_web_socket-3.0.0", - "packageUri": "lib/", - "languageVersion": "3.5" - }, - { - "name": "source_map_stack_trace", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/source_map_stack_trace-2.1.2", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "source_maps", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/source_maps-0.10.13", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "source_span", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/source_span-1.10.2", - "packageUri": "lib/", - "languageVersion": "3.1" - }, - { - "name": "stack_trace", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/stack_trace-1.12.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "stream_channel", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/stream_channel-2.1.4", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "string_scanner", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/string_scanner-1.4.1", - "packageUri": "lib/", - "languageVersion": "3.1" - }, - { - "name": "term_glyph", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/term_glyph-1.2.2", - "packageUri": "lib/", - "languageVersion": "3.1" - }, - { - "name": "test", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/test-1.31.2", - "packageUri": "lib/", - "languageVersion": "3.11" - }, - { - "name": "test_api", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/test_api-0.7.13", - "packageUri": "lib/", - "languageVersion": "3.11" - }, - { - "name": "test_core", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/test_core-0.6.19", - "packageUri": "lib/", - "languageVersion": "3.11" - }, - { - "name": "typed_data", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/typed_data-1.4.0", - "packageUri": "lib/", - "languageVersion": "3.5" - }, - { - "name": "vm_service", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/vm_service-15.2.0", - "packageUri": "lib/", - "languageVersion": "3.5" - }, - { - "name": "watcher", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/watcher-1.2.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "web", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/web-1.1.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "web_socket", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/web_socket-1.0.1", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "web_socket_channel", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/web_socket_channel-3.0.3", - "packageUri": "lib/", - "languageVersion": "3.3" - }, - { - "name": "webkit_inspection_protocol", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/webkit_inspection_protocol-1.2.1", - "packageUri": "lib/", - "languageVersion": "3.0" - }, - { - "name": "yaml", - "rootUri": "file:///Users/christianfindlay/.pub-cache/hosted/pub.dev/yaml-3.1.3", - "packageUri": "lib/", - "languageVersion": "3.4" - }, - { - "name": "dmx_storefront_example", - "rootUri": "../", - "packageUri": "lib/", - "languageVersion": "3.0" - } - ], - "generator": "pub", - "generatorVersion": "3.12.2", - "flutterRoot": "file:///opt/homebrew/share/flutter", - "flutterVersion": "3.44.2", - "pubCache": "file:///Users/christianfindlay/.pub-cache" -} diff --git a/examples/storefront/.dart_tool/package_graph.json b/examples/storefront/.dart_tool/package_graph.json deleted file mode 100644 index 3a01d97..0000000 --- a/examples/storefront/.dart_tool/package_graph.json +++ /dev/null @@ -1,448 +0,0 @@ -{ - "roots": [ - "dmx_storefront_example" - ], - "packages": [ - { - "name": "dmx_storefront_example", - "version": "0.1.0", - "dependencies": [ - "dmx" - ], - "devDependencies": [ - "test" - ] - }, - { - "name": "test", - "version": "1.31.2", - "dependencies": [ - "analyzer", - "async", - "boolean_selector", - "collection", - "coverage", - "http_multi_server", - "io", - "matcher", - "node_preamble", - "package_config", - "path", - "pool", - "shelf", - "shelf_packages_handler", - "shelf_static", - "shelf_web_socket", - "source_span", - "stack_trace", - "stream_channel", - "test_api", - "test_core", - "typed_data", - "web_socket_channel", - "webkit_inspection_protocol", - "yaml" - ] - }, - { - "name": "dmx", - "version": "0.0.0", - "dependencies": [] - }, - { - "name": "yaml", - "version": "3.1.3", - "dependencies": [ - "collection", - "source_span", - "string_scanner" - ] - }, - { - "name": "webkit_inspection_protocol", - "version": "1.2.1", - "dependencies": [ - "logging" - ] - }, - { - "name": "web_socket_channel", - "version": "3.0.3", - "dependencies": [ - "async", - "crypto", - "stream_channel", - "web", - "web_socket" - ] - }, - { - "name": "typed_data", - "version": "1.4.0", - "dependencies": [ - "collection" - ] - }, - { - "name": "test_core", - "version": "0.6.19", - "dependencies": [ - "analyzer", - "args", - "async", - "boolean_selector", - "collection", - "coverage", - "frontend_server_client", - "glob", - "io", - "meta", - "package_config", - "path", - "pool", - "source_map_stack_trace", - "source_maps", - "source_span", - "stack_trace", - "stream_channel", - "test_api", - "vm_service", - "yaml" - ] - }, - { - "name": "test_api", - "version": "0.7.13", - "dependencies": [ - "async", - "boolean_selector", - "collection", - "meta", - "source_span", - "stack_trace", - "stream_channel", - "string_scanner", - "term_glyph" - ] - }, - { - "name": "stream_channel", - "version": "2.1.4", - "dependencies": [ - "async" - ] - }, - { - "name": "stack_trace", - "version": "1.12.1", - "dependencies": [ - "path" - ] - }, - { - "name": "source_span", - "version": "1.10.2", - "dependencies": [ - "collection", - "path", - "term_glyph" - ] - }, - { - "name": "shelf_web_socket", - "version": "3.0.0", - "dependencies": [ - "shelf", - "stream_channel", - "web_socket_channel" - ] - }, - { - "name": "shelf_static", - "version": "1.1.3", - "dependencies": [ - "convert", - "http_parser", - "mime", - "path", - "shelf" - ] - }, - { - "name": "shelf_packages_handler", - "version": "3.0.2", - "dependencies": [ - "path", - "shelf", - "shelf_static" - ] - }, - { - "name": "shelf", - "version": "1.4.2", - "dependencies": [ - "async", - "collection", - "http_parser", - "path", - "stack_trace", - "stream_channel" - ] - }, - { - "name": "pool", - "version": "1.5.2", - "dependencies": [ - "async", - "stack_trace" - ] - }, - { - "name": "path", - "version": "1.9.1", - "dependencies": [] - }, - { - "name": "package_config", - "version": "3.0.0", - "dependencies": [ - "meta" - ] - }, - { - "name": "node_preamble", - "version": "2.0.2", - "dependencies": [] - }, - { - "name": "matcher", - "version": "0.12.20", - "dependencies": [ - "async", - "meta", - "stack_trace", - "term_glyph", - "test_api" - ] - }, - { - "name": "io", - "version": "1.0.5", - "dependencies": [ - "meta", - "path", - "string_scanner" - ] - }, - { - "name": "http_multi_server", - "version": "3.2.2", - "dependencies": [ - "async" - ] - }, - { - "name": "coverage", - "version": "1.15.1", - "dependencies": [ - "args", - "cli_config", - "glob", - "logging", - "meta", - "package_config", - "path", - "source_maps", - "stack_trace", - "vm_service", - "yaml" - ] - }, - { - "name": "collection", - "version": "1.19.1", - "dependencies": [] - }, - { - "name": "boolean_selector", - "version": "2.1.2", - "dependencies": [ - "source_span", - "string_scanner" - ] - }, - { - "name": "async", - "version": "2.13.1", - "dependencies": [ - "collection", - "meta" - ] - }, - { - "name": "analyzer", - "version": "14.1.0", - "dependencies": [ - "_fe_analyzer_shared", - "collection", - "convert", - "crypto", - "glob", - "meta", - "package_config", - "path", - "pub_semver", - "source_span", - "watcher", - "yaml" - ] - }, - { - "name": "string_scanner", - "version": "1.4.1", - "dependencies": [ - "source_span" - ] - }, - { - "name": "logging", - "version": "1.3.0", - "dependencies": [] - }, - { - "name": "web_socket", - "version": "1.0.1", - "dependencies": [ - "web" - ] - }, - { - "name": "web", - "version": "1.1.1", - "dependencies": [] - }, - { - "name": "crypto", - "version": "3.0.7", - "dependencies": [ - "typed_data" - ] - }, - { - "name": "vm_service", - "version": "15.2.0", - "dependencies": [] - }, - { - "name": "source_maps", - "version": "0.10.13", - "dependencies": [ - "source_span" - ] - }, - { - "name": "source_map_stack_trace", - "version": "2.1.2", - "dependencies": [ - "path", - "source_maps", - "stack_trace" - ] - }, - { - "name": "meta", - "version": "1.19.0", - "dependencies": [] - }, - { - "name": "glob", - "version": "2.1.3", - "dependencies": [ - "async", - "collection", - "file", - "path", - "string_scanner" - ] - }, - { - "name": "frontend_server_client", - "version": "4.0.0", - "dependencies": [ - "async", - "path" - ] - }, - { - "name": "args", - "version": "2.7.0", - "dependencies": [] - }, - { - "name": "term_glyph", - "version": "1.2.2", - "dependencies": [] - }, - { - "name": "mime", - "version": "2.0.0", - "dependencies": [] - }, - { - "name": "http_parser", - "version": "4.1.2", - "dependencies": [ - "collection", - "source_span", - "string_scanner", - "typed_data" - ] - }, - { - "name": "convert", - "version": "3.1.2", - "dependencies": [ - "typed_data" - ] - }, - { - "name": "cli_config", - "version": "0.2.0", - "dependencies": [ - "args", - "yaml" - ] - }, - { - "name": "watcher", - "version": "1.2.1", - "dependencies": [ - "async", - "path" - ] - }, - { - "name": "pub_semver", - "version": "2.2.0", - "dependencies": [ - "collection" - ] - }, - { - "name": "_fe_analyzer_shared", - "version": "105.0.0", - "dependencies": [ - "meta" - ] - }, - { - "name": "file", - "version": "7.0.1", - "dependencies": [ - "meta", - "path" - ] - } - ], - "configVersion": 1 -} \ No newline at end of file diff --git a/examples/storefront/pubspec.lock b/examples/storefront/pubspec.lock index 3547bd5..7c867fd 100644 --- a/examples/storefront/pubspec.lock +++ b/examples/storefront/pubspec.lock @@ -84,10 +84,11 @@ packages: dmx: dependency: "direct main" description: - path: "../../src/dart_packages/dmx" - relative: true - source: path - version: "0.0.0" + name: dmx + sha256: "0d604ba0c5a9cc9977281fff53ceee03e1cad5ff99fc7ce742a086d8839b6d33" + url: "https://pub.dev" + source: hosted + version: "0.3.0" file: dependency: transitive description: diff --git a/examples/storefront/pubspec.yaml b/examples/storefront/pubspec.yaml index 181cea7..bb57fd2 100644 --- a/examples/storefront/pubspec.yaml +++ b/examples/storefront/pubspec.yaml @@ -5,8 +5,7 @@ publish_to: none environment: sdk: ^3.0.0 dependencies: - dmx: - path: ../../src/dart_packages/dmx + dmx: ^0.3.0 dev_dependencies: test: ^1.25.0 diff --git a/src/dart_packages/dmx/CHANGELOG.md b/src/dart_packages/dmx/CHANGELOG.md index 151e17c..2b7be75 100644 --- a/src/dart_packages/dmx/CHANGELOG.md +++ b/src/dart_packages/dmx/CHANGELOG.md @@ -5,6 +5,15 @@ ## Unreleased +- No API changes. The README linked the extension's Marketplace page with the + publisher in lowercase, which 404s; it is `Nimblesite.dmx`. + +## 0.2.0 + +- No API changes. `lib/` is identical to 0.1.0 apart from the version constant. +- The tag names the version, and the release stamps it [release.version]. +- README rewritten in plainer language. + ## 0.1.0 First release. diff --git a/src/dart_packages/dmx/README.md b/src/dart_packages/dmx/README.md index bd0f36d..0972af0 100644 --- a/src/dart_packages/dmx/README.md +++ b/src/dart_packages/dmx/README.md @@ -8,7 +8,7 @@ factory, and no `build_runner` run. This package holds the `@dmx` annotation, the types the generated code uses, and the API for writing your own macros in Dart. The generating itself is done by the dmx tool, which the -[VS Code extension](https://marketplace.visualstudio.com/items?itemName=nimblesite.dmx) +[VS Code extension](https://marketplace.visualstudio.com/items?itemName=Nimblesite.dmx) bundles and runs for you. [Run the real generator in your browser](https://dmx.dev/playground.html) · diff --git a/src/dmx/tests/golden/pubspec.yaml b/src/dmx/tests/golden/pubspec.yaml index af119e6..4333ef2 100644 --- a/src/dmx/tests/golden/pubspec.yaml +++ b/src/dmx/tests/golden/pubspec.yaml @@ -4,5 +4,4 @@ publish_to: none environment: sdk: ^3.0.0 dependencies: - dmx: - path: ../../../dart_packages/dmx + dmx: ^0.3.0 diff --git a/src/editors/vscode/CHANGELOG.md b/src/editors/vscode/CHANGELOG.md index 473333d..45934ab 100644 --- a/src/editors/vscode/CHANGELOG.md +++ b/src/editors/vscode/CHANGELOG.md @@ -5,6 +5,19 @@ ## Unreleased +- New icon: the dmx mark the website, favicon and docs already use. The + extension had been shipping an older mark that matched nothing else. + +## 0.2.0 + +- First Marketplace release. +- Watches every Dart package in the folder you open, not just `lib` + [editor.extension.paths]. Set `dmx.paths` to name them yourself. +- Also finds the binary in `src/dmx/target/{release,debug}` + [editor.extension.binary]. +- Resolves reported paths against the folder dmx ran in. +- Removed a debug probe that ran on activation. + ## 0.1.0 First release. diff --git a/src/editors/vscode/README.md b/src/editors/vscode/README.md index 8952ed0..574991e 100644 --- a/src/editors/vscode/README.md +++ b/src/editors/vscode/README.md @@ -8,7 +8,7 @@ factories, and no `build_runner` run. ## Install Install **dmx — Dart code generation** from the -[VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=nimblesite.dmx), +[VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=Nimblesite.dmx), or run: ```bash diff --git a/src/editors/vscode/icon.png b/src/editors/vscode/icon.png index a0adb70..4768c9b 100644 Binary files a/src/editors/vscode/icon.png and b/src/editors/vscode/icon.png differ diff --git a/website/src/docs/index.md b/website/src/docs/index.md index ee5129a..b12b415 100644 --- a/website/src/docs/index.md +++ b/website/src/docs/index.md @@ -58,17 +58,20 @@ Install **dmx — Dart code generation** in any of these ways: - In VS Code, open **Extensions** (`⇧⌘X` on macOS or `Ctrl+Shift+X` on Windows and Linux), search for **dmx**, and select **Install**. -- From a terminal, run `code --install-extension nimblesite.dmx`. -- Open the [dmx Marketplace page](https://marketplace.visualstudio.com/items?itemName=nimblesite.dmx) +- From a terminal, run `code --install-extension Nimblesite.dmx`. +- Select [Install the VS Code extension](vscode:extension/Nimblesite.dmx), which + opens the extension in the editor you already have. +- Open the [dmx Marketplace page](https://marketplace.visualstudio.com/items?itemName=Nimblesite.dmx) and select **Install**. Open or reload a trusted Dart workspace after installation. The extension runs an initial build, inserts missing generated regions, and keeps them current as you save. -Platform-specific extensions are published for macOS and Linux on x64 and +Platform-specific extensions are published for macOS on ARM64, Linux on x64 and ARM64, Alpine on x64 and ARM64, and Windows on x64. VS Code selects the correct -bundle automatically. +bundle automatically, and installs a build carrying no binary anywhere else — +that one runs `dmx` from `PATH`. For an offline or air-gapped installation, download the VSIX for your platform from the [latest GitHub release](https://github.com/Nimblesite/dmx/releases/latest). diff --git a/website/src/index.njk b/website/src/index.njk index 164b5c7..f2905be 100644 --- a/website/src/index.njk +++ b/website/src/index.njk @@ -88,13 +88,16 @@ + + Install the VS Code extension + - Install the watcher + View on the Marketplace