diff --git a/.gitignore b/.gitignore index daf228f9b..f1f2d0eaf 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ test/spago-test **/__pycache__ templates/docs-search-app.js templates/purescript-docs-search +.DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md index 13163728b..47046ca30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ New features: - `spago run` now recognizes backend specified in the configuration file and calls the backend with `--run` argument. - documentation now includes a step-by-step guide on setting up a Spago/Parcel project (#456) - documentation now includes a step-by-step guide on setting up a Spago/Node and Spago/Webpack project (#456-extra) +- `spago path` returns output path so that it can be shared with tools such as `purs-loader` Bugfixes: - Warn (but don't error) when trying to watch missing directories (#406) diff --git a/README.md b/README.md index 245aac2fe..9e4046807 100644 --- a/README.md +++ b/README.md @@ -1093,6 +1093,13 @@ that is accepted by many commands. You can either: if you want to globally cache a tag or commit that is newer than 24h - the time `spago` will wait before updating its metadata file about "which things are globally cacheable". +### Know the output path for my compiled code + +As there are now various factors that can affect the output path of compiled code, run +`spago path output` along with any flags you would pass to `spago build` (like +`--purs-args` or `--no-share-output`) to return the output path Spago is using. +This can be useful for sharing an output folder with `webpack`, for instance. + ## Explanations ### Visual Overview: What happens when you do 'spago build'? diff --git a/app/Spago.hs b/app/Spago.hs index 17f42274e..9838a0d60 100644 --- a/app/Spago.hs +++ b/app/Spago.hs @@ -12,8 +12,8 @@ import qualified Turtle as CLI import Spago.Build (BuildOptions (..), DepsOnly (..), ExtraArg (..), ModuleName (..), NoBuild (..), NoInstall (..), NoSearch (..), - OpenDocs (..), ShareOutput (..), SourcePath (..), - TargetPath (..), Watch (..), WithMain (..)) + OpenDocs (..), PathType (..), ShareOutput (..), + SourcePath (..), TargetPath (..), Watch (..), WithMain (..)) import qualified Spago.Build import qualified Spago.Config as Config import Spago.Dhall (TemplateComments (..)) @@ -100,6 +100,9 @@ data Command -- | Bundle a module into a CommonJS module (replaced by BundleModule) | MakeModule + -- | Returns output folder for compiled code + | Path (Maybe PathType) BuildOptions + parser :: CLI.Parser (Command, GlobalOptions) parser = do opts <- globalOptions @@ -165,6 +168,7 @@ parser = do , bundleModule , docs , search + , path ] initProject = @@ -221,6 +225,17 @@ parser = do , pure Search ) + pathSubcommand + = CLI.subcommand "output" "Output path for compiled code" + (Path (Just OutputFolder) <$> buildOptions) + <|> (Path Nothing <$> buildOptions) + + path = + ( "path" + , "Display paths used by the project" + , pathSubcommand + ) + packageSetCommands = CLI.subcommandGroup "Package set commands:" [ install , sources @@ -351,5 +366,6 @@ main = do -> Spago.Build.docs format sourcePaths depsOnly noSearch openDocs Search -> Spago.Build.search Version -> printVersion + Path whichPath buildOptions -> Spago.Build.showPaths buildOptions whichPath Bundle -> die Messages.bundleCommandRenamed MakeModule -> die Messages.makeModuleCommandRenamed diff --git a/src/Spago/Build.hs b/src/Spago/Build.hs index 9d1fff931..470e91613 100644 --- a/src/Spago/Build.hs +++ b/src/Spago/Build.hs @@ -7,6 +7,7 @@ module Spago.Build , bundleModule , docs , search + , showPaths , Watch (..) , NoBuild (..) , NoInstall (..) @@ -15,6 +16,7 @@ module Spago.Build , Packages.DepsOnly (..) , NoSearch (..) , OpenDocs (..) + , PathType (..) , Purs.ExtraArg (..) , Purs.ModuleName (..) , Purs.SourcePath (..) @@ -358,6 +360,52 @@ getOutputPath buildOpts = do NoShareOutput -> pure Nothing ShareOutput -> pure outputPath +getOutputPathOrDefault + :: Spago m + => BuildOptions + -> m Sys.FilePath +getOutputPathOrDefault buildOpts + = (fromMaybe "output") <$> getOutputPath buildOpts + +data PathType + = OutputFolder + +-- | Used by `spago path output` command +showOutputPath + :: Spago m + => BuildOptions + -> m () +showOutputPath buildOptions = + echoStr =<< getOutputPathOrDefault buildOptions + +showPaths + :: Spago m + => BuildOptions + -> Maybe PathType + -> m () +showPaths buildOptions whichPaths = + case whichPaths of + (Just OutputFolder) -> showOutputPath buildOptions + Nothing -> showAllPaths buildOptions + +showAllPaths + :: Spago m + => BuildOptions + -> m () +showAllPaths buildOptions = + traverse_ showPath =<< getAllPaths buildOptions + where + showPath (a,b) + = echo (a <> ": " <> b) + +getAllPaths + :: Spago m + => BuildOptions + -> m [(Text, Text)] +getAllPaths buildOptions = do + outputPath <- getOutputPathOrDefault buildOptions + pure [ ("output", Text.pack outputPath) ] + -- | Find an output flag and then return the next item -- | which should be the output folder findOutputFlag :: [Purs.ExtraArg] -> Maybe Sys.FilePath diff --git a/test/SpagoSpec.hs b/test/SpagoSpec.hs index e59d98f32..b2b38ac33 100644 --- a/test/SpagoSpec.hs +++ b/test/SpagoSpec.hs @@ -9,9 +9,9 @@ import Test.Hspec (Spec, around_, describe, it, shouldBe, shou import Turtle (ExitCode (..), cd, cp, decodeString, empty, mkdir, mktree, mv, readTextFile, rm, shell, shellStrictWithErr, testdir, writeTextFile) -import Utils (checkFileHasInfix, checkFixture, readFixture, runFor, - shouldBeFailure, shouldBeFailureOutput, shouldBeSuccess, - shouldBeSuccessOutput, spago, withCwd) +import Utils (checkFileHasInfix, checkFixture, outputShouldEqual, + readFixture, runFor, shouldBeFailure, shouldBeFailureOutput, + shouldBeSuccess, shouldBeSuccessOutput, spago, withCwd) setup :: IO () -> IO () @@ -582,3 +582,26 @@ spec = around_ setup $ do mv "packages.dhall" "packages-old.dhall" writeTextFile "packages.dhall" "https://github.com/purescript/package-sets/releases/download/psc-0.13.4-20191025/packages.dhall sha256:f9eb600e5c2a439c3ac9543b1f36590696342baedab2d54ae0aa03c9447ce7d4" spago ["list-packages", "--json"] >>= shouldBeSuccessOutput "list-packages.json" + + describe "spago path output" $ do + it "Spago should output the correct path" $ do + + -- Create local 'monorepo-1' package that is the real root + mkdir "monorepo-1" + cd "monorepo-1" + spago ["init"] >>= shouldBeSuccess + + -- Create local 'monorepo-2' package that uses packages.dhall on top level + mkdir "monorepo-2" + cd "monorepo-2" + spago ["init"] >>= shouldBeSuccess + rm "packages.dhall" + writeTextFile "packages.dhall" $ "../packages.dhall" + spago ["path", "output"] >>= outputShouldEqual "./../output\n" + + it "Spago should output the local path when no overrides" $ do + + mkdir "monorepo-1" + cd "monorepo-1" + spago ["init"] >>= shouldBeSuccess + spago ["path", "output", "--no-share-output"] >>= outputShouldEqual "output\n" diff --git a/test/Utils.hs b/test/Utils.hs index b652fbb83..db67c89f1 100644 --- a/test/Utils.hs +++ b/test/Utils.hs @@ -4,6 +4,7 @@ module Utils , readFixture , getHighestTag , git + , outputShouldEqual , rmtree , runFor , shouldBeFailure @@ -52,6 +53,10 @@ shouldBeSuccess result@(_code, _stdout, _stderr) = do -- print $ "STDERR: " <> _stderr result `shouldSatisfy` (\(code, _, _) -> code == ExitSuccess) +outputShouldEqual :: HasCallStack => Text -> (ExitCode, Text, Text) -> IO () +outputShouldEqual expected (_,output,_) = do + output `shouldBe` expected + shouldBeSuccessOutput :: HasCallStack => FilePath -> (ExitCode, Text, Text) -> IO () shouldBeSuccessOutput expected (code, stdout, _stderr) = do expectedStdout <- readFixture expected