Skip to content

feat(cli): syspi update moves a usage to the highest version its constraint allows; outdated reports what it would move - #15

Open
devin-ai-integration[bot] wants to merge 5 commits into
feat/removefrom
feat/update
Open

devin-ai-integration[bot] wants to merge 5 commits into
feat/removefrom
feat/update

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

syspi update [-C dir] [-offline] [<resource>...] and syspi outdated [-json] [<resource>...] — the last of the commands 0.1.0 lacks.

Stacked on #10 (remove), base feat/remove: moving a lock entry leaves the previous version's copy under lib/, and update removes it through the pruning #10 adds (Options.Prune, libPath). Once #10 merges, this PR rebases onto develop with no change. The diff here is only the update/outdated commits.

  • update is the one command that moves a lock entry; everywhere else a lock entry that satisfies its constraint wins (README and docs/packages.md now say so). install/lock after loosening a constraint keep the locked version — tested.
  • Resolver: Options.Update (repository keys) / Options.UpdateAll make resolveVCS look at the repository first for those usages — latest lists the tags and vcs.Selects the highest satisfying the constraint — and treat the lock entry as absent only when that version differs; an entry already at the top is reused as before (nothing re-exported). Options.DryRun resolves as LockOnly and returns without writing. Result.Changes (changes(old, fresh), by repository key) lists every entry moved, added or dropped, in resource order.
  • install.Update(ctx, opts, resources): resources name usages of .project.json by canonical identity (as add/remove match); none means every repository of the closure. A usage that is not a repository (archive, local directory, standard library) has no versions to choose from and is refused by name; update leaves such entries alone. Then Run with Prune, so the moved-away copy goes (removed lib/base_2.0.0).
  • install.Outdated is the same resolution with DryRun: name old -> new lines (or -json), nothing written, nothing installed. Both need the repository, so -offline is refused with a message.
  • Naming one usage does not move the others: if widgets 1.1.0 needs base ^2.1.0 and base is locked at 2.0.0, update widgets reports the conflict (… already resolved to 2.0.0) instead of silently moving base; update widgets base or update moves both — tested.
$ syspi outdated
sysmod 5.1.5 -> 5.1.6
$ syspi update
installed sysmod 5.1.6 (git 5.1.6 fe07bc1f…) -> lib/mbse4u-sysmod_5.1.6
sysmod 5.1.5 -> 5.1.6
removed lib/mbse4u-sysmod_5.1.5
11 package(s) locked: 1 installed, 1 already present, 9 not installed (standard libraries and local directories); .project.lock.json updated

Tests: internal/install/update_test.go (lock wins for install; outdated writes nothing; named vs all; prune of the old copy; refusals; new/dropped entries) and tests/e2e/update_test.go (git flow with -json, -offline refusal, nothing to move; the git/hg/svn fixtures). Docs: README "Commands" and the lock paragraph, docs/packages.md "Lock file", changes/unreleased/update.added.md.

Proved on a real project (MBSE4U/sysmod-sysmlv2 locked at 5.1.5 with constraint >=5.1.0 <5.1.8, Open-MBEE/OpenSysML-Extensions-Library@1.0.0): syspi install keeps 5.1.5, syspi outdated prints sysmod 5.1.5 -> 5.1.6, syspi update installs lib/mbse4u-sysmod_5.1.6 and removes lib/mbse4u-sysmod_5.1.5, OpenSysML sysml -validate on a model importing SYSMOD::* and OOSEM::* passes before and after. With ^5.1.0 the highest tag is 5.1.8, whose .project.json says 5.1.7; SysPI refuses it as it always has (the tag must equal the version) — an upstream defect, not a lax mode to add.

Link to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/888897f71c264c89a8abc11e9a432241
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/888897f71c264c89a8abc11e9a432241?variant=devin
Requested by: @HuiJun


🟢 Devin Review found nothing to fix · View findings · Follow Devin's work

Devin Review

devin-ai-integration Bot and others added 2 commits November 12, 2026 06:30
…t version their constraints allow; outdated reports what it would move

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review November 12, 2026 06:38
devin-ai-integration Bot and others added 2 commits November 12, 2026 06:42
…tdated and lock see the collision install refuses

Two packages that would install under one name with different contents were refused only when installing; the dry run of outdated and lock itself passed them.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…d tag

When update finds the locked version is the highest allowed but another tag names the same version, the locked tag is used rather than the other spelling, so the revision check cannot fail against an unchanged entry.

Co-Authored-By: jason.han <hanhuijun@gmail.com>

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

…helper

changes() used the resolver's lockKey; repositoryKey in update.go does the same so the branch does not depend on that helper's presence.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
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