Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run Spago from a nested directory other than workspace root #1310

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b0187a7
Run Spago from a nested directory other than workspace root
fsoikin Dec 19, 2024
fbab1c3
The high spirits of questionable formatting are not to be trifled with
fsoikin Jan 19, 2025
ebba9da
When the slash is forward, every forest friend will notice
fsoikin Jan 20, 2025
d2dff38
Merge branch 'master' into nested-launch
f-f Jan 20, 2025
8bc1cf7
Merge branch 'master' into nested-launch
f-f Jan 23, 2025
2b79ca1
Merge branch 'master' into nested-launch
f-f Jan 31, 2025
171b93f
Do not attempt to load subpackages nested under malformed config
fsoikin Feb 3, 2025
2048499
Try to fix CI
fsoikin Feb 3, 2025
b467814
Debug MacOS test failure
fsoikin Feb 3, 2025
e15dcb5
Debug MacOS test failure
fsoikin Feb 3, 2025
6580f30
Debug MacOS test failure
fsoikin Feb 3, 2025
41fe063
Debug MacOS test failure
fsoikin Feb 3, 2025
124fc0f
Debug MacOS test failure
fsoikin Feb 3, 2025
a5f5bf0
Debug MacOS test failure
fsoikin Feb 3, 2025
443fdc4
Debug MacOS test failure
fsoikin Feb 3, 2025
5507c42
Debug MacOS test failure
fsoikin Feb 3, 2025
e3987ab
Debug MacOS test failure
fsoikin Feb 3, 2025
d7d0ecf
Debug MacOS test failure
fsoikin Feb 3, 2025
c0c918b
Debug MacOS test failure
fsoikin Feb 3, 2025
9f2b7f4
Debug MacOS test failure
fsoikin Feb 3, 2025
be6712e
Debug MacOS test failure
fsoikin Feb 3, 2025
38ff466
Debug MacOS test failure
fsoikin Feb 3, 2025
eb0df61
Remove debug cruft
fsoikin Feb 3, 2025
893d7c8
Remove more debug cruft
fsoikin Feb 3, 2025
2fb281b
Can't forget about Windows
fsoikin Feb 3, 2025
f6d9ec9
Review feedback: rename variables, add comment, add type signatures
fsoikin Feb 9, 2025
d1a15af
Autoformatter
fsoikin Feb 9, 2025
cc42d8e
Merge branch 'master' into nested-launch
fsoikin Feb 9, 2025
57a4768
Mention pruning reasoning
fsoikin Feb 9, 2025
67e96f1
Merge remote-tracking branch 'refs/remotes/origin/nested-launch' into…
fsoikin Feb 9, 2025
1bf9a7a
Merge branch 'master' into nested-launch
f-f Feb 14, 2025
b50b0f1
Merge branch 'master' into nested-launch
f-f Feb 14, 2025
52d8264
Merge branch 'master' into nested-launch
fsoikin Feb 19, 2025
2b23022
Fix test fixtures to account for prelude 6.0.2
fsoikin Feb 23, 2025
72092f4
More such spots
fsoikin Feb 23, 2025
8b09d98
And two more spots
fsoikin Feb 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -43,6 +43,8 @@ Other improvements:
- When the `publish.location` field is missing, `spago publish` will attempt to
figure out the location from Git remotes and write it back to `spago.yaml`.
- Internally Spago uses stricter-typed file paths.
- Spago can now be launched from a directory nested within the workspace, not
just from workspace root.
- `spago install` warns the user when the installed versions of packages are outside
their specified dependency ranges.
- `spago publish` no longer tries to validate all workspace dependencies, but
53 changes: 31 additions & 22 deletions bin/src/Main.purs
Original file line number Diff line number Diff line change
@@ -536,8 +536,7 @@ main = do
\c -> Aff.launchAff_ case c of
Cmd'SpagoCmd (SpagoCmd globalArgs@{ offline, migrateConfig } command) -> do
logOptions <- mkLogOptions startingTime globalArgs
rootPath <- Path.mkRoot =<< Paths.cwd
runSpago { logOptions, rootPath } case command of
runSpago { logOptions } case command of
Sources args -> do
{ env } <- mkFetchEnv
{ packages: mempty
@@ -552,6 +551,7 @@ main = do
void $ runSpago env (Sources.run { json: args.json })
Init args@{ useSolver } -> do
-- Fetch the registry here so we can select the right package set later
rootPath <- Path.mkRoot =<< Paths.cwd
env <- mkRegistryEnv offline <#> Record.union { rootPath }
setVersion <- parseSetVersion args.setVersion
void $ runSpago env $ Init.run { mode: args.mode, setVersion, useSolver }
@@ -599,7 +599,8 @@ main = do
void $ runSpago publishEnv (Publish.publish {})

Repl args@{ selectedPackage } -> do
packages <- FS.exists (rootPath </> "spago.yaml") >>= case _ of
cwd <- Paths.cwd
packages <- FS.exists (cwd </> "spago.yaml") >>= case _ of
true -> do
-- if we have a config then we assume it's a workspace, and we can run a repl in the project
pure mempty -- TODO newPackages
@@ -661,13 +662,14 @@ main = do
testEnv <- runSpago env (mkTestEnv args buildEnv)
runSpago testEnv Test.run
LsPaths args -> do
runSpago { logOptions, rootPath } $ Ls.listPaths args
let fetchArgs = { packages: mempty, selectedPackage: Nothing, pure: false, ensureRanges: false, testDeps: false, isRepl: false, migrateConfig, offline }
{ env } <- mkFetchEnv fetchArgs
runSpago env $ Ls.listPaths args
LsPackages args@{ pure } -> do
let fetchArgs = { packages: mempty, selectedPackage: Nothing, pure, ensureRanges: false, testDeps: false, isRepl: false, migrateConfig, offline }
{ env: env@{ workspace }, fetchOpts } <- mkFetchEnv fetchArgs
{ env, fetchOpts } <- mkFetchEnv fetchArgs
dependencies <- runSpago env (Fetch.run fetchOpts)
let lsEnv = { workspace, dependencies, logOptions, rootPath }
runSpago lsEnv (Ls.listPackageSet args)
runSpago (Record.union env { dependencies }) (Ls.listPackageSet args)
LsDeps { selectedPackage, json, transitive, pure } -> do
let fetchArgs = { packages: mempty, selectedPackage, pure, ensureRanges: false, testDeps: false, isRepl: false, migrateConfig, offline }
{ env, fetchOpts } <- mkFetchEnv fetchArgs
@@ -690,13 +692,11 @@ main = do
GraphModules args -> do
{ env, fetchOpts } <- mkFetchEnv { packages: mempty, selectedPackage: Nothing, pure: false, ensureRanges: false, testDeps: false, isRepl: false, migrateConfig, offline }
dependencies <- runSpago env (Fetch.run fetchOpts)
purs <- Purs.getPurs
runSpago { dependencies, logOptions, rootPath, purs, workspace: env.workspace } (Graph.graphModules args)
runSpago (Record.union env { dependencies }) (Graph.graphModules args)
GraphPackages args -> do
{ env, fetchOpts } <- mkFetchEnv { packages: mempty, selectedPackage: Nothing, pure: false, ensureRanges: false, testDeps: false, isRepl: false, migrateConfig, offline }
dependencies <- runSpago env (Fetch.run fetchOpts)
purs <- Purs.getPurs
runSpago { dependencies, logOptions, rootPath, purs, workspace: env.workspace } (Graph.graphPackages args)
runSpago (Record.union env { dependencies }) (Graph.graphPackages args)

Cmd'VersionCmd v -> when v do
output (OutputLines [ BuildInfo.packages."spago-bin" ])
@@ -951,7 +951,14 @@ mkReplEnv replArgs dependencies supportPackage = do
, selected
}

mkFetchEnv :: forall a b. { offline :: OnlineStatus, migrateConfig :: Boolean, isRepl :: Boolean | FetchArgsRow b } -> Spago (SpagoBaseEnv a) { env :: Fetch.FetchEnv (), fetchOpts :: Fetch.FetchOpts }
mkFetchEnv
:: a b
. { offline :: OnlineStatus
, migrateConfig :: Boolean
, isRepl :: Boolean
| FetchArgsRow b
}
-> Spago { logOptions :: LogOptions | a } { env :: Fetch.FetchEnv (), fetchOpts :: Fetch.FetchOpts }
mkFetchEnv args@{ migrateConfig, offline } = do
let
parsePackageName p =
@@ -966,24 +973,26 @@ mkFetchEnv args@{ migrateConfig, offline } = do
Left _err -> die $ "Failed to parse selected package name, was: " <> show args.selectedPackage

env <- mkRegistryEnv offline
{ rootPath } <- ask
workspace <-
runSpago (Record.union env { rootPath })
(Config.readWorkspace { maybeSelectedPackage, pureBuild: args.pure, migrateConfig })
cwd <- Paths.cwd
{ workspace, rootPath } <-
runSpago env
(Config.discoverWorkspace { maybeSelectedPackage, pureBuild: args.pure, migrateConfig } cwd)

FS.mkdirp $ rootPath </> Paths.localCachePath
FS.mkdirp $ rootPath </> Paths.localCachePackagesPath
logDebug $ "Workspace root path: " <> Path.quote rootPath
logDebug $ "Local cache: " <> Paths.localCachePath

let fetchOpts = { packages: packageNames, ensureRanges: args.ensureRanges, isTest: args.testDeps, isRepl: args.isRepl }
pure { fetchOpts, env: Record.union { workspace, rootPath } env }

mkRegistryEnv :: forall a. OnlineStatus -> Spago (SpagoBaseEnv a) (Registry.RegistryEnv ())
mkRegistryEnv offline = do
{ logOptions, rootPath } <- ask
{ logOptions } <- ask

-- Take care of the caches
FS.mkdirp Paths.globalCachePath
FS.mkdirp $ rootPath </> Paths.localCachePath
FS.mkdirp $ rootPath </> Paths.localCachePackagesPath
logDebug $ "Workspace root path: " <> Path.quote rootPath
logDebug $ "Global cache: " <> Path.quote Paths.globalCachePath
logDebug $ "Local cache: " <> Paths.localCachePath

-- Make sure we have git and purs
git <- Git.getGit
@@ -1004,7 +1013,7 @@ mkRegistryEnv offline = do
, db
}

mkLsEnv :: forall a. Fetch.PackageTransitiveDeps -> Spago (Fetch.FetchEnv a) Ls.LsEnv
mkLsEnv :: a. Fetch.PackageTransitiveDeps -> Spago (Fetch.FetchEnv a) (Ls.LsEnv ())
mkLsEnv dependencies = do
{ logOptions, workspace, rootPath } <- ask
selected <- case workspace.selected of
14 changes: 3 additions & 11 deletions core/src/Log.purs
Original file line number Diff line number Diff line change
@@ -22,7 +22,6 @@ module Spago.Log
, rightOrDie
, rightOrDie_
, rightOrDieWith
, rightOrDieWith'
, toDoc
) where

@@ -185,25 +184,18 @@ justOrDieWith' value msg = case value of
die' msg

rightOrDie :: b m err x. MonadEffect m => MonadAsk (LogEnv b) m => Loggable err => Either err x -> m x
rightOrDie value = rightOrDieWith value identity
rightOrDie = rightOrDieWith identity

rightOrDie_ :: b m err x. MonadEffect m => MonadAsk (LogEnv b) m => Loggable err => Either err x -> m Unit
rightOrDie_ = void <<< rightOrDie

rightOrDieWith :: a b m err x. MonadEffect m => MonadAsk (LogEnv b) m => Loggable a => Either err x -> (err -> a) -> m x
rightOrDieWith value toMsg = case value of
rightOrDieWith :: a b m err x. MonadEffect m => MonadAsk (LogEnv b) m => Loggable a => (err -> a) -> Either err x -> m x
rightOrDieWith toMsg value = case value of
Right a ->
pure a
Left err ->
die $ toMsg err

rightOrDieWith' :: a b m err x. MonadEffect m => MonadAsk (LogEnv b) m => Loggable a => Either err x -> (err -> Array a) -> m x
rightOrDieWith' value toMsg = case value of
Right a ->
pure a
Left err ->
die' $ toMsg err

data OutputFormat a
= OutputJson (CJ.Codec a) a
| OutputYaml (CJ.Codec a) a
3 changes: 2 additions & 1 deletion core/src/Prelude.purs
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ import Data.DateTime.Instant (Instant) as Extra
import Data.Either (Either(..), isLeft, isRight, either, hush) as Extra
import Data.Filterable (partition, partitionMap) as Extra
import Data.Foldable (foldMap, for_, foldl, and, or) as Extra
import Data.FoldableWithIndex (forWithIndex_) as Extra
import Data.Function (on) as Extra
import Data.Generic.Rep (class Generic) as Extra
import Data.Identity (Identity(..)) as Extra
@@ -47,7 +48,7 @@ import Partial.Unsafe (unsafeCrashWith)
import Registry.ManifestIndex (ManifestIndex) as Extra
import Registry.Types (PackageName, Version, Range, Location, License, Manifest(..), Metadata(..), Sha256) as Extra
import Spago.Json (printJson, parseJson) as Extra
import Spago.Log (logDebug, logError, logInfo, Docc, logSuccess, logWarn, die, die', justOrDieWith, justOrDieWith', rightOrDie, rightOrDie_, rightOrDieWith, rightOrDieWith', toDoc, indent, indent2, output, LogEnv, LogOptions, OutputFormat(..)) as Extra
import Spago.Log (logDebug, logError, logInfo, Docc, logSuccess, logWarn, die, die', justOrDieWith, justOrDieWith', rightOrDie, rightOrDie_, rightOrDieWith, toDoc, indent, indent2, output, LogEnv, LogOptions, OutputFormat(..)) as Extra
import Spago.Path (RawFilePath, GlobalPath, LocalPath, RootPath, class AppendPath, appendPath, (</>)) as Extra
import Spago.Yaml (YamlDoc, printYaml, parseYaml) as Extra

12 changes: 7 additions & 5 deletions src/Spago/Command/Ls.purs
Original file line number Diff line number Diff line change
@@ -50,22 +50,24 @@ type LsPathsArgs =
{ json :: Boolean
}

type LsSetEnv =
type LsSetEnv r =
{ dependencies :: Fetch.PackageTransitiveDeps
, logOptions :: LogOptions
, workspace :: Workspace
, rootPath :: RootPath
| r
}

type LsEnv =
type LsEnv r =
{ dependencies :: Fetch.PackageTransitiveDeps
, logOptions :: LogOptions
, workspace :: Workspace
, selected :: WorkspacePackage
, rootPath :: RootPath
| r
}

listPaths :: LsPathsArgs -> Spago { logOptions :: LogOptions, rootPath :: RootPath } Unit
listPaths :: r. LsPathsArgs -> Spago { logOptions :: LogOptions, rootPath :: RootPath | r } Unit
listPaths { json } = do
logDebug "Running `listPaths`"
{ rootPath } <- ask
@@ -90,7 +92,7 @@ listPaths { json } = do

-- TODO: add LICENSE field

listPackageSet :: LsPackagesArgs -> Spago LsSetEnv Unit
listPackageSet :: r. LsPackagesArgs -> Spago (LsSetEnv r) Unit
listPackageSet { json } = do
logDebug "Running `listPackageSet`"
{ workspace, rootPath } <- ask
@@ -102,7 +104,7 @@ listPackageSet { json } = do
true -> formatPackagesJson rootPath packages
false -> formatPackagesTable packages

listPackages :: LsDepsOpts -> Spago LsEnv Unit
listPackages :: r. LsDepsOpts -> Spago (LsEnv r) Unit
listPackages { transitive, json } = do
logDebug "Running `listPackages`"
{ dependencies, selected, rootPath } <- ask
422 changes: 255 additions & 167 deletions src/Spago/Config.purs

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions src/Spago/Prelude.purs
Original file line number Diff line number Diff line change
@@ -51,8 +51,7 @@ data OnlineStatus = Offline | Online | OnlineBypassCache
derive instance Eq OnlineStatus

type SpagoBaseEnv a =
{ rootPath :: Path.RootPath
, logOptions :: LogOptions
{ logOptions :: LogOptions
| a
}

4 changes: 4 additions & 0 deletions test-fixtures/config/discovery/a/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package:
name: a
dependencies:
- prelude
4 changes: 4 additions & 0 deletions test-fixtures/config/discovery/b/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package:
name: b
dependencies:
- prelude
12 changes: 12 additions & 0 deletions test-fixtures/config/discovery/from-a.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Reading Spago workspace configuration...

✓ Selecting package to build: a

Downloading dependencies...
Building...
purs compile: No files found using pattern: a/src/**/*.purs
Src Lib All
Warnings 0 0 0
Errors 0 0 0

✓ Build succeeded.
12 changes: 12 additions & 0 deletions test-fixtures/config/discovery/from-d.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Reading Spago workspace configuration...

✓ Selecting package to build: d

Downloading dependencies...
Building...
purs compile: No files found using pattern: d/src/**/*.purs
Src Lib All
Warnings 0 0 0
Errors 0 0 0

✓ Build succeeded.
17 changes: 17 additions & 0 deletions test-fixtures/config/discovery/from-nested.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Reading Spago workspace configuration...

✓ Selecting 3 packages to build:
c
d
nested-workspace

Downloading dependencies...
Building...
purs compile: No files found using pattern: c/src/**/*.purs
purs compile: No files found using pattern: d/src/**/*.purs
purs compile: No files found using pattern: src/**/*.purs
Src Lib All
Warnings 0 0 0
Errors 0 0 0

✓ Build succeeded.
17 changes: 17 additions & 0 deletions test-fixtures/config/discovery/from-root.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Reading Spago workspace configuration...

✓ Selecting 3 packages to build:
a
b
foo

Downloading dependencies...
Building...
purs compile: No files found using pattern: a/src/**/*.purs
purs compile: No files found using pattern: b/src/**/*.purs
purs compile: No files found using pattern: src/**/*.purs
Src Lib All
Warnings 0 0 0
Errors 0 0 0

✓ Build succeeded.
4 changes: 4 additions & 0 deletions test-fixtures/config/discovery/nested-workspace/c/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package:
name: c
dependencies:
- prelude
4 changes: 4 additions & 0 deletions test-fixtures/config/discovery/nested-workspace/d/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package:
name: d
dependencies:
- prelude
8 changes: 8 additions & 0 deletions test-fixtures/config/discovery/nested-workspace/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package:
name: nested-workspace
dependencies:
- prelude

workspace:
packageSet:
registry: 41.5.0
10 changes: 10 additions & 0 deletions test-fixtures/config/discovery/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package:
name: foo
dependencies:
- console
- effect
- prelude

workspace:
packageSet:
registry: 41.5.0
3 changes: 3 additions & 0 deletions test-fixtures/config/malformed-configs/a/b/c/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package:
name: c
dependencies: []
3 changes: 3 additions & 0 deletions test-fixtures/config/malformed-configs/a/b/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package:
title: b # `title` is not a valid field, this config will error out on parsing.
dependencies: []
3 changes: 3 additions & 0 deletions test-fixtures/config/malformed-configs/a/d/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package:
name: d
dependencies: []
3 changes: 3 additions & 0 deletions test-fixtures/config/malformed-configs/a/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package:
name: a
dependencies: []
9 changes: 9 additions & 0 deletions test-fixtures/config/malformed-configs/from-root.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Reading Spago workspace configuration...
‼ Failed to read config at "<test-dir>/a/b/spago.yaml"
Skipping it and all its subprojects

✘ Selected package bogus was not found in the local packages.
All available packages:
a
d
root
6 changes: 6 additions & 0 deletions test-fixtures/config/malformed-configs/spago.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package:
name: root
dependencies: []
workspace:
packageSet:
registry: 0.0.1
Empty file.
Empty file.
Empty file.
10 changes: 10 additions & 0 deletions test-fixtures/config/misnamed-configs/from-a.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Reading Spago workspace configuration...

✘ No spago.yaml found in the current directory or any of its parents.


Instead found "../spago.yml"
Note that Spago config files should be named spago.yaml, not spago.yml.


The configuration file help can be found here https://github.com/purescript/spago#the-configuration-file
12 changes: 12 additions & 0 deletions test-fixtures/config/misnamed-configs/from-b.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Reading Spago workspace configuration...

✘ No spago.yaml found in the current directory or any of its parents.


Instead found these:
"../../spago.yml"
"spago.yml"
Note that Spago config files should be named spago.yaml, not spago.yml.


The configuration file help can be found here https://github.com/purescript/spago#the-configuration-file
13 changes: 13 additions & 0 deletions test-fixtures/config/misnamed-configs/from-c.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Reading Spago workspace configuration...

✘ No spago.yaml found in the current directory or any of its parents.


Instead found these:
"../../../spago.yml"
"../spago.yml"
"spago.yml"
Note that Spago config files should be named spago.yaml, not spago.yml.


The configuration file help can be found here https://github.com/purescript/spago#the-configuration-file
12 changes: 12 additions & 0 deletions test-fixtures/config/misnamed-configs/from-d.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Reading Spago workspace configuration...

✘ No spago.yaml found in the current directory or any of its parents.


Instead found these:
"../../../spago.yml"
"../spago.yml"
Note that Spago config files should be named spago.yaml, not spago.yml.


The configuration file help can be found here https://github.com/purescript/spago#the-configuration-file
10 changes: 10 additions & 0 deletions test-fixtures/config/misnamed-configs/from-root.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Reading Spago workspace configuration...

✘ No spago.yaml found in the current directory or any of its parents.


Instead found "spago.yml"
Note that Spago config files should be named spago.yaml, not spago.yml.


The configuration file help can be found here https://github.com/purescript/spago#the-configuration-file
Empty file.
3 changes: 3 additions & 0 deletions test-fixtures/config/no-workspace-anywhere.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Reading Spago workspace configuration...

✘ No spago.yaml found in the current directory or any of its parents.
2 changes: 1 addition & 1 deletion test-fixtures/list-dependencies.json
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@
"prelude": {
"type": "registry",
"value": {
"version": "6.0.1"
"version": "6.0.2"
}
}
}
2 changes: 1 addition & 1 deletion test-fixtures/list-dependencies.txt
Original file line number Diff line number Diff line change
@@ -3,5 +3,5 @@
+---------+---------+----------+
| console | 6.1.0 | - |
| effect | 4.0.0 | - |
| prelude | 6.0.1 | - |
| prelude | 6.0.2 | - |
+---------+---------+----------+
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ package:
dependencies:
- console: ">=6.0.0 <7.0.0"
- effect: ">=4.0.0 <5.0.0"
- prelude: ">=6.0.1 <7.0.0"
- prelude: ">=6.0.2 <7.0.0"
Copy link
Collaborator Author

@fsoikin fsoikin Feb 23, 2025

Choose a reason for hiding this comment

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

This change and equivalent changes in other test fixtures are not related to the PR as such, but are fixing a different issue.

  • Prelude 6.0.2 was published on February 15th. It is included in package set 63.3.0.
  • Because of this, when building with registry solver, Spago pulls in this new version of prelude.
  • These test projects, however, explicitly specify prelude 6.0.1 as well as package set versions that don't have prelude 6.0.2 in them.
  • As a result, building with solver and building with package set produces different build plans, which in turn causes spago publish to run a new build, even if spago build was run immediately before it, which in turn produces compiler progress output, and this compiler progress output was unexpected in test fixtures, causing the tests to fail.
  • To fix the issue, I upgraded the test fixtures to use prelude 6.0.2 and a corresponding package set, so that build plans with and without solver will match for these projects.
  • This is not a good solution though, only a bandaid "for now". It will break again as soon as new packages are published. I'm not 100% sure what a good solution would be. Perhaps make the registry solver able to use a past snapshot of the registry? Or we could artificially cut out expected compiler output, like we already kind of do in some tests. Or, perhaps, this is actually good: this way Spago development never goes stale and keeps up with new stuff in new package sets.

Copy link
Contributor

Choose a reason for hiding this comment

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

@fsoikin , can this be merged as-is? When an updated package set causes test breakage in the future, I suggest we continue patching until a permanent solution is found. The value-add of this PR is already big, as it is. Thanks again

- maybe: ">=6.0.0 <7.0.0"
publish:
version: 0.0.1
@@ -13,6 +13,6 @@ package:
githubRepo: aaa
workspace:
packageSet:
registry: 58.0.0
registry: 63.3.0
extraPackages:
console: "6.0.0"
4 changes: 2 additions & 2 deletions test-fixtures/publish/1307-publish-dependencies/spago.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package:
name: root
dependencies:
- prelude: ">=6.0.1 <7.0.0"
- prelude: ">=6.0.2 <7.0.0"
- effect: ">=4.0.0 <5.0.0"
publish:
version: 0.0.1
@@ -11,4 +11,4 @@ package:
githubRepo: aaa
workspace:
packageSet:
registry: 62.2.5
registry: 63.3.0
4 changes: 2 additions & 2 deletions test-fixtures/publish/basic.yaml
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ package:
dependencies:
- console: ">=6.0.0 <7.0.0"
- effect: ">=4.0.0 <5.0.0"
- prelude: ">=6.0.1 <7.0.0"
- prelude: ">=6.0.2 <7.0.0"
test:
main: Test.Main
dependencies: []
@@ -15,6 +15,6 @@ package:
githubRepo: aaa
workspace:
packageSet:
registry: 28.1.1
registry: 63.3.0
extraPackages:
console: "6.1.0"
4 changes: 2 additions & 2 deletions test-fixtures/publish/extra-package-core/spago.yaml
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ package:
dependencies:
- console: ">=6.0.0 <7.0.0"
- effect: ">=4.0.0 <5.0.0"
- prelude: ">=6.0.1 <7.0.0"
- prelude: ">=6.0.2 <7.0.0"
- maybe: ">=6.0.0 <7.0.0"
test:
main: Test.Main
@@ -17,7 +17,7 @@ package:
githubRepo: aaa
workspace:
packageSet:
registry: 28.1.1
registry: 63.3.0
extraPackages:
console: "6.1.0"
maybe:
4 changes: 2 additions & 2 deletions test-fixtures/publish/extra-package-test/spago.yaml
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ package:
dependencies:
- console: ">=6.0.0 <7.0.0"
- effect: ">=4.0.0 <5.0.0"
- prelude: ">=6.0.1 <7.0.0"
- prelude: ">=6.0.2 <7.0.0"
test:
main: Test.Main
dependencies:
@@ -16,7 +16,7 @@ package:
githubRepo: aaa
workspace:
packageSet:
registry: 28.1.1
registry: 63.3.0
extraPackages:
console: "6.1.0"
maybe:
2 changes: 1 addition & 1 deletion test-fixtures/sources-output.txt
Original file line number Diff line number Diff line change
@@ -2,4 +2,4 @@ src/**/*.purs
test/**/*.purs
.spago/p/console-6.1.0/src/**/*.purs
.spago/p/effect-4.0.0/src/**/*.purs
.spago/p/prelude-6.0.1/src/**/*.purs
.spago/p/prelude-6.0.2/src/**/*.purs
2 changes: 1 addition & 1 deletion test-fixtures/sources-output.win.txt
Original file line number Diff line number Diff line change
@@ -2,4 +2,4 @@ src\**\*.purs
test\**\*.purs
.spago\p\console-6.1.0\src\**\*.purs
.spago\p\effect-4.0.0\src\**\*.purs
.spago\p\prelude-6.0.1\src\**\*.purs
.spago\p\prelude-6.0.2\src\**\*.purs
2 changes: 1 addition & 1 deletion test-fixtures/sources-subproject-output.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.spago/p/console-6.1.0/src/**/*.purs
.spago/p/effect-4.0.0/src/**/*.purs
.spago/p/prelude-6.0.1/src/**/*.purs
.spago/p/prelude-6.0.2/src/**/*.purs
subpackage/src/**/*.purs
subpackage/test/**/*.purs
2 changes: 1 addition & 1 deletion test-fixtures/sources-subproject-output.win.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.spago\p\console-6.1.0\src\**\*.purs
.spago\p\effect-4.0.0\src\**\*.purs
.spago\p\prelude-6.0.1\src\**\*.purs
.spago\p\prelude-6.0.2\src\**\*.purs
subpackage\src\**\*.purs
subpackage\test\**\*.purs
6 changes: 3 additions & 3 deletions test-fixtures/spago-yml-check-stderr.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Reading Spago workspace configuration...

Couldn't parse Spago config, error:
No spago.yaml found in the current directory or any of its parents.


Did not find "spago.yaml". Spago's configuration files must end with `.yaml`, not `.yml`.
Try renaming "spago.yml" to "spago.yaml" or run `spago init` to initialize a new project.
Instead found "spago.yml"
Note that Spago config files should be named spago.yaml, not spago.yml.


The configuration file help can be found here https://github.com/purescript/spago#the-configuration-file
7 changes: 4 additions & 3 deletions test/Prelude.purs
Original file line number Diff line number Diff line change
@@ -49,9 +49,10 @@ withTempDir = Aff.bracket createTempDir cleanupTempDir
where
createTempDir = do
oldCwd <- Paths.cwd
temp <- Path.mkRoot =<< mkTemp' (Just "spago-test-")
FS.mkdirp temp
Paths.chdir temp
temp' <- mkTemp' (Just "spago-test-")
FS.mkdirp temp'
Paths.chdir temp'
temp <- Path.mkRoot =<< Paths.cwd
isDebug <- liftEffect $ map isJust $ Process.lookupEnv "SPAGO_TEST_DEBUG"
when isDebug do
log $ "Running test in " <> Path.quote temp
95 changes: 90 additions & 5 deletions test/Spago/Config.purs
Original file line number Diff line number Diff line change
@@ -3,12 +3,16 @@ module Test.Spago.Config where
import Test.Prelude

import Codec.JSON.DecodeError as CJ
import Data.String as String
import Registry.License as License
import Registry.Location (Location(..))
import Registry.PackageName as PackageName
import Registry.Version as Version
import Spago.Core.Config (SetAddress(..))
import Spago.Core.Config as C
import Spago.FS as FS
import Spago.Path as Path
import Spago.Paths as Paths
import Spago.Yaml as Yaml
import Test.Spec (Spec)
import Test.Spec as Spec
@@ -64,11 +68,92 @@ spec =
<> "\n - Could not decode GitHub:"
<> "\n Unknown field(s): bogus_field"
)
where
shouldFailWith result expectedError =
case result of
Right _ -> Assert.fail "Expected an error, but parsed successfully"
Left err -> CJ.print err `shouldEqual` expectedError

Spec.around withTempDir $
Spec.describe "spago.yaml discovery" do
Spec.it "discovers config up the directory tree" \{ testCwd, fixture, spago } -> do
FS.copyTree { src: fixture "config/discovery", dst: testCwd }
spago [ "build" ] >>= shouldBeSuccess
spago [ "build" ] >>= shouldBeSuccessErr' (fixture "config/discovery/from-root.txt")

-- Running from `./a`, Spago should discover the workspace root at
-- './' and select package 'a'
Paths.chdir $ testCwd </> "a"
spago [ "build" ] >>= shouldBeSuccessErr' (fixture "config/discovery/from-a.txt")

-- Running from `./nested-workspace`, Spago should use the workspace
-- root at './nested-workspace' and not the one at './'
Paths.chdir $ testCwd </> "nested-workspace"
spago [ "build" ] >>= shouldBeSuccess
spago [ "build" ] >>= shouldBeSuccessErr' (fixture "config/discovery/from-nested.txt")

-- Running from `./nested-workspace/d`, Spago should use the workspace
-- root at './nested-workspace', because that's the closest one, and
-- select package 'd'
Paths.chdir $ testCwd </> "nested-workspace" </> "d"
spago [ "build" ] >>= shouldBeSuccessErr' (fixture "config/discovery/from-d.txt")

-- At workspace roots, a ".spago" directory should be created for
-- local cache, but not in subdirs
FS.exists (testCwd </> ".spago") `Assert.shouldReturn` true
FS.exists (testCwd </> "a" </> ".spago") `Assert.shouldReturn` false
FS.exists (testCwd </> "nested-workspace" </> ".spago") `Assert.shouldReturn` true
FS.exists (testCwd </> "nested-workspace" </> "d" </> ".spago") `Assert.shouldReturn` false

Spec.it "reports no config in any parent directories" \{ spago, fixture } ->
spago [ "build" ] >>= shouldBeFailureErr' (fixture "config/no-workspace-anywhere.txt")

Spec.it "reports possible misnamed configs up the directory tree" \{ testCwd, spago, fixture } -> do
FS.copyTree { src: fixture "config/misnamed-configs", dst: testCwd }
spago [ "build" ] >>= shouldBeFailureErr' (fixture "config/misnamed-configs/from-root.txt")

Paths.chdir $ testCwd </> "a"
spago [ "build" ] >>= shouldBeFailureErr' (fixture "config/misnamed-configs/from-a.txt")

Paths.chdir $ testCwd </> "a" </> "b"
spago [ "build" ] >>= shouldBeFailureErr' (fixture "config/misnamed-configs/from-b.txt")

Paths.chdir $ testCwd </> "a" </> "b" </> "c"
spago [ "build" ] >>= shouldBeFailureErr' (fixture "config/misnamed-configs/from-c.txt")

Paths.chdir $ testCwd </> "a" </> "b" </> "d"
spago [ "build" ] >>= shouldBeFailureErr' (fixture "config/misnamed-configs/from-d.txt")

Spec.it "warns about a malformed config, but stops parsing down the tree" \{ spago, fixture, testCwd } -> do
FS.copyTree { src: fixture "config/malformed-configs", dst: testCwd }

-- Running with "-p bogus" to get Spago to list all available
-- packages. Packages `b` and `c` shouldn't be in that list because
-- b's config is malformatted, so Spago should warn about it and stop
-- loading configs down the tree from `b`, thus skipping `c`.
spago [ "build", "-p", "bogus" ] >>= checkOutputs'
{ result: isLeft
, stdoutFile: Nothing
, stderrFile: Just (fixture "config/malformed-configs/from-root.txt")
, sanitize:
String.trim
>>> String.replaceAll (String.Pattern $ Path.toRaw testCwd) (String.Replacement "<test-dir>")
>>> String.replaceAll (String.Pattern "\\") (String.Replacement "/")
}

where
shouldFailWith result expectedError =
case result of
Right _ -> Assert.fail "Expected an error, but parsed successfully"
Left err -> CJ.print err `shouldEqual` expectedError

shouldBeSuccessErr' = shouldBeErr isRight
shouldBeFailureErr' = shouldBeErr isLeft

shouldBeErr result file = checkOutputs'
{ stdoutFile: Nothing
, stderrFile: Just file
, result
, sanitize:
String.trim
>>> String.replaceAll (String.Pattern "\\") (String.Replacement "/")
>>> String.replaceAll (String.Pattern "\r\n") (String.Replacement "\n")
}

validSpagoYaml :: { serialized :: String, parsed :: C.Config }
validSpagoYaml =