Skip to content

Commit c2c4ffa

Browse files
Integrate Bun tactic into Node.js strategy
Wire up Bun lockfile support in the Node.js strategy: - Add Bun constructor to NodeProject ADT - Add bun.lock detection in identifyProjectType - Add Bun dispatch in getDeps - Add BunProjectType to discovery filter Detection order: Yarn -> NPM -> Pnpm -> Bun -> fallback NPM Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
1 parent 3f8dcbe commit c2c4ffa

1 file changed

Lines changed: 43 additions & 30 deletions

File tree

src/Strategy/Node.hs

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ import Path (
7474
(</>),
7575
)
7676
import Strategy.Node.Errors (CyclicPackageJson (CyclicPackageJson), MissingNodeLockFile (..), fossaNodeDocUrl, npmLockFileDocUrl, yarnLockfileDocUrl, yarnV2LockfileDocUrl)
77+
import Strategy.Node.Bun.BunLock qualified as BunLock
7778
import Strategy.Node.Npm.PackageLock qualified as PackageLock
7879
import Strategy.Node.Npm.PackageLockV3 qualified as PackageLockV3
7980
import Strategy.Node.PackageJson (
@@ -96,16 +97,16 @@ import Strategy.Node.Pnpm.Workspace (PnpmWorkspace (workspaceSpecs))
9697
import Strategy.Node.YarnV1.YarnLock qualified as V1
9798
import Strategy.Node.YarnV2.YarnLock qualified as V2
9899
import Types (
99-
DependencyResults (DependencyResults),
100-
DiscoveredProject (..),
101-
DiscoveredProjectType (NpmProjectType, PnpmProjectType, YarnProjectType),
102-
FoundTargets (ProjectWithoutTargets),
103-
GraphBreadth (Complete, Partial),
104-
License (License),
105-
LicenseResult (LicenseResult, licensesFound),
106-
LicenseType (LicenseURL, UnknownType),
107-
licenseFile,
108-
)
100+
DependencyResults (DependencyResults),
101+
DiscoveredProject (..),
102+
DiscoveredProjectType (BunProjectType, NpmProjectType, PnpmProjectType, YarnProjectType),
103+
FoundTargets (ProjectWithoutTargets),
104+
GraphBreadth (Complete, Partial),
105+
License (License),
106+
LicenseResult (LicenseResult, licensesFound),
107+
LicenseType (LicenseURL, UnknownType),
108+
licenseFile,
109+
)
109110

110111
skipJsFolders :: WalkStep
111112
skipJsFolders = WalkSkipSome ["node_modules", "bower_components", ".yarn"]
@@ -118,7 +119,7 @@ discover ::
118119
) =>
119120
Path Abs Dir ->
120121
m [DiscoveredProject NodeProject]
121-
discover dir = withMultiToolFilter [YarnProjectType, NpmProjectType, PnpmProjectType] $
122+
discover dir = withMultiToolFilter [YarnProjectType, NpmProjectType, PnpmProjectType, BunProjectType] $
122123
context "NodeJS" $ do
123124
manifestList <- context "Finding nodejs/pnpm projects" $ collectManifests dir
124125
manifestMap <- context "Reading manifest files" $ (Map.fromList . catMaybes) <$> traverse loadPackage manifestList
@@ -147,6 +148,7 @@ mkProject project = do
147148
NPMLock _ g -> (g, NpmProjectType)
148149
NPM g -> (g, NpmProjectType)
149150
Pnpm _ g -> (g, PnpmProjectType)
151+
Bun _ g -> (g, BunProjectType)
150152
Manifest rootManifest <- fromEitherShow $ findWorkspaceRootManifest graph
151153
pure $
152154
DiscoveredProject
@@ -172,12 +174,18 @@ getDeps ::
172174
getDeps (Yarn yarnLockFile graph) = analyzeYarn yarnLockFile graph
173175
getDeps (NPMLock packageLockFile graph) = analyzeNpmLock packageLockFile graph
174176
getDeps (Pnpm pnpmLockFile _) = analyzePnpmLock pnpmLockFile
177+
getDeps (Bun bunLockFile _) = analyzeBunLock bunLockFile
175178
getDeps (NPM graph) = analyzeNpm graph
176179

177180
analyzePnpmLock :: (Has Diagnostics sig m, Has ReadFS sig m, Has Logger sig m) => Manifest -> m DependencyResults
178181
analyzePnpmLock (Manifest pnpmLockFile) = do
179-
result <- PnpmLock.analyze pnpmLockFile
180-
pure $ DependencyResults result Complete [pnpmLockFile]
182+
result <- PnpmLock.analyze pnpmLockFile
183+
pure $ DependencyResults result Complete [pnpmLockFile]
184+
185+
analyzeBunLock :: (Has Diagnostics sig m, Has ReadFS sig m) => Manifest -> m DependencyResults
186+
analyzeBunLock (Manifest bunLockFile) = do
187+
result <- BunLock.analyze bunLockFile
188+
pure $ DependencyResults result Complete [bunLockFile]
181189

182190
analyzeNpmLock :: (Has Diagnostics sig m, Has ReadFS sig m) => Manifest -> PkgJsonGraph -> m DependencyResults
183191
analyzeNpmLock (Manifest npmLockFile) graph = do
@@ -364,25 +372,29 @@ identifyProjectType ::
364372
PkgJsonGraph ->
365373
m NodeProject
366374
identifyProjectType graph = do
367-
Manifest manifest <- fromEitherShow $ findWorkspaceRootManifest graph
368-
let yarnFilePath = parent manifest Path.</> $(mkRelFile "yarn.lock")
369-
packageLockPath = parent manifest Path.</> $(mkRelFile "package-lock.json")
370-
pnpmLockPath = parent manifest Path.</> $(mkRelFile "pnpm-lock.yaml")
371-
yarnExists <- doesFileExist yarnFilePath
372-
pkgLockExists <- doesFileExist packageLockPath
373-
pnpmLockExists <- doesFileExist pnpmLockPath
374-
pure $ case (yarnExists, pkgLockExists, pnpmLockExists) of
375-
(True, _, _) -> Yarn (Manifest yarnFilePath) graph
376-
(_, True, _) -> NPMLock (Manifest packageLockPath) graph
377-
(_, _, True) -> Pnpm (Manifest pnpmLockPath) graph
378-
_ -> NPM graph
375+
Manifest manifest <- fromEitherShow $ findWorkspaceRootManifest graph
376+
let yarnFilePath = parent manifest Path.</> $(mkRelFile "yarn.lock")
377+
packageLockPath = parent manifest Path.</> $(mkRelFile "package-lock.json")
378+
pnpmLockPath = parent manifest Path.</> $(mkRelFile "pnpm-lock.yaml")
379+
bunLockPath = parent manifest Path.</> $(mkRelFile "bun.lock")
380+
yarnExists <- doesFileExist yarnFilePath
381+
pkgLockExists <- doesFileExist packageLockPath
382+
pnpmLockExists <- doesFileExist pnpmLockPath
383+
bunLockExists <- doesFileExist bunLockPath
384+
pure $ case (yarnExists, pkgLockExists, pnpmLockExists, bunLockExists) of
385+
(True, _, _, _) -> Yarn (Manifest yarnFilePath) graph
386+
(_, True, _, _) -> NPMLock (Manifest packageLockPath) graph
387+
(_, _, True, _) -> Pnpm (Manifest pnpmLockPath) graph
388+
(_, _, _, True) -> Bun (Manifest bunLockPath) graph
389+
_ -> NPM graph
379390

380391
data NodeProject
381-
= Yarn Manifest PkgJsonGraph
382-
| NPMLock Manifest PkgJsonGraph
383-
| NPM PkgJsonGraph
384-
| Pnpm Manifest PkgJsonGraph
385-
deriving (Eq, Ord, Show, Generic)
392+
= Yarn Manifest PkgJsonGraph
393+
| NPMLock Manifest PkgJsonGraph
394+
| NPM PkgJsonGraph
395+
| Pnpm Manifest PkgJsonGraph
396+
| Bun Manifest PkgJsonGraph
397+
deriving (Eq, Ord, Show, Generic)
386398

387399
instance LicenseAnalyzeProject NodeProject where
388400
licenseAnalyzeProject = pure . analyzeLicenses . pkgGraph
@@ -414,6 +426,7 @@ pkgGraph (Yarn _ pjg) = pjg
414426
pkgGraph (NPMLock _ pjg) = pjg
415427
pkgGraph (NPM pjg) = pjg
416428
pkgGraph (Pnpm _ pjg) = pjg
429+
pkgGraph (Bun _ pjg) = pjg
417430

418431
findWorkspaceRootManifest :: PkgJsonGraph -> Either String Manifest
419432
findWorkspaceRootManifest PkgJsonGraph{jsonGraph} =

0 commit comments

Comments
 (0)