Skip to content

feat(install): install dependencies by id and explain unknown module names - #144

Open
ehennestad wants to merge 5 commits into
devfrom
claude/nansen-install-errors-1ea074
Open

ehennestad wants to merge 5 commits into
devfrom
claude/nansen-install-errors-1ea074

Conversation

@ehennestad

Copy link
Copy Markdown
Collaborator

Summary

nansen_install(Modules="some_name") raised a warning for an unknown module and then installed only the core dependencies, without saying which module names exist. There was no way to install a single dependency. This PR adds ids to the dependency manifests, a targeted install by id, and error messages that list what is available.

Changes

  • The dependency manifest schema has an optional id field: a short, lowercase, kebab-case identifier for a community toolbox, unique across manifests. readManifest returns it as Id. Every community toolbox in code/dependencies.nansen.json and in the two-photon module manifest has an id, for example flowreg, normcorre, suite2p and catalog.
  • nansen_install("flowreg") installs only the named community toolboxes plus MatBox and adds them to the path. It accepts a string array of ids. Update=true updates the named toolboxes that are installed and installs the missing ones. The core installation check (verifyInstallation) is skipped for this call.
  • nansen_install(Modules=...) accepts the package name (nansen.module.ophys.twophoton), the name in module.nansen.json ("Two Photon Imaging") or the short name (twophoton). The last two are matched without regard to letter case.
  • Module names and ids are checked before anything is downloaded. An unknown module name throws NANSEN:Dependencies:UnknownModule with a table of the modules on the path and a note that NANSEN finds modules in +nansen/+module folders on the MATLAB search path. An unknown id throws NANSEN:Dependencies:UnknownDependency with the available ids grouped by module. A module name passed as an id points to Modules=.
  • nansen.internal.dependencies.assertInstalled("flowreg") throws NANSEN:Dependencies:NotInstalled with the command nansen_install("flowreg") when the installCheck of the toolbox is not on the path. Code that needs an optional toolbox can call it before using the toolbox.
  • New functions in nansen.internal.dependencies: listModules, resolveModuleNames, resolveDependencyIds and assertInstalled. listModules uses what and dir, so it works before community toolboxes such as recursiveDir are installed.
  • AddonManager.installMissingAddons, updateAddons and getManagedAddonsForModules take an AddonNames filter.
  • Fix: nansen_install() requested an output from installMissingAddons, which suppresses its failure summary, so failed installs were not reported. When every missing add-on failed, it printed "All dependencies are installed". It now passes ShowSummary=true and prints that message only when no add-on needed to be installed.
  • Fix: the Flow Registration installCheck was OF_Options, but the class is OF_options. The check matched only on file systems that ignore case.
  • Tests: DependencyLookupTest creates fixture modules in a temporary folder on the path and covers the lookups, the error messages and the checks in nansen_install. TestDependencyManagement checks the core ids against the pattern in the schema. AddonManagerTest covers the AddonNames filter.

Notes

  • The draft two-photon migration stack deletes code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json in WP8: remove the two-photon module from NANSEN and require it from its own repository #137. Rebasing the stack onto this PR gives a modify/delete conflict on that file; keep the deletion.
  • The manifest in NANSEN-TwoPhoton needs the same ids and the OF_options fix. The four assertAddonInstalled methods there (flowreg, normcorre, suite2p, extract) can then call nansen.internal.dependencies.assertInstalled with their id.

🤖 Generated with Claude Code

ehennestad and others added 4 commits September 18, 2026 17:15
Dependency entries had only a display name, such as "Flow
Registration", which is too long to type and can contain spaces. The
manifest schema now has an optional "id": a short, lowercase,
kebab-case identifier for a community toolbox that is unique across
manifests. readManifest returns it in the Id field.

Every community toolbox in the core manifest and in the two-photon
module manifest gets an id, for example "flowreg", "normcorre",
"suite2p" and "catalog". A test checks that the core ids are present,
unique and match the pattern in the schema.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The installCheck for Flow Registration was "OF_Options", but the
class in the flow_registration toolbox is defined as OF_options. On
macOS, which ignores case in file names, which("OF_Options") still
finds OF_options.m. On a case-sensitive file system the check does
not find the file, so NANSEN would report Flow Registration as
missing even when it is installed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AddonManager.installMissingAddons prints a summary of failed installs
only when the caller requests no outputs or passes ShowSummary.
nansen_install requested the number of installed add-ons, so failed
downloads and setup steps were never reported. When every missing
add-on failed, that number was zero and nansen_install printed "All
dependencies are installed".

nansen_install now passes ShowSummary=true and prints that message
only when no add-on needed to be installed (NumAttempted is zero).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nansen_install("flowreg") installs only the community toolboxes with
the given ids, plus MatBox, and adds them to the path. It skips the
core installation check. Update=true updates the named toolboxes that
are installed and installs the missing ones. The ids come from the
core manifest and from the dependencies.nansen.json file of each
module on the MATLAB search path.

nansen_install(Modules=...) accepts a module's package name, the name
in its module.nansen.json file, or the last part of its package name.
Module names and dependency ids are checked before anything is
downloaded. An unknown module name lists the modules on the path and
explains that modules are found in +nansen/+module folders on the
path. An unknown id lists the available ids by module, and a module
name given as an id points to Modules=.

New functions in nansen.internal.dependencies:
- listModules finds modules with what() and dir(), so it works
  before community toolboxes such as recursiveDir are installed
- resolveModuleNames and resolveDependencyIds convert user input and
  raise the errors above
- assertInstalled throws an error with the nansen_install command
  for a dependency that is not on the path, for code to call before
  it uses an optional toolbox

AddonManager.installMissingAddons, updateAddons and
getManagedAddonsForModules take an AddonNames filter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Test Results

392 tests  +23   392 ✅ +23   39s ⏱️ +12s
 26 suites + 1     0 💤 ± 0 
  1 files   ± 0     0 ❌ ± 0 

Results for commit 4cf5e82. ± Comparison against base commit d8ee8c3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant