Skip to content

API: Add getVersion method to EnvironmentManager - #1923

Merged
Eduardo Villalpando Mello (edvilme) merged 4 commits into
mainfrom
api-2-env-manager-version
Oct 12, 2026
Merged

Eduardo Villalpando Mello (edvilme) merged 4 commits into
mainfrom
api-2-env-manager-version

Conversation

@edvilme

Copy link
Copy Markdown
Contributor

Contributes to #1837
As part of the efforts to streamline the API and simplify feature detection (#1874), environment managers should have a mechanism to advertise their versions. PackageManager's already do this with a async getVersion() method.

@edvilme
Eduardo Villalpando Mello (edvilme) marked this pull request as ready for review October 9, 2026 22:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Configured Conda paths and git-checkout pyenv versions are mishandled, and required API release artifacts are missing.

3 open findings
What changed in this PR

Adds optional environment-manager version reporting to support API 2.0 capability detection.

Changes:

  • Adds EnvironmentManager.getVersion().
  • Implements version retrieval for Conda, Pipenv, Poetry, and pyenv.
  • Adds parsing and delegation tests.
File Description
src/​types.ts Defines the optional API method.
src/​managers/​common/​registeredManagers.ts Delegates version retrieval.
src/​managers/​conda/​condaEnvManager.ts Reports Conda versions.
src/​managers/​pipenv/​pipenvManager.ts Reports Pipenv versions.
src/​managers/​pipenv/​pipenvUtils.ts Parses Pipenv output.
src/​managers/​poetry/​poetryManager.ts Reports Poetry versions.
src/​managers/​pyenv/​pyenvManager.ts Reports pyenv versions.
src/​managers/​pyenv/​pyenvUtils.ts Parses pyenv output.
src/​test/​features/​envManagers.unit.test.ts Tests delegation and fallback.
src/​test/​managers/​pipenv/​pipenvUtils.getPipenv.unit.test.ts Tests Pipenv parsing.
src/​test/​managers/​pyenv/​pyenvUtils.unit.test.ts Tests pyenv parsing.
Files not reviewed (1)
  • api/package-lock.json: Generated file

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/types.ts
Comment thread src/managers/conda/condaEnvManager.ts
Comment thread src/managers/pyenv/pyenvUtils.ts Outdated
@heejaechang

Heejae Chang (heejaechang) commented Oct 9, 2026 •

Copy link
Copy Markdown

🔒 Automated review in progress — Heejae Chang (@heejaechang) is auto-reviewing this PR.

@heejaechang

Copy link
Copy Markdown

Result: ⚠️ partially-verified

Verification details

Verification: Isolated verification observed failures that were not classified as caused by this PR: Dependency and test discovery. The relevant tests could not be fully run in the isolated environment; this review is not fully verified.

Summary: Test compilation passed, and 76 targeted Mocha tests passed, including all eight tests added by the PR. Fifteen supplemental checks passed for built-in managers’ version parsing, unavailable tools, command failures, and unparseable output. Offline dependency installation succeeded; discovery exited unsuccessfully because the container lacks Git metadata, not because of changed code. Verification is partial because API package-artifact tests and real-tool integration were not run.

Test runs: 5 passed, 1 failed, 1 not run

  • ⚠️ Not run | API package-artifact tests | npm run test:package
  • ❌ Failed | unrelated to this PR | Dependency and test discovery | printf 'AUTOMATION_SANDBOX_PROFILE=%s\n' "$AUTOMATION_SANDBOX_PROFILE"; node --version; npm --version; test ! -d node_modules || printf 'node_modules exists\n'; node -e 'const p=require("./package.json"); console.log(JSON.stringify({scripts:p.scripts,devDependencies:p.devDependencies},null,2))'; ls -a build; git status --short; git log -1 --oneline
  • ✅ Passed | Version API and changed utility tests | node ./node_modules/mocha/bin/mocha.js --no-config --require source-map-support/register --require ./out/test/unittests.js --ui tdd --timeout 180000 out/test/features/envManagers.unit.test.js out/test/managers/conda/commands.unit.test.js out/test/managers/pipenv/pipenvUtils.getPipenv.unit.test.js out/test/managers/pyenv/pyenvUtils.unit.test.js out/test/managers/poetry/commands.unit.test.js
  • ✅ Passed | Manager resolution, package operations, and API regressions | node ./node_modules/mocha/bin/mocha.js --no-config --require source-map-support/register --require ./out/test/unittests.js --ui tdd --timeout 180000 out/test/managers/conda/condaUtils.getConda.unit.test.js out/test/managers/conda/condaUtils.toolExecution.unit.test.js out/test/managers/conda/condaPackageManager.unit.test.js out/test/managers/poetry/poetryUtils.getPoetry.unit.test.js out/test/managers/poetry/poetryPackageManager.unit.test.js out/test/extensionApi.unit.test.js
  • ✅ Passed | Offline dependency preparation | npm ci --offline --ignore-scripts
  • ✅ Passed | TypeScript test compilation | npm run compile-tests
  • ✅ Passed | Built-in manager getVersion supplemental checks | node <<'NODE'
    require('./out/test/unittests.js');
    const assert = require('node:assert/strict');
    const sinon = require('sinon');
    const cases = [
    ['pipenv', 'PipenvManager', 'pipenvManager', 'getPipenv', 'pipenv, version 2024.4.1\n', '2024.4.1'],
    ['pyenv', 'PyEnvManager', 'pyenvManager', 'getPyenv', 'pyenv 2.3.24-19-gabcdef1\n', '2.3.24'],
    ['poetry', 'PoetryManager', 'poetryManager', 'getPoetry', 'Poetry (version 2.1.1)\n', '2.1.1'],
    ];
    (async () => {
    const cp = require('./out/common/childProcess.apis');
    for (const [area, cls, file, getter, output, expected] of cases) {
    const utils = require(./out/managers/${area}/${area}Utils);
    const Manager = require(./out/managers/${area}/${file})[cls];
    const manager = new Manager({}, {});
    try {
    const tool = /custom tools/${area};
    const getTool = sinon.stub(utils, getter).resolves(tool);
    const exec = sinon.stub(cp, 'execProcess').resolves({ stdout: output, stderr: '' });
    assert.equal((await manager.getVersion()).public, expected);
    assert.equal(exec.firstCall.args[0], &quot;${tool}&quot; --version);
    console.log(PASS ${area}: configured tool and parsed PEP 440 result);
    getTool.resolves(undefined);
    exec.resetHistory();
    assert.equal(await manager.getVersion(), undefined);
    assert.equal(exec.callCount, 0);
    console.log(PASS ${area}: unavailable tool returns undefined without execution);
    getTool.resolves(tool);
    exec.rejects(new Error('Command not found'));
    assert.equal(await manager.getVersion(), undefined);
    console.log(PASS ${area}: command failure returns undefined);
    exec.resolves({ stdout: 'unexpected version output\n', stderr: '' });
    assert.equal(await manager.getVersion(), undefined);
    console.log(PASS ${area}: unparseable output returns undefined);
    } finally {
    manager.dispose();
    sinon.restore();
    }
    }
    const utils = require('./out/managers/conda/condaUtils');
    const { CondaEnvManager } = require('./out/managers/conda/condaEnvManager');
    const manager = new CondaEnvManager({}, {}, { info() {}, error() {} });
    try {
    const run = sinon.stub(utils, 'runConda').resolves('conda 24.1.2\n');
    assert.equal((await manager.getVersion()).public, '24.1.2');
    assert.deepEqual(run.firstCall.args[0], ['--version']);
    assert.equal(run.firstCall.args[1], manager.log);
    console.log('PASS conda: delegates version command with logger');
    run.rejects(new Error('Conda not found'));
    assert.equal(await manager.getVersion(), undefined);
    console.log('PASS conda: command failure returns undefined');
    run.resolves('unexpected version output\n');
    assert.equal(await manager.getVersion(), undefined);
    console.log('PASS conda: unparseable output returns undefined');
    } finally {
    manager.dispose();
    sinon.restore();
    }
    console.log('15 manager-level checks passed');
    })().catch(error => { console.error(error); process.exitCode = 1; });
    NODE
⚠️ API package-artifact tests diagnostic output
Not attempted within the six-command verification budget; API package build artifacts were not prepared.
❌ Dependency and test discovery diagnostic output
AUTOMATION_SANDBOX_PROFILE=typescript
v22.21.1
10.9.4
Scripts identify compile-tests and the Mocha unit-test configuration.
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
[container exit=128]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Approved via Review Center.

@heejaechang Heejae Chang (heejaechang) added the review-auto:approved Automated review: no blocking findings (approval posted). label Oct 9, 2026
@edvilme
Eduardo Villalpando Mello (edvilme) merged commit f6aec34 into main Oct 12, 2026
110 of 111 checks passed
@edvilme
Eduardo Villalpando Mello (edvilme) deleted the api-2-env-manager-version branch October 12, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

debt Code quality issues review-auto:approved Automated review: no blocking findings (approval posted).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants