Skip to content

Commit

Permalink
Read spago.yaml files and use them to create Manifests (#593)
Browse files Browse the repository at this point in the history
  • Loading branch information
f-f authored Mar 12, 2023
1 parent 68dddd9 commit 53a120a
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 30 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ jobs:
- name: "Check that all Dhall compiles, and fixtures correctly conform to a Manifest"
run: nix develop --command 'registry-verify-dhall'

- name: "Install dependencies"
run: nix develop --command 'registry-install'
- name: "Build project"
run: nix develop --command 'registry-build'

- name: "Run tests"
run: nix develop --command 'registry-test'
Expand Down
3 changes: 2 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"registry-foreign": "file:../foreign",
"registry-lib": "file:../lib",
"xhr2": "^0.2.1"
"xhr2": "^0.2.1",
"yaml": "^2.2.1"
}
}
1 change: 1 addition & 0 deletions app/spago.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ package:
- registry-lib
- run
- safe-coerce
- spago-core
- strings
- sunde
- these
Expand Down
99 changes: 77 additions & 22 deletions app/src/App/API.purs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ import Run (AFF, EFFECT, Run)
import Run as Run
import Run.Except (EXCEPT)
import Run.Except as Except
import Spago.Core.Config as Spago
import Spago.Core.Prelude as Spago.Prelude
import Spago.Log as Spago.Log
import Sunde as Sunde

-- | Operations can be exercised for old, pre-registry packages, or for packages
Expand Down Expand Up @@ -371,31 +374,58 @@ publish source payload = do
, "sources indicated by the `files` key in your manifest."
]

-- If this is a legacy import, then we need to construct a `Manifest` for it.
-- If the package doesn't have a purs.json we can try to make one - possible scenarios:
-- - in case it has a spago.yaml then we know how to read that, and have all the info to move forward
-- - if it's a legacy import then we can try to infer as much info as possible to make a manifest
let packagePursJson = Path.concat [ packageDirectory, "purs.json" ]
hadPursJson <- Run.liftEffect $ FS.Sync.exists packagePursJson
unless hadPursJson do
Notify.notify $ "Package source does not have a purs.json file. Creating one from your bower.json and/or spago.dhall files..."
address <- case existingMetadata.location of
Git _ -> Except.throw "Legacy packages can only come from GitHub."
GitHub { subdir: Just subdir } -> Except.throw $ "Legacy packages cannot use the 'subdir' key, but this package specifies a " <> subdir <> " subdir."
GitHub { owner, repo } -> pure { owner, repo }

version <- case LenientVersion.parse payload.ref of
Left _ -> Except.throw $ "The provided ref " <> payload.ref <> " is not a version of the form X.Y.Z or vX.Y.Z, so it cannot be used."
Right result -> pure $ LenientVersion.version result

Legacy.Manifest.fetchLegacyManifest payload.name address (RawVersion payload.ref) >>= case _ of
Left manifestError -> do
let formatError { error, reason } = reason <> " " <> Legacy.Manifest.printLegacyManifestError error
Except.throw $ String.joinWith "\n"
[ "Could not publish your package because there were issues converting its spago.dhall and/or bower.json files into a purs.json manifest:"
, formatError manifestError
]
Right legacyManifest -> do
Log.debug $ "Successfully produced a legacy manifest from the package source. Writing it to the package source..."
let manifest = Legacy.Manifest.toManifest payload.name version existingMetadata.location legacyManifest
Run.liftAff $ writeJsonFile Manifest.codec packagePursJson manifest
let packageSpagoYaml = Path.concat [ packageDirectory, "spago.yaml" ]
hasSpagoYaml <- Run.liftEffect $ FS.Sync.exists packageSpagoYaml
case hasSpagoYaml of
true -> do
Notify.notify $ "Package source does not have a purs.json file, creating one from your spago.yaml file..."
-- Need to make a Spago log env first, disable the logging
let spagoEnv = { logOptions: { color: false, verbosity: Spago.Log.LogQuiet } }
maybeConfig <- Spago.Prelude.runSpago spagoEnv (Spago.readConfig packageSpagoYaml)
case maybeConfig of
Left err' -> Except.throw $ String.joinWith "\n"
[ "Could not publish your package - a spago.yaml was present, but it was not possible to read it:"
, err'
]
Right { yaml: config } -> do
-- Once we have the config we are still not entirely sure it fits into a Manifest
-- E.g. need to make sure all the ranges are present
case spagoToManifest config of
Left err -> Except.throw $ String.joinWith "\n"
[ "Could not publish your package - there was an error while converting your spago.yaml into a purs.json manifest:"
, err
]
Right manifest -> do
Log.debug "Successfully converted a spago.yaml into a purs.json manifest"
Run.liftAff $ writeJsonFile Manifest.codec packagePursJson manifest
false -> do
Notify.notify $ "Package source does not have a purs.json file. Creating one from your bower.json and/or spago.dhall files..."
address <- case existingMetadata.location of
Git _ -> Except.throw "Legacy packages can only come from GitHub."
GitHub { subdir: Just subdir } -> Except.throw $ "Legacy packages cannot use the 'subdir' key, but this package specifies a " <> subdir <> " subdir."
GitHub { owner, repo } -> pure { owner, repo }

version <- case LenientVersion.parse payload.ref of
Left _ -> Except.throw $ "The provided ref " <> payload.ref <> " is not a version of the form X.Y.Z or vX.Y.Z, so it cannot be used."
Right result -> pure $ LenientVersion.version result

Legacy.Manifest.fetchLegacyManifest payload.name address (RawVersion payload.ref) >>= case _ of
Left manifestError -> do
let formatError { error, reason } = reason <> " " <> Legacy.Manifest.printLegacyManifestError error
Except.throw $ String.joinWith "\n"
[ "Could not publish your package because there were issues converting its spago.dhall and/or bower.json files into a purs.json manifest:"
, formatError manifestError
]
Right legacyManifest -> do
Log.debug $ "Successfully produced a legacy manifest from the package source. Writing it to the package source..."
let manifest = Legacy.Manifest.toManifest payload.name version existingMetadata.location legacyManifest
Run.liftAff $ writeJsonFile Manifest.codec packagePursJson manifest

Log.debug "A valid purs.json is available in the package source."

Expand Down Expand Up @@ -981,3 +1011,28 @@ getPacchettiBotti = do

packagingTeam :: Team
packagingTeam = { org: "purescript", team: "packaging" }

spagoToManifest :: Spago.Config -> Either String Manifest
spagoToManifest config = do
package@{ name, description, dependencies: Spago.Dependencies deps } <- note "Did not find a package in the config" config.package
publishConfig@{ version, license } <- note "Did not find a `publish` section in the package config" package.publish
location <- note "Did not find a `location` field in the publish config" publishConfig.location
let
checkRange :: Tuple PackageName (Maybe Range) -> Either PackageName (Tuple PackageName Range)
checkRange (Tuple packageName maybeRange) = case maybeRange of
Nothing -> Left packageName
Just r -> Right (Tuple packageName r)
let { fail: failedPackages, success } = partitionEithers $ map checkRange (Map.toUnfoldable deps :: Array _)
dependencies <- case failedPackages of
[] -> Right (Map.fromFoldable success)
errs -> Left $ "The following packages did not have their ranges specified: " <> String.joinWith ", " (map PackageName.print errs)
pure $ Manifest
{ version
, license
, name
, location
, description
, dependencies
, owners: Nothing -- TODO Spago still needs to add this to its config
, files: Nothing -- TODO Spago still needs to add this to its config
}
4 changes: 2 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@
scripts = pkgs.symlinkJoin {
name = "scripts";
paths = pkgs.lib.mapAttrsToList pkgs.writeShellScriptBin {
registry-install = ''
registry-build = ''
cd $(git rev-parse --show-toplevel)
npm ci
spago install
spago build
'';

registry-test = ''
Expand Down
20 changes: 18 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"workspaces": [
"app",
"foreign",
"lib"
]
}
7 changes: 6 additions & 1 deletion spago.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
workspace:
package_set:
registry: 2.2.0
registry: 11.10.0
extra_packages:
spago-core:
git: https://github.com/purescript/spago.git
ref: ad81065f577436185bd0fe4bfb88714363ffca15
subdir: spaghetto/core

0 comments on commit 53a120a

Please sign in to comment.