Skip to content

Commit

Permalink
Remove src deps from test deps on --pedantic-packages report (#1092)
Browse files Browse the repository at this point in the history
Co-authored-by: Fabrizio Ferrai <fabrizio.ferrai@gmail.com>
  • Loading branch information
JordanMartinez and f-f authored Nov 6, 2023
1 parent c9fd17b commit 2f272e6
Show file tree
Hide file tree
Showing 14 changed files with 540 additions and 182 deletions.
142 changes: 80 additions & 62 deletions src/Spago/Purs/Graph.purs
Original file line number Diff line number Diff line change
Expand Up @@ -183,68 +183,86 @@ checkImports graph = do
packageGraph <- runSpago (Record.union { selected: NEA.singleton selected } env) $ getModuleGraphWithPackage graph

let
packageName = selected.package.name
testPackageName = unsafeCoerce (PackageName.print packageName <> ":test")

declaredDependencies = unwrap selected.package.dependencies
declaredTestDependencies = maybe Map.empty (unwrap <<< _.dependencies) selected.package.test

-- The direct dependencies specified in the config
dependencyPackages = Map.mapMaybe (const (Just Map.empty)) declaredDependencies
dependencyTestPackages = Map.mapMaybe (const (Just Map.empty)) $ Map.union declaredDependencies declaredTestDependencies

-- Compile the globs for the project, we get the set of source files in the project
projectGlob :: Set FilePath <- map Set.fromFoldable do
map Array.fold $ traverse compileGlob (Config.sourceGlob NoTestGlobs packageName (WorkspacePackage selected))

-- Same but for tests
projectTestsGlob :: Set FilePath <- map Set.fromFoldable do
map Array.fold $ traverse compileGlob (Config.sourceGlob OnlyTestGlobs packageName (WorkspacePackage selected))

let
-- Filter this improved graph to only have the project modules
projectGraph = Map.filterWithKey (\_ { path } -> Set.member path projectGlob) packageGraph
projectTestsGraph = Map.filterWithKey (\_ { path } -> Set.member path projectTestsGlob) packageGraph

-- Go through all the modules in the project graph, figure out which packages each module depends on,
-- accumulate all of that in a single place
accumulateImported importedPkgs' (Tuple moduleName { depends }) =
let
accumulateDep importedPkgs importedModule = case Map.lookup importedModule packageGraph of
Nothing -> importedPkgs
-- Skip dependencies on modules in the same package, we are not interested in that
Just { package } | package == packageName -> importedPkgs
Just { package } | package == testPackageName -> importedPkgs
Just { package: importedPackage } -> Map.alter
( case _ of
Nothing -> Just $ Map.singleton moduleName (Set.singleton importedModule)
Just p -> Just $ Map.alter
( case _ of
Nothing -> Just $ Set.singleton importedModule
Just set -> Just $ Set.insert importedModule set
)
moduleName
p
)
importedPackage
importedPkgs
in
foldl accumulateDep importedPkgs' depends

importedPackages :: ImportedPackages
importedPackages = foldl accumulateImported Map.empty (Map.toUnfoldable projectGraph :: Array _)
importedTestPackages = foldl accumulateImported Map.empty (Map.toUnfoldable projectTestsGraph :: Array _)

unused = Map.keys $ Map.difference dependencyPackages importedPackages
transitive = Map.difference importedPackages dependencyPackages
unusedTest =
if Set.isEmpty projectTestsGlob then Set.empty
else Map.keys $ Map.difference (Map.difference dependencyTestPackages dependencyPackages) importedTestPackages
transitiveTest =
if Set.isEmpty projectTestsGlob then Map.empty
else Map.difference importedTestPackages dependencyTestPackages

pure { unused, transitive, unusedTest, transitiveTest }
dropValues = Map.mapMaybe (const (Just Map.empty))
srcDeps = unwrap selected.package.dependencies
srcResult <- getUsedUnusedTransitiveFor
{ selected
, packageName: selected.package.name
, dependencyPackages: dropValues srcDeps
, isSrc: true
, packageGraph
}
let srcDepsUsed = Map.filterKeys (flip Map.member srcResult.used) srcDeps
testResult <- getUsedUnusedTransitiveFor
{ selected
, packageName: selected.package.name
, dependencyPackages:
dropValues
-- add the used source dependencies, not the declared ones.
$ Map.unionWith const srcDepsUsed
-- get test deps
$ maybe Map.empty (unwrap <<< _.dependencies) selected.package.test
, isSrc: false
, packageGraph
}

pure
{ unused: srcResult.unused
, transitive: srcResult.transitive
, unusedTest: Set.difference testResult.unused $ Map.keys srcResult.used
, transitiveTest: differenceAll testResult.transitive [ srcResult.used, srcResult.transitive ]
}
where
differenceAll sourceMap removalsArray = foldl Map.difference sourceMap removalsArray
getUsedUnusedTransitiveFor { selected, packageName, dependencyPackages, isSrc, packageGraph } = do
let
testPackageName = unsafeCoerce (PackageName.print packageName <> ":test")

testGlobOption
| isSrc = NoTestGlobs
| otherwise = OnlyTestGlobs

-- Compile the globs for the project, we get the set of source files in the project
glob :: Set FilePath <- map Set.fromFoldable do
map Array.fold $ traverse compileGlob (Config.sourceGlob testGlobOption packageName (WorkspacePackage selected))

let
-- Filter this improved graph to only have the project modules
projectGraph = Map.filterWithKey (\_ { path } -> Set.member path glob) packageGraph

-- Go through all the modules in the project graph, figure out which packages each module depends on,
-- accumulate all of that in a single place
accumulateImported importedPkgs' (Tuple moduleName { depends }) =
let
accumulateDep importedPkgs importedModule = case Map.lookup importedModule packageGraph of
Nothing -> importedPkgs
-- Skip dependencies on modules in the same package, we are not interested in that
Just { package } | package == packageName -> importedPkgs
Just { package } | package == testPackageName -> importedPkgs
Just { package: importedPackage } -> Map.alter
( case _ of
Nothing -> Just $ Map.singleton moduleName (Set.singleton importedModule)
Just p -> Just $ Map.alter
( case _ of
Nothing -> Just $ Set.singleton importedModule
Just set -> Just $ Set.insert importedModule set
)
moduleName
p
)
importedPackage
importedPkgs
in
foldl accumulateDep importedPkgs' depends

importedPackages :: ImportedPackages
importedPackages = foldl accumulateImported Map.empty (Map.toUnfoldable projectGraph :: Array _)

pure
{ used: if isSrc then Map.intersection dependencyPackages importedPackages else Map.empty
, unused: Map.keys $ Map.difference dependencyPackages importedPackages
, transitive: Map.difference importedPackages dependencyPackages
}

--------------------------------------------------------------------------------
-- Errors
Expand Down
28 changes: 0 additions & 28 deletions test-fixtures/check-direct-import-transitive-dependency.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Reading Spago workspace configuration...
Read the package set from the registry

βœ… Selecting package to build: pedantic

Downloading dependencies...
Building...
Src Lib All
Warnings 0 0 0
Errors 0 0 0

βœ… Build succeeded.

Looking for unused and undeclared transitive dependencies...

❌ Sources for package 'pedantic' import the following transitive dependencies - please add them to the project dependencies, or remove the imports:
maybe
from `Main`, which imports:
Data.Maybe


Run the following command to install them all:
spago install -p pedantic maybe


❌ Tests for package 'pedantic' import the following transitive dependencies - please add them to the project dependencies, or remove the imports:
control
from `Test.Main`, which imports:
Control.Alt


Run the following command to install them all:
spago install --test-deps -p pedantic control
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Reading Spago workspace configuration...
Read the package set from the registry

βœ… Selecting package to build: pedantic

Downloading dependencies...
Building...
Src Lib All
Warnings 0 0 0
Errors 0 0 0

βœ… Build succeeded.

Looking for unused and undeclared transitive dependencies...

❌ Tests for package 'pedantic' import the following transitive dependencies - please add them to the project dependencies, or remove the imports:
control
from `Test.Main`, which imports:
Control.Alt


Run the following command to install them all:
spago install --test-deps -p pedantic control
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Reading Spago workspace configuration...
Read the package set from the registry

βœ… Selecting package to build: pedantic

Downloading dependencies...
Building...
Src Lib All
Warnings 0 0 0
Errors 0 0 0

βœ… Build succeeded.

Looking for unused and undeclared transitive dependencies...

❌ Sources for package 'pedantic' import the following transitive dependencies - please add them to the project dependencies, or remove the imports:
control
from `Main`, which imports:
Control.Alt


Run the following command to install them all:
spago install -p pedantic control
43 changes: 43 additions & 0 deletions test-fixtures/pedantic/check-pedantic-packages.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Reading Spago workspace configuration...
Read the package set from the registry

βœ… Selecting package to build: pedantic

Downloading dependencies...
Building...
Src Lib All
Warnings 0 0 0
Errors 0 0 0

βœ… Build succeeded.

Looking for unused and undeclared transitive dependencies...

❌ Sources for package 'pedantic' declares unused dependencies - please remove them from the project config:
- console
- effect
- either


❌ Sources for package 'pedantic' import the following transitive dependencies - please add them to the project dependencies, or remove the imports:
newtype
from `Main`, which imports:
Data.Newtype


Run the following command to install them all:
spago install -p pedantic newtype


❌ Tests for package 'pedantic' declares unused dependencies - please remove them from the project config:
- tuples


❌ Tests for package 'pedantic' import the following transitive dependencies - please add them to the project dependencies, or remove the imports:
either
from `Test.Main`, which imports:
Data.Either


Run the following command to install them all:
spago install --test-deps -p pedantic either
31 changes: 31 additions & 0 deletions test-fixtures/pedantic/check-unused-dependency-in-source.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Reading Spago workspace configuration...
Read the package set from the registry

βœ… Selecting package to build: pedantic

Downloading dependencies...
Building...
Src Lib All
Warnings 0 0 0
Errors 0 0 0

βœ… Build succeeded.

Looking for unused and undeclared transitive dependencies...

❌ Sources for package 'pedantic' declares unused dependencies - please remove them from the project config:
- console
- effect


❌ Tests for package 'pedantic' import the following transitive dependencies - please add them to the project dependencies, or remove the imports:
console
from `Test.Main`, which imports:
Effect.Class.Console
effect
from `Test.Main`, which imports:
Effect


Run the following command to install them all:
spago install --test-deps -p pedantic console effect
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Reading Spago workspace configuration...
Read the package set from the registry

βœ… Selecting package to build: 7368613235362d2f444a2b4f56375435646a59726b53586548
βœ… Selecting package to build: pedantic

Downloading dependencies...
Building...
Expand All @@ -13,6 +13,6 @@ Errors 0 0 0

Looking for unused and undeclared transitive dependencies...

❌ Sources for package '7368613235362d2f444a2b4f56375435646a59726b53586548' declares unused dependencies - please remove them from the project config:
❌ Sources for package 'pedantic' declares unused dependencies - please remove them from the project config:
- console
- effect
23 changes: 23 additions & 0 deletions test-fixtures/pedantic/check-unused-source-and-test-dependency.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Reading Spago workspace configuration...
Read the package set from the registry

βœ… Selecting package to build: pedantic

Downloading dependencies...
Building...
Src Lib All
Warnings 0 0 0
Errors 0 0 0

βœ… Build succeeded.

Looking for unused and undeclared transitive dependencies...

❌ Sources for package 'pedantic' declares unused dependencies - please remove them from the project config:
- console
- effect


❌ Tests for package 'pedantic' declares unused dependencies - please remove them from the project config:
- console
- effect
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Reading Spago workspace configuration...
Read the package set from the registry

βœ… Selecting package to build: 7368613235362d2f444a2b4f56375435646a59726b53586548
βœ… Selecting package to build: pedantic

Downloading dependencies...
Building...
Expand All @@ -13,5 +13,5 @@ Errors 0 0 0

Looking for unused and undeclared transitive dependencies...

❌ Tests for package '7368613235362d2f444a2b4f56375435646a59726b53586548' declares unused dependencies - please remove them from the project config:
❌ Tests for package 'pedantic' declares unused dependencies - please remove them from the project config:
- newtype
Loading

0 comments on commit 2f272e6

Please sign in to comment.