Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
f-f committed Jul 8, 2019
2 parents b12ea08 + 3be573a commit bf71f81
Show file tree
Hide file tree
Showing 24 changed files with 620 additions and 46 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,11 @@ script:
'cd spago && stack build --test --no-run-tests --copy-bins --local-bin-path ./artifacts'
fi
nvm install 10 && nvm use 10
npm install -g psc-package@3.0.1
npm install -g psc-package@3.0.1 bower@1.8.8
# get newest purescript from github releases
TAG=$(wget -q -O - https://github.com/purescript/purescript/releases/latest --server-response --max-redirect 0 2>&1 | sed -n -e 's/.*Location:.*tag\///p')
TAG="v0.13.0"
wget -O $HOME/purescript.tar.gz https://github.com/purescript/purescript/releases/download/$TAG/$PURS_OS.tar.gz
tar -xvf $HOME/purescript.tar.gz -C $HOME/
chmod a+x $HOME/purescript
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Bugfixes:
New features:
- Add support for starting a repl within a folder which has not been setup as a spago project (#168)
- Add `--format` flag to `spago docs` (#294)
- Add `--no-config-format` global flag to skip formatting Dhall files during operations. (#300, #302)
- Add `bump-version` command, for generating `bower.json` files and making version tags in Git (#203)

## [0.8.5] - 2019-06-18

Expand Down
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,17 @@ $ spago run --node-args "arg1 arg2"
```


### Avoid re-formatting the `spago.dhall` and `packages.dhall` with each command

You can pass the `--no-config-format` or `-F` global flag:

``` bash
$ spago build -F
Installation complete.
Build succeeded.
```


### Test my project

You can also test your project with `spago`:
Expand Down Expand Up @@ -709,22 +720,21 @@ $ spago docs --format ctags

If you wish to develop a library with `spago` you can definitely do so, and use it to
manage and build your project, until you need to "publish" your library, where you'll need
to use `bower`.
to use `pulp`.
When you decide you want to publish your library for others to use, you should:
- make a Bowerfile that includes the dependencies from `spago.dhall`
- run `pulp version`
- run `pulp publish`
- run `spago bump-version --no-dry-run <BUMP>`. This will generate a `bower.json` in a new commit in Git that is tagged with the version.
- run `pulp publish`. This will ensure the package is registered in Bower, push the version tag to Git and upload documentation to Pursuit.
This is because the PureScript ecosystem uses the Bower registry as a "unique names registry".
So in order to "publish" a package one needs to add it there, and eventually to [`package-sets`][package-sets].
Consequentially, package-sets requires (full instructions [here][package-sets-contributing])
that packages in it:
- are in the Bower registry
- use `pulp version` (because this gives versions with `vX.Y.Z`)
- use `spago bump-version` or `pulp version` (because this gives versions with `vX.Y.Z`)
- use `pulp publish` (so that's it's available on the Bower registry and on [Pursuit][pursuit])
All of this will be automated in future versions.
All of this will be automated in future versions, removing the need for Pulp.
A library published in this way is [purescript-rave](https://github.com/reactormonk/purescript-rave).
Expand Down
2 changes: 1 addition & 1 deletion app/Curator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ withAST path transform = do
newExpr <- transformMExpr transform expr
echo $ "Done. Updating the \"" <> path <> "\" file.."
writeTextFile (pathFromText path) $ Dhall.prettyWithHeader header newExpr <> "\n"
liftIO $ Dhall.format path
liftIO $ Dhall.format DoFormat path
where
transformMExpr
:: Monad m
Expand Down
45 changes: 40 additions & 5 deletions app/Spago.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,21 @@ import qualified Paths_spago as Pcli
import qualified System.Environment as Env
import qualified Turtle as CLI

import Spago.Build (BuildOptions (..), ExtraArg (..), ModuleName (..),
NoBuild (..), SourcePath (..), TargetPath (..), Watch (..),
WithMain (..), NoInstall (..))
import Spago.Build (BuildOptions (..), ExtraArg (..),
ModuleName (..), SourcePath (..),
TargetPath (..), Watch (..),
WithMain (..), NoBuild (..),
NoInstall (..))
import qualified Spago.Build
import Spago.DryRun (DryRun (..))
import Spago.GlobalCache (CacheFlag (..))
import Spago.Messages as Messages
import Spago.Packages (PackageName (..), PackagesFilter (..), JsonFlag(..))
import qualified Spago.Packages
import qualified Spago.PscPackage as PscPackage
import qualified Spago.Purs as Purs
import Spago.Version (VersionBump(..))
import qualified Spago.Version as Version
import Spago.Watch (ClearScreen (..))


Expand Down Expand Up @@ -58,6 +63,9 @@ data Command
-- | Test the project with some module, default Test.Main
| Test (Maybe ModuleName) BuildOptions [ExtraArg]

-- | Bump and tag a new version in preparation for release.
| BumpVersion DryRun VersionBump

-- | Run the project with some module, default Main
| Run (Maybe ModuleName) BuildOptions [ExtraArg]

Expand Down Expand Up @@ -109,11 +117,12 @@ data Command
parser :: CLI.Parser (Command, GlobalOptions)
parser = do
opts <- globalOptions
command <- projectCommands <|> packageSetCommands <|> pscPackageCommands <|> otherCommands <|> oldCommands
command <- projectCommands <|> packageSetCommands <|> publishCommands <|> pscPackageCommands <|> otherCommands <|> oldCommands
pure (command, opts)
where
force = CLI.switch "force" 'f' "Overwrite any project found in the current directory"
verbose = CLI.switch "verbose" 'v' "Enable additional debug logging, e.g. printing `purs` commands"
noConfigFormat = CLI.switch "no-config-format" 'F' "Disable formatting the configuration file `spago.dhall`"
watchBool = CLI.switch "watch" 'w' "Watch for changes in local files and automatically rebuild"
noInstallBool = CLI.switch "no-install" 'n' "Don't run the automatic installation of packages"
clearScreenBool = CLI.switch "clear-screen" 'l' "Clear the screen on rebuild (watch mode only)"
Expand All @@ -139,6 +148,11 @@ parser = do
pure $ case res of
True -> NoBuild
False -> DoBuild
noFormat = do
res <- noConfigFormat
pure $ case res of
True -> NoFormat
False -> DoFormat
jsonFlagBool = CLI.switch "json" 'j' "Produce JSON output"
jsonFlag = do
res <- jsonFlagBool
Expand All @@ -151,6 +165,15 @@ parser = do
"update" -> Just NewCache
_ -> Nothing
in CLI.optional $ CLI.opt wrap "global-cache" 'c' "Configure the global caching behaviour: skip it with `skip` or force update with `update`"
versionBump =
let spec = \case
"major" -> Just Version.Major
"minor" -> Just Version.Minor
"patch" -> Just Version.Patch
v | Right v' <- Version.parseVersion v -> Just $ Exact v'
_ -> Nothing
in CLI.arg spec "bump" "How to bump the version. Acceptable values: 'major', 'minor', 'patch', or a version (e.g. 'v1.2.3')."
dryRun = bool DryRun NoDryRun <$> CLI.switch "no-dry-run" 'f' "Actually perform side-effects (the default is to describe what would be done)"
mainModule = CLI.optional (CLI.opt (Just . ModuleName) "main" 'm' "Module to be used as the application's entry point")
toTarget = CLI.optional (CLI.opt (Just . TargetPath) "to" 't' "The target file path")
limitJobs = CLI.optional (CLI.optInt "jobs" 'j' "Limit the amount of jobs that can run concurrently")
Expand All @@ -160,7 +183,7 @@ parser = do
replPackageNames = CLI.many $ CLI.opt (Just . PackageName) "dependency" 'd' "Package name to add to the REPL as dependency"
passthroughArgs = many $ CLI.arg (Just . ExtraArg) " ..any `purs compile` option" "Options passed through to `purs compile`; use -- to separate"
buildOptions = BuildOptions <$> limitJobs <*> cacheFlag <*> watch <*> clearScreen <*> sourcePaths <*> noInstall <*> passthroughArgs
globalOptions = GlobalOptions <$> verbose
globalOptions = GlobalOptions <$> verbose <*> noFormat
packagesFilter =
let wrap = \case
"direct" -> Just DirectDeps
Expand Down Expand Up @@ -281,6 +304,17 @@ parser = do
)


publishCommands = CLI.subcommandGroup "Publish commands:"
[ bumpVersion
]

bumpVersion =
( "bump-version"
, "Bump and tag a new version, and generate bower.json, in preparation for release."
, BumpVersion <$> dryRun <*> versionBump
)


pscPackageCommands = CLI.subcommandGroup "Psc-Package compatibility commands:"
[ pscPackageLocalSetup
, pscPackageInsDhall
Expand Down Expand Up @@ -352,6 +386,7 @@ main = do
Freeze -> Spago.Packages.freeze
Build buildOptions -> Spago.Build.build buildOptions Nothing
Test modName buildOptions nodeArgs -> Spago.Build.test modName buildOptions nodeArgs
BumpVersion dryRun spec -> Version.bumpVersion dryRun spec
Run modName buildOptions nodeArgs -> Spago.Build.run modName buildOptions nodeArgs
Repl limitJobs cacheConfig replPackageNames paths pursArgs -> Spago.Build.repl limitJobs cacheConfig replPackageNames paths pursArgs
BundleApp modName tPath shouldBuild buildOptions
Expand Down
4 changes: 3 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ install:
- choco install -y haskell-stack --version %STACK_VERSION%
- stack setup > nul
- choco install psc-package
- npm install -g bower
- set PATH=%APPDATA%\npm;%PATH%
- ps: |
$releases = "https://api.github.com/repos/purescript/purescript/releases"
$tag = (Invoke-WebRequest $releases | ConvertFrom-Json)[0].tag_name
$tag = "v0.13.0"
$download = "https://github.com/purescript/purescript/releases/download/$tag/win64.tar.gz"
Invoke-WebRequest $download -Out purescript.tar.gz
- tar -xvf purescript.tar.gz
Expand Down
1 change: 1 addition & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ library:
- aeson
- aeson-pretty
- containers
- bower-json
- dhall
- dhall-json
- bytestring
Expand Down
109 changes: 109 additions & 0 deletions src/Spago/Bower.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
module Spago.Bower
( bowerPath
, writeBowerJson
, runBowerInstall
) where

import Spago.Prelude

import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Encode.Pretty as Pretty
import qualified Data.ByteString.Lazy as ByteString
import qualified Data.Map as Map
import Data.String (IsString)
import Web.Bower.PackageMeta (PackageMeta (..))
import qualified Web.Bower.PackageMeta as Bower

import Spago.Config (Config (..), PublishConfig (..))
import qualified Spago.Config as Config
import Spago.DryRun (DryRun (..))
import qualified Spago.Git as Git
import qualified Spago.GlobalCache as GlobalCache
import Spago.GlobalCache (RepoMetadataV1 (..), Tag (..))
import qualified Spago.Packages as Packages
import Spago.PackageSet (PackageName (..), Package (..), PackageLocation(..))
import qualified Spago.Templates as Templates


bowerPath :: IsString t => t
bowerPath = "bower.json"


writeBowerJson :: Spago m => DryRun -> m ()
writeBowerJson dryRun = do
config@Config{..} <- Config.ensureConfig
PublishConfig{..} <- throws publishConfig

bowerName <- mkPackageName name
bowerDependencies <- mkDependencies config
template <- templateBowerJson

let bowerLicense = [publishLicense]
bowerRepository = Just $ Bower.Repository publishRepository "git"
bowerPkg = template { bowerLicense, bowerRepository, bowerName, bowerDependencies }
prettyConfig = Pretty.defConfig
{ Pretty.confCompare = Pretty.keyOrder ["name", "license", "repository", "ignore", "dependencies"] <> compare
, Pretty.confTrailingNewline = True
}
bowerJson = Pretty.encodePretty' prettyConfig bowerPkg

ignored <- Git.isIgnored bowerPath
when ignored $ do
die $ bowerPath <> " is being ignored by git - change this before continuing."

case dryRun of
DryRun -> echo $ "Skipped writing " <> bowerPath <> " because this is a dry run."
NoDryRun -> do
liftIO $ ByteString.writeFile bowerPath bowerJson
echo $ "Generated " <> bowerPath <> " using the package set."


runBowerInstall :: Spago m => DryRun -> m ()
runBowerInstall = \case
DryRun -> echo "Skipped running `bower install` because this is a dry run."
NoDryRun -> do
echo "Running `bower install` so `pulp publish` can read resolved versions from it."
shell "bower install --silent" empty >>= \case
ExitSuccess -> pure ()
ExitFailure _ -> die "Failed to run `bower install` on your package"


templateBowerJson :: Spago m => m Bower.PackageMeta
templateBowerJson = do
case Aeson.decodeStrict Templates.bowerJson of
Just t ->
pure t
Nothing ->
die "Invalid bower.json template (this is a Spago bug)"


mkPackageName :: Spago m => Text -> m Bower.PackageName
mkPackageName spagoName = do
let psName = "purescript-" <> spagoName
case Bower.mkPackageName psName of
Left err ->
die $ psName <> " is not a valid Bower package name: " <> Bower.showPackageNameError err
Right name ->
pure name


mkDependencies :: Spago m => Config -> m [(Bower.PackageName, Bower.VersionRange)]
mkDependencies config = do

reposMeta <- GlobalCache.getMetadata Nothing
deps <- Packages.getDirectDeps config

for deps $ \(PackageName{..}, Package{..}) -> do
case location of
Local path ->
die $ "Unable to create Bower version for local repo: " <> path
Remote{..} | not (isTag packageName version reposMeta) ->
die $ "Unable to create Bower version from non-tag version: " <> packageName <> " " <> version
Remote{..} -> do
bowerName <- mkPackageName packageName
pure (bowerName, Bower.VersionRange $ "^" <> version)
where
isTag packageName version reposMeta =
isJust $ do
RepoMetadataV1{..} <- Map.lookup (PackageName packageName) reposMeta
Map.lookup (Tag version) tags
2 changes: 1 addition & 1 deletion src/Spago/Build.hs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ repl maybeLimit cacheFlag newPackages sourcePaths passthroughArgs = do

config@Config.Config{ packageSet = PackageSet.PackageSet{..}, ..} <- Config.ensureConfig

let updatedConfig = Config.Config name (dependencies <> newPackages) (Config.packageSet config) configSourcePaths
let updatedConfig = Config.Config name (dependencies <> newPackages) (Config.packageSet config) configSourcePaths publishConfig

deps <- Packages.getProjectDeps updatedConfig
let globs = Packages.getGlobs deps <> Config.configSourcePaths updatedConfig <> sourcePaths
Expand Down
Loading

0 comments on commit bf71f81

Please sign in to comment.