Skip to content

Commit 1afe463

Browse files
committed
search parent dirs for workspace
#1237
1 parent f130b33 commit 1afe463

File tree

3 files changed

+82
-5
lines changed

3 files changed

+82
-5
lines changed

src/Spago/Config.purs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import Data.Enum as Enum
3838
import Data.Graph as Graph
3939
import Data.HTTP.Method as Method
4040
import Data.Int as Int
41+
import Data.List (List(..), (:))
4142
import Data.Map as Map
4243
import Data.Nullable (Nullable)
4344
import Data.Nullable as Nullable
@@ -47,6 +48,7 @@ import Data.Set.NonEmpty (NonEmptySet)
4748
import Data.Set.NonEmpty as NonEmptySet
4849
import Data.String (CodePoint, Pattern(..))
4950
import Data.String as String
51+
import Data.Traversable (sequence)
5052
import Dodo as Log
5153
import Effect.Aff as Aff
5254
import Effect.Uncurried (EffectFn2, EffectFn3, runEffectFn2, runEffectFn3)
@@ -164,6 +166,17 @@ type ReadWorkspaceOptions =
164166
, migrateConfig :: Boolean
165167
}
166168

169+
type PrelimWorkspace =
170+
{ backend :: Maybe Core.BackendConfig
171+
, buildOpts :: Maybe
172+
{ censorLibraryWarnings :: Maybe Core.CensorBuildWarnings
173+
, output :: Maybe String
174+
, statVerbosity :: Maybe Core.StatVerbosity
175+
}
176+
, extraPackages :: Maybe (Map PackageName Core.ExtraPackage)
177+
, packageSet :: Maybe Core.SetAddress
178+
}
179+
167180
-- | Reads all the configurations in the tree and builds up the Map of local
168181
-- | packages to be integrated in the package set
169182
readWorkspace :: ReadWorkspaceOptions -> Spago (Registry.RegistryEnv _) Workspace
@@ -180,6 +193,36 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do
180193
false, true -> logWarn $ "Your " <> path <> " is using an outdated format. Run Spago with the --migrate flag to update it to the latest version."
181194
_, false -> pure unit
182195

196+
logInfo "Gathering all the spago configs higher in the tree..."
197+
let
198+
higherPaths :: List FilePath
199+
higherPaths = Array.toUnfoldable $ Paths.toGitSearchPath Paths.cwd
200+
201+
checkForWorkspace :: forall a. FilePath
202+
-> Spago (LogEnv a) (Maybe PrelimWorkspace)
203+
checkForWorkspace config = do
204+
result <- readConfig config
205+
case result of
206+
Left _ -> pure Nothing
207+
Right { yaml: { workspace: Nothing } } -> pure Nothing
208+
Right { yaml: { workspace: Just ws } } -> pure (Just ws)
209+
210+
searchHigherPaths :: forall a. List FilePath -> Spago (LogEnv a) (Maybe PrelimWorkspace)
211+
searchHigherPaths Nil = pure Nothing
212+
searchHigherPaths (path : otherPaths) = do
213+
mYaml :: Maybe String <- map Array.head $ liftAff $ Glob.gitignoringGlob path [ "./spago.yaml" ]
214+
case mYaml of
215+
Nothing -> searchHigherPaths otherPaths
216+
Just foundSpagoYaml -> do
217+
mWorkspace :: Maybe PrelimWorkspace <- checkForWorkspace foundSpagoYaml
218+
case mWorkspace of
219+
Nothing -> searchHigherPaths otherPaths
220+
workspace -> pure workspace
221+
222+
mHigherConfigPath <- searchHigherPaths higherPaths
223+
for_ mHigherConfigPath $ \higherConfigPath -> do
224+
logDebug $ [ toDoc "Found workspace at higher path:" ]
225+
183226
-- First try to read the config in the root. It _has_ to contain a workspace
184227
-- configuration, or we fail early.
185228
{ workspace, package: maybePackage, workspaceDoc } <- readConfig "spago.yaml" >>= case _ of
@@ -199,10 +242,10 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do
199242
doMigrateConfig "spago.yaml" config
200243
pure { workspace, package, workspaceDoc: doc }
201244

202-
logDebug "Gathering all the spago configs in the tree..."
203-
otherConfigPaths <- liftAff $ Glob.gitignoringGlob Paths.cwd [ "**/spago.yaml" ]
204-
unless (Array.null otherConfigPaths) do
205-
logDebug $ [ toDoc "Found packages at these paths:", Log.indent $ Log.lines (map toDoc otherConfigPaths) ]
245+
logDebug "Gathering all the spago configs lower in the tree..."
246+
otherLowerConfigPaths <- liftAff $ Glob.gitignoringGlob Paths.cwd [ "**/spago.yaml" ]
247+
unless (Array.null otherLowerConfigPaths) do
248+
logDebug $ [ toDoc "Found packages at these lower paths:", Log.indent $ Log.lines (map toDoc otherLowerConfigPaths) ]
206249

207250
-- We read all of them in, and only read the package section, if any.
208251
let
@@ -220,7 +263,7 @@ readWorkspace { maybeSelectedPackage, pureBuild, migrateConfig } = do
220263
Right config -> do
221264
Right { config, hasTests, configPath: path, packagePath: Path.dirname path }
222265

223-
{ right: otherPackages, left: failedPackages } <- partitionMap identity <$> traverse readWorkspaceConfig otherConfigPaths
266+
{ right: otherPackages, left: failedPackages } <- partitionMap identity <$> traverse readWorkspaceConfig otherLowerConfigPaths
224267
unless (Array.null failedPackages) do
225268
logWarn $ [ toDoc "Failed to read some configs:" ] <> failedPackages
226269

src/Spago/Paths.purs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import Effect.Unsafe (unsafePerformEffect)
66
import Node.Path (FilePath)
77
import Node.Path as Path
88
import Node.Process as Process
9+
import Data.Array (cons, replicate, reverse)
10+
import Data.String (joinWith)
911

1012
type NodePaths =
1113
{ config :: FilePath
@@ -38,6 +40,17 @@ toLocalCachePath rootDir = Path.concat [ rootDir, ".spago" ]
3840
toLocalCachePackagesPath :: FilePath -> FilePath
3941
toLocalCachePackagesPath rootDir = Path.concat [ toLocalCachePath rootDir, "p" ]
4042

43+
-- search maximum 4 levels up the tree to find the Git project, if it exists
44+
toGitSearchPath :: FilePath -> Array FilePath
45+
toGitSearchPath rootDir = reverse $ makeSearchPaths rootDir 2 where
46+
makeSearchPath :: FilePath -> Int -> FilePath
47+
makeSearchPath wd i = joinWith "" $ cons wd $ cons "/" $ replicate i "../"
48+
49+
makeSearchPaths :: FilePath -> Int -> Array FilePath
50+
makeSearchPaths wd 0 = pure wd
51+
makeSearchPaths wd i | i > 0 = cons (makeSearchPath wd i) (makeSearchPaths wd (i - 1))
52+
makeSearchPaths _ _ = mempty
53+
4154
registryPath FilePath
4255
registryPath = Path.concat [ globalCachePath, "registry" ]
4356

test/Spago/Paths.purs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module Test.Spago.Paths where
2+
3+
import Test.Prelude
4+
5+
import Test.Spec (Spec)
6+
import Test.Spec as Spec
7+
import Test.Spec.Assertions as Assert
8+
9+
import Spago.Paths (toGitSearchPath)
10+
11+
spec :: Spec Unit
12+
spec = Spec.around withTempDir do
13+
Spec.describe "paths" do
14+
Spec.it "generate four paths to parent directories of working directory, plus working directory" \ _ -> do
15+
toGitSearchPath "~/a/b/c/d/e" `Assert.shouldEqual`
16+
[ "~/a/b/c/d/e"
17+
, "~/a/b/c/d/e/../"
18+
, "~/a/b/c/d/e/../../"
19+
, "~/a/b/c/d/e/../../../"
20+
, "~/a/b/c/d/e/../../../../"
21+
]

0 commit comments

Comments
 (0)