Skip to content

Commit 456be94

Browse files
authored
Refactor the graph functionality to remove the custom module name parser (#773)
1 parent 5042ae2 commit 456be94

File tree

14 files changed

+196
-442
lines changed

14 files changed

+196
-442
lines changed

app/Spago.hs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import qualified Spago.Version
1919
import qualified Spago.Command.Ls as Ls
2020
import qualified Spago.Command.Path as Path
2121
import qualified Spago.Command.Verify as Verify
22+
import qualified Spago.Command.Init as Init
2223

2324

2425
main :: IO ()
@@ -45,7 +46,7 @@ main = withUtf8 $ do
4546

4647
-- ### Commands that need only a basic global env
4748
Init force noComments tag
48-
-> void $ Spago.Packages.initProject force noComments tag
49+
-> void $ Init.initProject force noComments tag
4950
Freeze
5051
-> Spago.PackageSet.freeze Spago.PackageSet.packagesPath
5152
Version
@@ -88,16 +89,19 @@ main = withUtf8 $ do
8889
$ Verify.verify checkUniqueModules Nothing
8990

9091
-- ### Commands that need a build environment: a config, build options and access to purs
91-
Build buildOptions -> Run.withBuildEnv globalUsePsa
92-
$ Spago.Build.build buildOptions Nothing
93-
Search -> Run.withBuildEnv globalUsePsa
92+
Build buildOptions -> Run.withBuildEnv globalUsePsa buildOptions
93+
$ Spago.Build.build Nothing
94+
Search -> Run.withBuildEnv globalUsePsa defaultBuildOptions
9495
$ Spago.Build.search
95-
Docs format sourcePaths depsOnly noSearch openDocs -> Run.withBuildEnv globalUsePsa
96-
$ Spago.Build.docs format sourcePaths depsOnly noSearch openDocs
97-
Test modName buildOptions nodeArgs -> Run.withBuildEnv globalUsePsa
98-
$ Spago.Build.test modName buildOptions nodeArgs
99-
Run modName buildOptions nodeArgs -> Run.withBuildEnv globalUsePsa
100-
$ Spago.Build.run modName buildOptions nodeArgs
96+
Docs format sourcePaths depsOnly noSearch openDocs ->
97+
let
98+
opts = defaultBuildOptions { depsOnly = depsOnly, sourcePaths = sourcePaths }
99+
in Run.withBuildEnv globalUsePsa opts
100+
$ Spago.Build.docs format noSearch openDocs
101+
Test modName buildOptions nodeArgs -> Run.withBuildEnv globalUsePsa buildOptions
102+
$ Spago.Build.test modName nodeArgs
103+
Run modName buildOptions nodeArgs -> Run.withBuildEnv globalUsePsa buildOptions
104+
$ Spago.Build.run modName nodeArgs
101105

102106
-- ### Legacy commands, here for smoother migration path to new ones
103107
Bundle -> die [ display Messages.bundleCommandRenamed ]

package.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,11 @@ library:
9898
- dhall >= 1.38.0
9999
- directory >= 1.3.4.0
100100
- either
101-
- exceptions
102101
- file-embed
103102
- filepath
104103
- foldl
105104
- fsnotify
106105
- generic-lens
107-
- github
108106
- Glob
109107
- http-types
110108
- http-client
@@ -134,7 +132,6 @@ library:
134132
- unliftio
135133
- unordered-containers
136134
- utf8-string
137-
- vector
138135
- versions
139136
- with-utf8
140137
- zlib
@@ -163,6 +160,7 @@ executables:
163160
- -rtsopts
164161
- -with-rtsopts=-N
165162
dependencies:
163+
- ansi-terminal
166164
- base >= 4.7 && < 5
167165
- spago
168166
- text < 1.3

spago.cabal

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ cabal-version: 1.12
44
--
55
-- see: https://github.com/sol/hpack
66
--
7-
-- hash: ab7469432b7c2f686c6414d0dae5b3cd0c8204f64bdd993199ec586d21964698
7+
-- hash: 77b5d785b2feb191ce5732a72494d5d950758a3c9dd77a3c98827bf19c3bafa3
88

99
name: spago
1010
version: 0.20.0
@@ -43,8 +43,8 @@ library
4343
Spago.Async
4444
Spago.Bower
4545
Spago.Build
46-
Spago.Build.Parser
4746
Spago.CLI
47+
Spago.Command.Init
4848
Spago.Command.Ls
4949
Spago.Command.Path
5050
Spago.Command.Verify
@@ -89,13 +89,11 @@ library
8989
, dhall >=1.38.0
9090
, directory >=1.3.4.0
9191
, either
92-
, exceptions
9392
, file-embed
9493
, filepath
9594
, foldl
9695
, fsnotify
9796
, generic-lens
98-
, github
9997
, http-client
10098
, http-conduit
10199
, http-types
@@ -124,7 +122,6 @@ library
124122
, unliftio
125123
, unordered-containers
126124
, utf8-string
127-
, vector
128125
, versions
129126
, with-utf8
130127
, zlib
@@ -158,7 +155,6 @@ test-suite spec
158155
main-is: Main.hs
159156
other-modules:
160157
BumpVersionSpec
161-
Spago.Build.ParserSpec
162158
Spago.PursSpec
163159
SpagoSpec
164160
Spec

src/Spago/Build.hs

Lines changed: 35 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import qualified Data.List.NonEmpty as NonEmpty
1818
import qualified Data.Map as Map
1919
import qualified Data.Set as Set
2020
import qualified Data.Text as Text
21-
import qualified Data.Versions as Version
2221
import System.Directory (getCurrentDirectory)
2322
import System.FilePath (splitDirectories)
2423
import qualified System.FilePath.Glob as Glob
@@ -29,7 +28,6 @@ import qualified Turtle
2928
import qualified System.Process as Process
3029
import qualified Web.Browser as Browser
3130

32-
import qualified Spago.Build.Parser as Parse
3331
import qualified Spago.Command.Path as Path
3432
import qualified Spago.RunEnv as Run
3533
import qualified Spago.Config as Config
@@ -51,31 +49,19 @@ prepareBundleDefaults maybeModuleName maybeTargetPath = (moduleName, targetPath)
5149
targetPath = fromMaybe (TargetPath "index.js") maybeTargetPath
5250

5351
-- eventually running some other action after the build
54-
build
55-
:: HasBuildEnv env
56-
=> BuildOptions -> Maybe (RIO Env ())
57-
-> RIO env ()
58-
build BuildOptions{..} maybePostBuild = do
52+
build :: HasBuildEnv env => Maybe (RIO Env ()) -> RIO env ()
53+
build maybePostBuild = do
5954
logDebug "Running `spago build`"
55+
BuildOptions{..} <- view (the @BuildOptions)
6056
Config{..} <- view (the @Config)
61-
PursCmd { compilerVersion } <- view (the @PursCmd)
6257
deps <- Packages.getProjectDeps
63-
case noInstall of
64-
DoInstall -> Fetch.fetchPackages deps
65-
NoInstall -> pure ()
6658
let partitionedGlobs@(Packages.Globs{..}) = Packages.getGlobs deps depsOnly configSourcePaths
6759
allPsGlobs = Packages.getGlobsSourcePaths partitionedGlobs <> sourcePaths
6860
allJsGlobs = Packages.getJsGlobs deps depsOnly configSourcePaths <> sourcePaths
6961

70-
checkImports globs = do
71-
minVersion <- case Version.semver "0.14.0" of
72-
Left _ -> die [ "Unable to parse min version for imports check" ]
73-
Right minVersion -> pure minVersion
74-
when (compilerVersion >= minVersion) $ do
75-
graph <- Purs.graph globs
76-
case graph of
77-
Left err -> logWarn $ displayShow err
78-
Right (Purs.ModuleGraph moduleGraph) -> do
62+
checkImports = do
63+
maybeGraph <- view (the @Graph)
64+
for_ maybeGraph $ \(Purs.ModuleGraph moduleGraph) -> do
7965
let
8066
matchesGlob :: Sys.FilePath -> SourcePath -> Bool
8167
matchesGlob path sourcePath =
@@ -88,11 +74,11 @@ build BuildOptions{..} maybePostBuild = do
8874
projectModules :: [ModuleName]
8975
projectModules =
9076
map fst
91-
$ filter (\(_, Purs.ModuleGraphNode{..}) -> isProjectFile (Text.unpack path))
77+
$ filter (\(_, Purs.ModuleGraphNode{..}) -> isProjectFile (Text.unpack graphNodePath))
9278
$ Map.toList moduleGraph
9379

9480
getImports :: ModuleName -> Set ModuleName
95-
getImports = maybe Set.empty (Set.fromList . Purs.depends) . flip Map.lookup moduleGraph
81+
getImports = maybe Set.empty (Set.fromList . graphNodeDepends) . flip Map.lookup moduleGraph
9682

9783
-- All package modules that are imported from our project files
9884
importedPackageModules :: Set ModuleName
@@ -113,7 +99,7 @@ build BuildOptions{..} maybePostBuild = do
11399
importedPackages :: Set PackageName
114100
importedPackages =
115101
Set.fromList
116-
$ mapMaybe (getPackageFromPath . Purs.path <=< flip Map.lookup moduleGraph)
102+
$ mapMaybe (getPackageFromPath . graphNodePath <=< flip Map.lookup moduleGraph)
117103
$ Set.toList importedPackageModules
118104

119105
dependencyPackages :: Set PackageName
@@ -157,7 +143,7 @@ build BuildOptions{..} maybePostBuild = do
157143
shell backendCmd empty >>= \case
158144
ExitSuccess -> pure ()
159145
ExitFailure n -> die [ "Backend " <> displayShow backend <> " exited with error:" <> repr n ]
160-
checkImports globs
146+
checkImports
161147

162148
buildAction globs = do
163149
env <- Run.getEnv
@@ -254,38 +240,29 @@ repl newPackages sourcePaths pursArgs depsOnly = do
254240

255241
-- | Test the project: compile and run "Test.Main"
256242
-- (or the provided module name) with node
257-
test
258-
:: HasBuildEnv env
259-
=> Maybe ModuleName -> BuildOptions -> [BackendArg]
260-
-> RIO env ()
261-
test maybeModuleName buildOpts extraArgs = do
243+
test :: HasBuildEnv env => Maybe ModuleName -> [BackendArg] -> RIO env ()
244+
test maybeModuleName extraArgs = do
262245
let moduleName = fromMaybe (ModuleName "Test.Main") maybeModuleName
263-
Config.Config { alternateBackend, configSourcePaths } <- view (the @Config)
264-
liftIO (foldMapM (Glob.glob . Text.unpack . unSourcePath) configSourcePaths) >>= \paths -> do
265-
results <- forM paths $ \path -> do
266-
content <- readFileBinary path
267-
pure $ Parse.checkModuleNameMatches (encodeUtf8 $ unModuleName moduleName) content
268-
if or results
269-
then do
246+
Config.Config { alternateBackend } <- view (the @Config)
247+
maybeGraph <- view (the @Graph)
248+
-- We check if the test module is included in the build and spit out a nice error if it isn't (see #383)
249+
for_ maybeGraph $ \(ModuleGraph moduleMap) -> case Map.lookup moduleName moduleMap of
250+
Nothing -> die [ "Module '" <> (display . unModuleName) moduleName <> "' not found! Are you including it in your build?" ]
251+
Just _ -> do
270252
sourceDir <- Turtle.pwd
271253
let dirs = RunDirectories sourceDir sourceDir
272-
runBackend alternateBackend dirs moduleName (Just "Tests succeeded.") "Tests failed: " buildOpts extraArgs
273-
else do
274-
die [ "Module '" <> (display . unModuleName) moduleName <> "' not found! Are you including it in your build?" ]
254+
runBackend alternateBackend dirs moduleName (Just "Tests succeeded.") "Tests failed: " extraArgs
275255

276256

277257
-- | Run the project: compile and run "Main"
278258
-- (or the provided module name) with node
279-
run
280-
:: HasBuildEnv env
281-
=> Maybe ModuleName -> BuildOptions -> [BackendArg]
282-
-> RIO env ()
283-
run maybeModuleName buildOpts extraArgs = do
259+
run :: HasBuildEnv env => Maybe ModuleName -> [BackendArg] -> RIO env ()
260+
run maybeModuleName extraArgs = do
284261
Config.Config { alternateBackend } <- view (the @Config)
285262
let moduleName = fromMaybe (ModuleName "Main") maybeModuleName
286263
sourceDir <- Turtle.pwd
287264
let dirs = RunDirectories sourceDir sourceDir
288-
runBackend alternateBackend dirs moduleName Nothing "Running failed; " buildOpts extraArgs
265+
runBackend alternateBackend dirs moduleName Nothing "Running failed; " extraArgs
289266

290267

291268
-- | Run the select module as a script: init, compile, and run the provided module
@@ -296,7 +273,7 @@ script
296273
-> [PackageName]
297274
-> ScriptBuildOptions
298275
-> RIO env ()
299-
script modulePath tag packageDeps opts@ScriptBuildOptions{..} = do
276+
script modulePath tag packageDeps opts = do
300277
logDebug "Running `spago script`"
301278
absoluteModulePath <- fmap Text.pack (makeAbsolute (Text.unpack modulePath))
302279
currentDir <- Turtle.pwd
@@ -325,21 +302,10 @@ script modulePath tag packageDeps opts@ScriptBuildOptions{..} = do
325302
let runDirs :: RunDirectories
326303
runDirs = RunDirectories scriptDirPath currentDir
327304

328-
Run.withBuildEnv' (Just config) NoPsa (runAction runDirs)
305+
Run.withBuildEnv' (Just config) NoPsa buildOpts (runAction runDirs)
329306
where
330-
runAction dirs = do
331-
let
332-
buildOpts = BuildOptions
333-
{ shouldClear = NoClear
334-
, shouldWatch = BuildOnce
335-
, allowIgnored = DoAllowIgnored
336-
, sourcePaths = []
337-
, withSourceMap = WithoutSrcMap
338-
, noInstall = DoInstall
339-
, depsOnly = AllSources
340-
, ..
341-
}
342-
runBackend Nothing dirs (ModuleName "Main") Nothing "Script failed to run; " buildOpts []
307+
buildOpts = fromScriptOptions defaultBuildOptions opts
308+
runAction dirs = runBackend Nothing dirs (ModuleName "Main") Nothing "Script failed to run; " []
343309

344310

345311
data RunDirectories = RunDirectories { sourceDir :: FilePath, executeDir :: FilePath }
@@ -353,13 +319,13 @@ runBackend
353319
-> ModuleName
354320
-> Maybe Text
355321
-> Text
356-
-> BuildOptions
357322
-> [BackendArg]
358323
-> RIO env ()
359-
runBackend maybeBackend RunDirectories{ sourceDir, executeDir } moduleName maybeSuccessMessage failureMessage buildOpts@BuildOptions{pursArgs} extraArgs = do
324+
runBackend maybeBackend RunDirectories{ sourceDir, executeDir } moduleName maybeSuccessMessage failureMessage extraArgs = do
360325
logDebug $ display $ "Running with backend: " <> fromMaybe "nodejs" maybeBackend
326+
BuildOptions{ pursArgs } <- view (the @BuildOptions)
361327
let postBuild = maybe (nodeAction $ Path.getOutputPath pursArgs) backendAction maybeBackend
362-
build buildOpts (Just postBuild)
328+
build (Just postBuild)
363329
where
364330
fromFilePath = Text.pack . Turtle.encodeString
365331
runJsSource = fromFilePath (sourceDir Turtle.</> ".spago/run.js")
@@ -409,7 +375,7 @@ bundleApp withMain maybeModuleName maybeTargetPath noBuild buildOpts usePsa =
409375
let (moduleName, targetPath) = prepareBundleDefaults maybeModuleName maybeTargetPath
410376
bundleAction = Purs.bundle withMain (withSourceMap buildOpts) moduleName targetPath
411377
in case noBuild of
412-
DoBuild -> Run.withBuildEnv usePsa $ build buildOpts (Just bundleAction)
378+
DoBuild -> Run.withBuildEnv usePsa buildOpts $ build (Just bundleAction)
413379
NoBuild -> Run.getEnv >>= (flip runRIO) bundleAction
414380

415381
-- | Bundle into a CommonJS module
@@ -436,21 +402,20 @@ bundleModule maybeModuleName maybeTargetPath noBuild buildOpts usePsa = do
436402
Right _ -> logInfo $ display $ "Make module succeeded and output file to " <> unTargetPath targetPath
437403
Left (n :: SomeException) -> die [ "Make module failed: " <> repr n ]
438404
case noBuild of
439-
DoBuild -> Run.withBuildEnv usePsa $ build buildOpts (Just bundleAction)
405+
DoBuild -> Run.withBuildEnv usePsa buildOpts $ build (Just bundleAction)
440406
NoBuild -> Run.getEnv >>= (flip runRIO) bundleAction
441407

442408

443409
-- | Generate docs for the `sourcePaths` and run `purescript-docs-search build-index` to patch them.
444410
docs
445-
:: (HasLogFunc env, HasConfig env)
411+
:: HasBuildEnv env
446412
=> Maybe Purs.DocsFormat
447-
-> [SourcePath]
448-
-> Packages.DepsOnly
449413
-> NoSearch
450414
-> OpenDocs
451415
-> RIO env ()
452-
docs format sourcePaths depsOnly noSearch open = do
416+
docs format noSearch open = do
453417
logDebug "Running `spago docs`"
418+
BuildOptions { sourcePaths, depsOnly } <- view (the @BuildOptions)
454419
Config{..} <- view (the @Config)
455420
deps <- Packages.getProjectDeps
456421
logInfo "Generating documentation for the project. This might take a while..."
@@ -486,9 +451,7 @@ docs format sourcePaths depsOnly noSearch open = do
486451
openLink link = liftIO $ Browser.openBrowser (Text.unpack link)
487452

488453
-- | Start a search REPL.
489-
search
490-
:: (HasPurs env, HasLogFunc env, HasConfig env)
491-
=> RIO env ()
454+
search :: HasBuildEnv env => RIO env ()
492455
search = do
493456
Config{..} <- view (the @Config)
494457
deps <- Packages.getProjectDeps

0 commit comments

Comments
 (0)