chore(setup): add SDK installer library - #750
Conversation
536ddf1 to
fb2c630
Compare
| func fileContains(path, substr string) bool { | ||
| b, err := os.ReadFile(path) | ||
| return err == nil && strings.Contains(string(b), substr) | ||
| } |
There was a problem hiding this comment.
Substring match skips SDK install
Medium Severity
IsInstalled treats any manifest substring match as proof the SDK is present. Related packages such as @launchdarkly/node-server-sdk-redis contain @launchdarkly/node-server-sdk as a prefix, so setup can skip installing the real SDK when only an integration package is listed.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit fb2c630. Configure here.
| return []string{"gem", "install", pkg}, pkg | ||
| case "dotnet-server-sdk": | ||
| pkg = "LaunchDarkly.ServerSdk" | ||
| return []string{"dotnet", "add", "package", pkg}, pkg |
There was a problem hiding this comment.
Dotnet install breaks on solutions
High Severity
Detection accepts a root .sln with no adjacent .csproj, but install always runs dotnet add package without a project path and only looks for *.csproj in the root. Typical solution layouts therefore fail install even though detection succeeds.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit fb2c630. Configure here.
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>
fb2c630 to
1f13de3
Compare
There was a problem hiding this comment.
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).
❌ 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"} |
There was a problem hiding this comment.
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.
Reviewed by Cursor Bugbot for commit 1f13de3. Configure here.


Describe the solution you've provided
Second layer of the guided
setupcommand: the SDK installer. Given a detection result, installs the SDK via the project's package manager (Installerinterface,PackageInstaller,InstallArgs,IsInstalled), and flags SDKs that require manual install.Builds on the detection library (
DetectResult).Related issues
Part of the
setup-ldfeature. Stacked PR — base isffantl/setup-ld/1-detector.Requirements
Note
Medium Risk
Runs real package-manager commands in the user’s project directory (mutable dependency files), though behavior is bounded by SDK ID mapping and is covered by tests via a stubbed runner.
Overview
Adds the guided setup install layer: given a
DetectResult, it installs the matching LaunchDarkly SDK via the project’s package manager (or reports that manual steps are required).PackageInstallerimplementsInstallerby resolving install commands withInstallArgs(Node npm/yarn/pnpm/bun, Python pip/poetry/uv/pipenv,go get, Rubygemvsbundle add,dotnet add package) and running them in the target directory via an injectablerunhook (defaults toexec).IsInstalledscans common manifests (package.json,go.mod,pyproject.toml,Gemfile,*.csproj, etc.) and skips the command when the dependency is already present.Manual-install SDKs (Java, Android, Swift/iOS) return
Success: falsewithout error and a package coordinate for the wizard; unknown SDK IDs error instead of no-op. AStubInstallerremains for callers not wired yet.installer_test.gocovers command selection, install/skip/failure paths, and manual/unknown behavior.Reviewed by Cursor Bugbot for commit 1f13de3. Bugbot is set up for automated code reviews on this repo. Configure here.