Skip to content

chore(setup): add SDK installer library - #750

Open
ffantl-ld wants to merge 3 commits into
ffantl/setup-ld/1-detectorfrom
ffantl/setup-ld/2-installer
Open

chore(setup): add SDK installer library#750
ffantl-ld wants to merge 3 commits into
ffantl/setup-ld/1-detectorfrom
ffantl/setup-ld/2-installer

Conversation

@ffantl-ld

@ffantl-ld ffantl-ld commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Describe the solution you've provided

Second layer of the guided setup command: the SDK installer. Given a detection result, installs the SDK via the project's package manager (Installer interface, PackageInstaller, InstallArgs, IsInstalled), and flags SDKs that require manual install.

Builds on the detection library (DetectResult).

Related issues

Part of the setup-ld feature. Stacked PR — base is ffantl/setup-ld/1-detector.

Requirements

  • I have added test coverage for new or changed functionality

Note

Medium Risk
Runs real package-manager commands via exec on user projects; incorrect install targeting or false IsInstalled positives could skip needed SDK installs or modify the wrong .NET project.

Overview
Adds internal/setup installer layer for the guided setup flow: given a DetectResult, it can install the matching LaunchDarkly SDK via the project’s package manager or surface manual-install guidance.

PackageInstaller implements Installer by mapping SDK IDs to install commands (InstallArgs) for Node (npm/yarn/pnpm/bun), Python (pip/poetry/uv/pipenv), Go, Ruby (bundle add when Bundler is detected), and .NET. Java, Android, and Swift/iOS return package coordinates with Success=false and no error via RequiresManualInstall; unknown SDK IDs error.

Before running a command, IsInstalled scans manifests (and nested .csproj files) using boundary-aware mentionsPackage matching so related packages (e.g. *-redis) are not treated as the core SDK. .NET installs add --project when needed, or return Failed with FailureReason when there are zero or multiple projects.

Includes broad unit tests for command selection, install outcomes, and edge cases.

Reviewed by Cursor Bugbot for commit 45e5847. Bugbot is set up for automated code reviews on this repo. Configure here.

@ffantl-ld
ffantl-ld marked this pull request as ready for review July 27, 2026 17:23
@ffantl-ld
ffantl-ld requested review from Vadman97 and erangeles July 27, 2026 17:23
Comment thread internal/setup/installer.go
Comment thread internal/setup/installer.go
Comment thread internal/setup/installer.go Outdated
@ffantl-ld
ffantl-ld requested review from a team and removed request for Vadman97 July 28, 2026 16:37
@ffantl-ld
ffantl-ld force-pushed the ffantl/setup-ld/2-installer branch from 536ddf1 to fb2c630 Compare July 31, 2026 17:47
Comment thread internal/setup/installer.go
Comment thread internal/setup/installer.go
@ffantl-ld
ffantl-ld force-pushed the ffantl/setup-ld/2-installer branch from fb2c630 to 1f13de3 Compare July 31, 2026 18:25

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1f13de3. Configure here.

case "python-server-sdk":
manifests = []string{"requirements.txt", "pyproject.toml", "setup.py", "Pipfile", "uv.lock"}
case "ruby-server-sdk":
manifests = []string{"Gemfile", "Gemfile.lock"}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Lockfiles fake installed status

Low Severity

IsInstalled treats go.sum, Gemfile.lock, and uv.lock as proof the SDK is a project dependency. Those lockfiles can retain package names after removal from go.mod / Gemfile / pyproject.toml, or list transitive-only hits, so setup can set AlreadyInstalled and skip adding a direct dependency the app still needs. Node correctly checks only package.json.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1f13de3. Configure here.

@ffantl-ld
ffantl-ld force-pushed the ffantl/setup-ld/2-installer branch from 1f13de3 to 220b32e Compare August 3, 2026 18:52
ffantl-ld and others added 3 commits August 3, 2026 15:45
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`gem install` left the Gemfile untouched, so the SDK stayed unavailable under
bundler and IsInstalled kept returning false. Use `bundle add` when the project
is Bundler-managed, and poetry, uv or pipenv when one of those manages the
Python dependencies.

Unrecognised package managers fall back to pip rather than being run as a
command, since the value reaches InstallArgs from the detector.

InstallArgs added launchdarkly-react-native-client-sdk, which npm marks
deprecated in favour of @launchdarkly/react-native-client-sdk. The unscoped
launchdarkly-js-client-sdk is the v3 package whose initialize API the init
template uses; the scoped one is v4 and exposes createClient.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
IsInstalled tested for its package name as a substring, so
@launchdarkly/node-server-sdk-redis, launchdarkly-server-sdk-otel, and
LaunchDarkly.ServerSdk.Telemetry each counted as the SDK itself and the real
install was skipped. Require a non-name character on both sides, which every
manifest format supplies.

Detection accepts a solution with no project file beside it, but install ran a
bare `dotnet add package`, which needs the working directory to hold exactly
one project. Resolve the project the solution refers to and pass --project;
with none or several, stop and say so rather than adding the SDK to an
arbitrary assembly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ffantl-ld
ffantl-ld force-pushed the ffantl/setup-ld/2-installer branch from 220b32e to 45e5847 Compare August 3, 2026 19:48
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.

2 participants