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 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -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.

## [0.21.0] - 2023-05-04

Expand Down
53 changes: 31 additions & 22 deletions bin/src/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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" ])
Expand Down Expand Up @@ -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 =
Expand All @@ -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
Expand All @@ -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
Expand Down
14 changes: 3 additions & 11 deletions core/src/Log.purs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ module Spago.Log
, rightOrDie
, rightOrDie_
, rightOrDieWith
, rightOrDieWith'
, toDoc
) where

Expand Down Expand Up @@ -183,25 +182,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
Expand Down
3 changes: 2 additions & 1 deletion core/src/Prelude.purs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down
12 changes: 7 additions & 5 deletions src/Spago/Command/Ls.purs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
Loading
Loading