Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ emsdk/

# daspkg artifacts
daspkg.lock
.daspkg_global.lock
.daspkg_standalone
modules/.daspkg_tmp/
modules/.daspkg_backup/
modules/.daspkg_cache/
modules/.daspkg.log
examples/*/modules/

# Claude Code (local settings)
Expand Down
7 changes: 5 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,10 @@ ENDFUNCTION()


FOREACH(_module ${_modules})
INCLUDE(modules/${_module}/CMakeLists.txt OPTIONAL)
# Skip daspkg-installed modules that build themselves (standalone CMake)
IF(NOT EXISTS "${PROJECT_SOURCE_DIR}/modules/${_module}/.daspkg_standalone")
INCLUDE(modules/${_module}/CMakeLists.txt OPTIONAL)
ENDIF()
ENDFOREACH()

# Clean stale .shared_module files. When a module is disabled, its .shared_module
Expand Down Expand Up @@ -1307,6 +1310,7 @@ install(FILES

install(FILES ${PROJECT_SOURCE_DIR}/install/README.md DESTINATION ${DAS_INSTALL_DOCDIR})
install(FILES ${PROJECT_SOURCE_DIR}/install/CLAUDE.md DESTINATION ${DAS_INSTALL_DOCDIR})
install(FILES ${PROJECT_SOURCE_DIR}/install/.gitignore DESTINATION ${DAS_INSTALL_DOCDIR})
install(DIRECTORY ${PROJECT_SOURCE_DIR}/install/skills DESTINATION ${DAS_INSTALL_DOCDIR})
install(FILES ${PROJECT_SOURCE_DIR}/LICENSE DESTINATION ${DAS_INSTALL_DOCDIR})
install(FILES ${PROJECT_SOURCE_DIR}/3rdparty/uriparser/COPYING DESTINATION ${DAS_INSTALL_DOCDIR} RENAME URIPARSER.LICENSE)
Expand Down Expand Up @@ -1354,7 +1358,6 @@ file(GLOB DAS_DASPKG_FILES ${PROJECT_SOURCE_DIR}/utils/daspkg/*.das)
install(FILES ${DAS_DASPKG_FILES} DESTINATION utils/daspkg)
install(FILES
${PROJECT_SOURCE_DIR}/utils/daspkg/README.md
${PROJECT_SOURCE_DIR}/utils/daspkg/DESIGN.md
DESTINATION utils/daspkg
)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/utils/daspkg/fixtures/
Expand Down
114 changes: 106 additions & 8 deletions doc/source/reference/utils/daspkg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ Design principles:
- **Executable manifests** -- ``.das_package`` is a daslang script, not
a static JSON file. Version resolution, dependency declarations, and
build steps can contain arbitrary logic.
- **Per-project** -- packages install into the project's ``modules/``
directory (like ``node_modules``), not globally. Reproducible builds
by default.
- **Per-project by default** -- packages install into the project's
``modules/`` directory (like ``node_modules``). Reproducible builds
by default. Large modules can be installed **globally** with
``--global`` to avoid redundant clones and builds across projects.
- **Two package types** -- pure-daslang (just ``.das`` files, no build)
and C++ (cmake auto-build from source).

Expand All @@ -84,6 +85,8 @@ Commands
* - ``update [name]``
- Re-install one or all packages at their pinned version
(re-clone, rebuild).
* - ``upgrade [name]``
- Upgrade one or all packages to the latest version.
* - ``list``
- List installed packages.
* - ``search <query>``
Expand All @@ -99,12 +102,21 @@ Commands
* - ``withdraw <name>``
- Remove a package from the index via PR (requires ``gh`` CLI).

All commands that operate on packages (``install``, ``remove``,
``update``, ``upgrade``, ``list``, ``check``, ``build``) accept the
``--global`` flag.

Options:

- ``--root <path>`` -- project root (default: current directory).
- ``--force`` -- force reinstall even if already installed.
- ``--global``, ``-g`` -- operate on global modules in
``{das_root}/modules/`` (see :ref:`daspkg_global_modules`).
- ``--color`` / ``--no-color`` -- enable/disable ANSI colored output.
- ``--verbose``, ``-v`` -- print debug details (git commands, resolve
steps, file operations).
- ``--json`` -- machine-readable JSON output (``search``, ``list``,
``check``).


Package sources
Expand Down Expand Up @@ -251,6 +263,78 @@ When you run ``daspkg install github.com/user/repo@v1.0``:
7. Auto-build if ``.das_package`` has ``build()``.


.. _daspkg_global_modules:

Global modules
==============

By default, packages install per-project into ``{root}/modules/``.
Large packages with native builds (e.g. dasImgui) can be installed
**globally** -- once under ``{das_root}/modules/`` -- and shared across
all projects using that daScript SDK.

.. code-block:: bash

# install globally
daspkg install --global dasImgui

# list / update / upgrade / remove / build / check globally
daspkg list --global
daspkg update --global dasImgui
daspkg upgrade --global dasImgui
daspkg remove --global dasImgui
daspkg build --global
daspkg check --global

Install behavior
----------------

- **Global install** (``--global``): clones and builds in
``{das_root}/modules/``, records in
``{das_root}/modules/.daspkg_global.lock``.
- **Local install auto-uses global**: ``daspkg install foo`` checks the
global lock file first. If a compatible global version exists, it
records a reference (``"global": true`` in the project lock file)
instead of cloning -- zero network, zero build time.
- **Version mismatch**: if the global version doesn't satisfy the
requested version, daspkg errors with a suggestion. Use ``--force``
to install locally, or ``--global`` to update the global copy.
- **Dependencies**: global packages' dependencies also install globally.
Built-in SDK modules already in ``{das_root}/modules/`` are skipped
automatically.

Coexistence (local + global)
----------------------------

A package can exist both locally and globally. The C++ runtime
(``require_dynamic_modules``) handles this via **shadow detection**:

- If the same module directory exists in both ``{das_root}/modules/``
and ``{project_root}/modules/``, the **local version wins**.
- A warning is printed:
``Warning: local 'dasImgui' shadows global -- using local``
- This is safe -- removing the local copy seamlessly falls back to the
global one.

Remove behavior
---------------

- ``daspkg remove --global foo`` -- deletes ``{das_root}/modules/foo/``
and removes from global lock file.
- ``daspkg remove foo`` (where project entry has ``"global": true``) --
only removes the project lock file reference; the global directory is
**not** deleted.

CMake integration
-----------------

Global packages that use ``cmake_build()`` or ``custom_build()`` get a
``.daspkg_standalone`` marker file. The main daScript ``CMakeLists.txt``
skips directories with this marker during auto-discovery, preventing
build errors from standalone CMakeLists.txt files that expect
``DASLANG_DIR`` to be set explicitly.


Project layout
==============

Expand All @@ -270,6 +354,13 @@ Project layout
.daspkg_cache/ # index cache (gitignored)
.daspkg_tmp/ # temp dir during install (gitignored)

{das_root}/ # daScript SDK root
modules/
.daspkg_global.lock # global lock file (gitignored)
<global_package>/
.daspkg_standalone # marker: built by daspkg, skip in CMake
... # same structure as local packages


Lock file
=========
Expand All @@ -280,23 +371,30 @@ Lock file

{
"sdk_version": "",
"packages": {
"mymodule": {
"packages": [
{
"name": "mymodule",
"source": "github.com/user/mymodule",
"version": "v1.0",
"version": "1.0",
"tag": "v1.0",
"branch": "",
"root": true,
"local": false
"local": false,
"global": false
}
}
]
}

- **root** -- ``true`` if the user explicitly installed this package;
``false`` if it was pulled in as a transitive dependency.
- **version** -- what the user requested.
- **tag/branch** -- what ``.das_package`` resolved to (the actual git ref).
- **local** -- ``true`` for packages installed from a local path.
- **global** -- ``true`` if the package is resolved from a global
install in ``{das_root}/modules/`` (no local copy).

The global lock file (``{das_root}/modules/.daspkg_global.lock``) uses
the same format to track globally installed packages.


Package index
Expand Down
27 changes: 27 additions & 0 deletions install/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Build artifacts
build/
bin/
lib/
.cache/

# JIT
.jitted_scripts/

# AOT
_aot_generated/

# daspkg
daspkg.lock
.daspkg_global.lock
.daspkg_standalone
modules/.daspkg_tmp/
modules/.daspkg_backup/
modules/.daspkg_cache/
modules/.daspkg.log

# IDE
.vscode/

# MCP
.mcp.json
sgconfig.yml
84 changes: 73 additions & 11 deletions skills/daspkg.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ The `--root` flag sets the project root directory (default: current directory).

| Command | Usage | Description |
|---|---|---|
| `search` | `search [query] --json` | Search the package index. Empty query lists all. `--json` for structured output |
| `install` | `install <source> [--force]` | Install a package. Without source, installs all deps from `.das_package` |
| `remove` | `remove <name>` | Remove an installed package |
| `update` | `update [name]` | Re-install at pinned version. Without name, updates all |
| `upgrade` | `upgrade [name]` | Upgrade to latest version. Without name, upgrades all |
| `list` | `list [--json]` | List installed packages |
| `check` | `check [--json]` | Verify installed packages match lockfile |
| `build` | `build` | Build native (CMake) packages |
| `search` | `search [query] [--json]` | Search the package index. Empty query lists all |
| `install` | `install <source> [--force] [--global]` | Install a package. Without source, installs all deps from `.das_package` |
| `remove` | `remove <name> [--global]` | Remove an installed package |
| `update` | `update [name] [--global]` | Re-install at pinned version. Without name, updates all |
| `upgrade` | `upgrade [name] [--global]` | Upgrade to latest version. Without name, upgrades all |
| `list` | `list [--json] [--global]` | List installed packages |
| `check` | `check [--json] [--global]` | Verify installed packages match lockfile |
| `build` | `build [--global]` | Build native (CMake) packages |
| `doctor` | `doctor` | Check environment (git, cmake, gh) |
| `introduce` | `introduce` | Register package in the public index (creates PR on daspkg-index) |
| `withdraw` | `withdraw` | Remove package from the public index |
Expand All @@ -39,14 +39,76 @@ The `--root` flag sets the project root directory (default: current directory).
- **Local path:** `install ./path/to/package`
- **Index name:** `install my-package` (looks up in package index)

## Options

| Flag | Description |
|---|---|
| `--root <path>` | Project root directory (default: current directory) |
| `--force` | Force reinstall (overrides duplicate/version checks) |
| `--global`, `-g` | Operate on global modules in `{das_root}/modules/` (see below) |
| `--color` | Enable colored output |
| `--no-color` | Disable colored output (useful for capturing output) |
| `--verbose`, `-v` | Print detailed progress |
| `--json` | Machine-readable JSON output (`search`, `list`, `check`) |

## Key Details

- Packages install to `modules/<RepoName>/` (e.g. `modules/dasAnthropic/`)
- Packages install to `{root}/modules/<RepoName>/` (e.g. `modules/dasAnthropic/`)
- Lock file: `daspkg.lock` in the `--root` directory
- Package name (in `.das_package`) can differ from repo name
- `install` and `update`/`upgrade` can take 10+ minutes for packages with native builds — use long timeouts
- `--no-color` flag disables ANSI color output (useful for capturing output)
- `--json` flag on `search`, `list`, `check` returns structured JSON

## Global Modules

Large packages (e.g. dasImgui) can be installed **globally** — once under `{das_root}/modules/` — and shared across all projects using that daScript SDK. This avoids redundant clones and builds.

### Usage

```bash
# Install globally (to das_root/modules/)
daspkg install --global dasImgui
daspkg install --global github.com/user/dasImgui@1.0

# List globally installed packages
daspkg list --global

# Update/upgrade globally
daspkg update --global dasImgui
daspkg upgrade --global dasImgui

# Remove globally
daspkg remove --global dasImgui

# Build all global native packages
daspkg build --global

# Check global packages
daspkg check --global
```

### Install behavior

- **Global install** (`--global`): clones and builds in `{das_root}/modules/`, records in `{das_root}/modules/.daspkg_global.lock`
- **Local install auto-uses global:** `daspkg install foo` checks the global lock file first. If a compatible global version exists, it records a reference (`"global": true` in project lock file) instead of cloning — zero network, zero build time
- **Version mismatch:** if the global version doesn't satisfy the project's requested version, daspkg errors with a suggestion. Use `--force` to install locally, or `--global` to update the global copy
- **Dependencies:** global packages' dependencies also install globally. Built-in SDK modules (already in `das_root/modules/`) are automatically skipped

### Coexistence (local + global)

A package can exist both locally and globally. The C++ runtime (`require_dynamic_modules`) handles this via **shadow detection**:

- If the same module directory exists in both `{das_root}/modules/` and `{project_root}/modules/`, the **local version wins**
- A warning is printed: `"Warning: local 'dasImgui' shadows global — using local"`
- This is safe — removing the local copy seamlessly falls back to the global one

### Remove behavior

- `daspkg remove --global foo` — deletes `{das_root}/modules/foo/` and removes from global lock file
- `daspkg remove foo` (where project entry has `"global": true`) — only removes the project lock file reference; the global directory is not deleted

### CMake integration

Global packages that use `cmake_build()` or `custom_build()` get a `.daspkg_standalone` marker file. The main daScript `CMakeLists.txt` skips directories with this marker during auto-discovery, preventing `FATAL_ERROR` from standalone CMakeLists.txt files (e.g. dasImgui requires `DASLANG_DIR` to be set explicitly).

## `.das_package` Manifest

Expand Down
Loading
Loading