diff --git a/README.md b/README.md index 5fe306efd..489da98ea 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![build](https://github.com/purescript/spago/actions/workflows/build.yml/badge.svg)](https://github.com/purescript/spago/actions/workflows/build.yml) [![Maintainer: f-f](https://img.shields.io/badge/maintainer-f%2d-f-teal.svg)](http://github.com/f-f) -*(IPA: /ˈspaɡo/)* +_(IPA: /ˈspaɡo/)_ PureScript package manager and build tool. @@ -22,16 +22,18 @@ PureScript package manager and build tool. > This new Spago is still in alpha, so while most of it works well, there will be some rough edges here and there. Please report them if you find any! The recommended installation method for Windows, Linux and macOS is `npm` (see the latest releases on npm - [here][spago-npm]): +[here][spago-npm]): ``` npm install -g spago@next ``` Other installation methods available: + - With Nix, using [purescript-overlay] **General notes:** + - The assumption is that you already installed the [PureScript compiler][purescript]. If not, get it with `npm install -g purescript`, or the recommended method for your OS. - You might have issues with `npm` and Docker (e.g. getting the message "Downloading the spago binary failed.." etc) @@ -39,7 +41,6 @@ Other installation methods available: - either **do not run npm as root**, because it doesn't work well with binaries. Use it as a nonprivileged user. - or use `--unsafe-perm`: `npm install -g --unsafe-perm spago@next` - ## Super quick tutorial Let's set up a new project! @@ -63,6 +64,7 @@ This last command will create a few files: ``` If you have a look at the `spago.yaml` file, you'll see that it contains two sections: + - [the `workspace` section](#the-workspace), which details the configuration for the _dependencies_ of the project as a whole (which can be a monorepo, and contain more than one package), and other general configuration settings. In this sample project, the only configuration needed is the [package set](#whats-a-package-set) version from which all the dependencies will be chosen. See [here](#querying-package-sets) for more info about how to query the package sets. - [the `package` section](#whats-a-package), that is about the configuration of the package at hand, such as its name, dependencies, and so on. @@ -76,6 +78,7 @@ $ spago run ``` This will: + - download and compile the necessary dependencies (equivalent to `spago install`) - compile this sample project in the `output/` directory (equivalent to `spago build`).\ You can take a look at the content of `output/Main/index.js` to see what kind of JavaScript has been generated from your new `Main.purs` file @@ -95,6 +98,7 @@ $ node . Great! If you read unitl here you should be set to go write some PureScript without worrying too much about the build 😊 Where to go from here? There are a few places you should check out: + - see [the "How to achieve X"](#how-do-i) section for practical advice without too much explanation - see instead the [Concepts and Explanations](#concepts-and-explanations) section for more in-depth explanations about the concepts that power Spago, such as [package sets](#whats-a-package-set), or [the Workspace](#the-workspace). @@ -153,10 +157,10 @@ Where to go from here? There are a few places you should check out: - ## Design goals and reasons Our main design goals are: + - **Great UX**: a good build system just does what's most expected and gets out of the way so you can focus on actually thinking about the software itself, instead of spending your time configuring the build. - **Minimal dependencies**: users should not be expected to install a myriad of tools on their system to support various workflows. Spago only expects `git` and `purs` to be installed. - **Reproducible builds**: we exploit [package sets](#whats-a-package-set) and [lock files](#the-lock-file) to make your build reproducible, so that if your project builds today it will also build tomorrow and every day after that. @@ -169,6 +173,7 @@ Some tools that inspired `spago` are: [Rust's Cargo][cargo], [Haskell's Stack][s We'd love your help, and welcome PRs and contributions! Some ideas for getting started: + - [Build and run `spago`](CONTRIBUTING.md#developing-spago) - [Help us fix bugs and build features](https://github.com/purescript/spago/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+label%3A%22defect%22) - Help us improve our documentation @@ -176,7 +181,6 @@ Some ideas for getting started: For more details see the [`CONTRIBUTING.md`][contributing] - ## How do I... This section contains a collection of mini-recipes you might want to follow in order to get things done with Spago. @@ -203,10 +207,12 @@ rm spago.dhall packages.dhall Some packages might not be found or have the wrong version, in which case you'll have to carefully: + - try to run `spago install some-package` for packages found in the package set (see [how to query the set](#querying-package-sets)) - [add the packages that are missing from the set](#add-a-package-to-the-package-set) In **all** cases, you'll want to switch to the new Registry package sets, so replace something like this: + ```yaml workspace: package_set: @@ -214,6 +220,7 @@ workspace: ``` ...with this: + ```yaml workspace: package_set: @@ -317,7 +324,7 @@ $ spago build This is mostly just a thin layer above the PureScript compiler command `purs compile`. -*Note*: by default the `build` command will try to install any dependencies that haven't been +_Note_: by default the `build` command will try to install any dependencies that haven't been fetched yet - if you wish to disable this behaviour, you can pass the `--no-install` flag. The build will produce very many JavaScript files in the `output/` folder. These @@ -326,10 +333,13 @@ are ES modules, and you can just `import` them e.g. on Node. > [!NOTE]\ > The wrapper on the compiler is so thin that you can pass options to `purs`. > E.g. if you wish to ask `purs` to emit errors in JSON format, you can run +> > ```console > $ spago build --purs-args "--json-errors" > ``` +> > However, some `purs` flags are covered by Spago ones, e.g. to change the location of the `output` folder: +> > ```console > $ spago build --output myOutput > ``` @@ -353,6 +363,7 @@ $ spago build --before clear --before "notify-send 'Building'" ``` If you want to run the program, just use `run`: + ```console $ spago run -p package-name -m Module.Containing.Main @@ -377,7 +388,7 @@ spago run -p package-name --purs-args "--verbose-errors" # package: # run: # main: Main -# execArgs: +# exec_args: # - "arg1" # - "arg2" $ spago run -p package-name @@ -543,7 +554,6 @@ workspace: > If the upstream library that you are adding has a `spago.yaml` file, then Spago will just pick up the dependencies from there. > If that's not the case, then you'll have the provide the dependencies yourself, adding a `dependencies` field. - As you might expect, this works also in the case of adding local packages: ```yaml @@ -638,6 +648,7 @@ This package set could look something like this: The second format possible is what Spago calls a `LegacyPackageSet`, and it's simply a map from package names to the location of the package, described as the (4) option for how to specify `extra_packages` in the [configuration format section](#the-configuration-file). Something like this: + ```js { "legacy-package-style": { @@ -698,6 +709,7 @@ The vast majority of Spago projects will contain only one package, defined in th It is however possible to define multiple packages in the same repository! The basic rules are: + - [a package](#whats-a-package) is defined by a `spago.yaml` file containing a `package` section. - there can be only one `workspace` section in the whole repository, which defines the "root" of the current [Spago Workspace](#the-workspace). This defines your package set/build plan. - Spago will autodetect all the packages inside the workspace @@ -731,6 +743,7 @@ Then your file tree might look like this: ``` Where: + - the top level `spago.yaml` could look like this: ```yaml @@ -745,9 +758,9 @@ Where: package: name: lib1 dependencies: - - effect - - console - - prelude + - effect + - console + - prelude ``` - then, assuming `lib2` depends on `lib1`, `lib2/spago.yaml` might look like this: @@ -756,14 +769,14 @@ Where: package: name: lib2 dependencies: - - effect - - console - - prelude - - lib1 # <------ Note the dependency here + - effect + - console + - prelude + - lib1 # <------ Note the dependency here tests: main: Test.Lib2.Main dependencies: - - spec + - spec ``` - and then `app1/spago.yaml` would look something like this: @@ -773,9 +786,9 @@ Where: name: app1 # Note that the app does not include all the dependencies that the lib included dependencies: - - prelude - - aff # This dep was not used by the library - - lib2 # And we have `lib2` as a dependency + - prelude + - aff # This dep was not used by the library + - lib2 # And we have `lib2` as a dependency ``` Given this setup, Spago will figure out that there are three separate packages in the repository. @@ -828,16 +841,18 @@ The file tree might look like this: ``` Where the `common/spago.yaml` is just a package with no workspace defined, as it's going to support both the JS and the Erlang backend: + ```yaml package: name: common dependencies: - - effect - - console - - prelude + - effect + - console + - prelude ``` Then the `client/spago.yaml` might look like this: + ```yaml workspace: package_set: @@ -848,12 +863,13 @@ workspace: package: name: client dependencies: - - prelude - - common - - halogen + - prelude + - common + - halogen ``` And the `server/spago.yaml` might look like this: + ```yaml workspace: package_set: @@ -866,12 +882,13 @@ workspace: package: name: server dependencies: - - prelude - - common - - erl-process + - prelude + - common + - erl-process ``` This all means that: + - there is a [Spago Workspace](#the-workspace) in the `client` folder, another one in the `server` folder, but none in the `common` folder - the `common` package is shared between the two workspaces, note that it's included as a local package in both - the `client` workspace uses the default JS package set, and the `server` workspace uses a Purerl package set @@ -885,13 +902,13 @@ Like this: package: name: mypackage dependencies: - - effect - - console - - prelude + - effect + - console + - prelude tests: main: Test.Main dependencies: - - spec + - spec ``` You can add more with `spago install --test-deps some-new-package`. @@ -905,6 +922,7 @@ This is a good-defaults wrapper into `esbuild`, and it's meant to be used for bu See the [`esbuild` getting started][install-esbuild] for installation instructions. This command supports a few options, and the most important ones are: + - the `--bundle-type` flag, which can be either `app` or `module` - the `--platform` flag, which can be either `browser` or `node` @@ -930,6 +948,7 @@ $ spago bundle --bundle-type module --main Main --outfile index.js ``` Can now import it in your Node project: + ```console $ node -e "import('./index.js').then(m => console.log(m.main))" [Function] @@ -940,23 +959,28 @@ $ node -e "import('./index.js').then(m => console.log(m.main))" When bundling, you can include `--source-maps` to generate a final source map for your bundle. Example: + ```console spago bundle -p my-project --source-maps --minify --outfile=bundle.js ``` + will generate a minified bundle: `bundle.js`, and a source map: `bundle.js.map`. #### Node -If your target platform is node, then you need to ensure your node version is >= 12.2.0 and [enable source maps](https://nodejs.org/dist/latest-v20.x/docs/api/cli.html#--enable-source-maps -) when executing your script: + +If your target platform is node, then you need to ensure your node version is >= 12.2.0 and [enable source maps](https://nodejs.org/dist/latest-v20.x/docs/api/cli.html#--enable-source-maps) when executing your script: + ```console spago bundle -p my-project --platform node --source-maps --minify --outfile=bundle.js node --enable-source-maps bundle.js ``` #### Browsers + If you are targeting browsers, then you will need to ensure your server is configured to serve the source map from the same directory as your bundle. So for example if your server is configured to serve files from `public/`, you might run: + ```console spago bundle -p my-project --platform browser --source-maps --minify --outfile=public/bundle.js ``` @@ -981,6 +1005,7 @@ The file itself is stored in the `.spago` folder if you'd like to have a look at To build documentation for your project and its dependencies (i.e. a "project-local [Pursuit][pursuit]"), you can use the `docs` command: + ```console $ spago docs ``` @@ -989,12 +1014,14 @@ This will generate all the documentation in the `./generated-docs` folder of you You might then want to open the `index.html` file in there. If you wish for the documentation to be opened in browser when generated, you can pass an `open` flag: + ```console $ spago docs --open ``` You can customize the output to other formats beyond html. Supported formats include ctags, etags, and markdown. For example to generate ctags for use in your editor: + ```console $ spago docs --format ctags ``` @@ -1005,7 +1032,6 @@ Sometimes you'd like to pull up docs for dependencies even when you have compila $ spago docs --deps-only` ``` - ### Alternate backends Spago supports compiling with alternate purescript backends, such as [purerl]. @@ -1084,6 +1110,7 @@ This section details some of the concepts that are useful to know when using Spa ### What's a "package"? Spago considers a "package" any folder that contains: + - a `spago.yaml` file with a valid `package` section - a `src` subfolder with PureScript source files @@ -1092,6 +1119,7 @@ That's all there is to it! You can have many of these in your repository if you' The above holds for "workspace packages", i.e. the packages for which you have the source locally, and inside your repository. These are the packages "in your project". Packages on which your project depends on can come from a few different sources: + - [the Registry][registry] - local packages - i.e. packages that are on your filesystem but external to your repository - remote packages - i.e. packages that are not on your filesystem, but somewhere on the internet @@ -1107,6 +1135,7 @@ Packages have "dependencies", which are other packages that are required for the The most generic way of defining a "package set" is "a collection of package versions that are known to build together". The point of a package set is to provide a "stable" set of packages that you can use to build your project, without worrying about version conflicts. In practice, it looks something like [this][sample-package-set]: + ```json { "version": "41.2.0", @@ -1143,6 +1172,7 @@ For any software project, it's usually possible to find a clear line between "th Following this line of reasoning, Spago - taking inspiration from other tools such as [Bazel][bazel] - uses the concept of of a "workspace" to characterise the sum of all the project packages and their dependencies (including only "potential" ones). A very succint introduction to this idea can be found [in Bazel's documentation][bazel-workspace]: + > A workspace is a directory tree on your filesystem that contains the source files for the software you want to build.\ > Each workspace has a text file named `WORKSPACE` which may be empty, or may contain references to external dependencies required to build the outputs.\ > Directories containing a file called `WORKSPACE` are considered the root of a workspace.\ @@ -1151,6 +1181,7 @@ A very succint introduction to this idea can be found [in Bazel's documentation] Spago goes by these same rules, with the difference that we do not use a separate `WORKSPACE` file, but instead use the `workspace` section of the `spago.yaml` file to define what the set of our external dependencies are, and where they come from. This can be as simple as: + ```yaml workspace: {} ``` @@ -1158,6 +1189,7 @@ workspace: {} ...which means that "this is now a workspace, and all the dependencies are going to be fetched from the Registry". Or it can be more complex, e.g.: + ```yaml workspace: package_set: @@ -1266,18 +1298,18 @@ workspace: # Specify whether to censor warnings coming from the compiler # for files in the `.spago` directory`. # Optional and can be one of two possible values - censor_library_warnings: + censor_library_warnings: # Value 1: "all" - All warnings are censored all # Value 2: `NonEmptyArray (Either String { by_prefix :: String })` - # - String values: + # - String values: # censor warnings if the code matches this code - # - { by_prefix } values: - # censor warnings if the warning's message + # - { by_prefix } values: + # censor warnings if the warning's message # starts with the given text - CodeName - # Note: when using `by_prefix`, use the `>` for block-string: + # Note: when using `by_prefix`, use the `>` for block-string: # see https://yaml-multiline.info/ - by_prefix: > "Data.Map"'s `Semigroup instance` @@ -1318,22 +1350,22 @@ package: # Fail the build if this package's `dependencies` field has redundant/underspecified packages. # Optional boolean that defaults to `false`. pedantic_packages: false - + # Specify whether to censor warnings coming from the compiler # for files from this package. # Optional and can be one of two possible values - censor_project_warnings: + censor_project_warnings: # Value 1: "all" - All warnings are censored all # Value 2: `NonEmptyArray (Either String { by_prefix :: String })` - # - String values: + # - String values: # censor warnings if the code matches this code - # - { by_prefix } values: - # censor warnings if the warning's message + # - { by_prefix } values: + # censor warnings if the warning's message # starts with the given text - CodeName - # Note: when using `by_prefix`, use the `>` for block-string: + # Note: when using `by_prefix`, use the `>` for block-string: # see https://yaml-multiline.info/ - by_prefix: > "Data.Map"'s `Semigroup instance` @@ -1367,7 +1399,7 @@ package: # The entrypoint for the program main: Main # List of arguments to pass to the program - execArgs: + exec_args: - "--cli-arg" - "foo" @@ -1379,7 +1411,7 @@ package: dependencies: - foo # Optional list of arguments to pass to the test program - execArgs: + exec_args: - "--cli-arg" - "foo" @@ -1390,18 +1422,18 @@ package: # Specify whether to censor warnings coming from the compiler # for files from this package's test code. # Optional and can be one of two possible values - censor_test_warnings: + censor_test_warnings: # Value 1: "all" - All warnings are censored all # Value 2: `NonEmptyArray (Either String { by_prefix :: String })` - # - String values: + # - String values: # censor warnings if the code matches this code - # - { by_prefix } values: - # censor warnings if the warning's message + # - { by_prefix } values: + # censor warnings if the warning's message # starts with the given text - CodeName - # Note: when using `by_prefix`, use the `>` for block-string: + # Note: when using `by_prefix`, use the `>` for block-string: # see https://yaml-multiline.info/ - by_prefix: > "Data.Map"'s `Semigroup instance` @@ -1488,13 +1520,15 @@ packages, you should run the appropriate package-manager for that (e.g. npm). ### Differences from legacy spago #### Watch mode -Spago dropped support for the --watch flag in `spago build` and `spago test`. + +Spago dropped support for the --watch flag in `spago build` and `spago test`. VSCode users are recommended to use the [Purescript IDE](purescript-ide) extension for seamless experiences with automatic rebuilds. Users of other editors, e.g. vim, emacs, etc., can make use of the underlying [LSP plugin](purescript-language-server). If you want a very simple drop in replacement for `spago test --watch`, you can use a general purpose tool such as [watchexec]: + ```console watchexec -e purs,js,yaml -- spago test ``` diff --git a/bin/src/Flags.purs b/bin/src/Flags.purs index f0ee98304..ef76036e5 100644 --- a/bin/src/Flags.purs +++ b/bin/src/Flags.purs @@ -285,4 +285,3 @@ depsOnly = ( O.long "deps-only" <> O.help "Build depedencies only" ) - diff --git a/bin/src/Main.purs b/bin/src/Main.purs index e3e15d819..939b2b2ed 100644 --- a/bin/src/Main.purs +++ b/bin/src/Main.purs @@ -740,7 +740,7 @@ mkRunEnv runArgs { dependencies, purs } = do runConf f = selected.package.run >>= f moduleName = fromMaybe "Main" (runArgs.main <|> runConf _.main) - execArgs = fromMaybe [] (runArgs.execArgs <|> runConf _.execArgs) + execArgs = fromMaybe [] (runArgs.execArgs <|> runConf _.exec_args) runOptions = { moduleName @@ -770,7 +770,7 @@ mkTestEnv testArgs { dependencies, purs } = do testConf f = selected.package.test >>= f moduleName = fromMaybe "Test.Main" (testConf (_.main >>> Just)) - execArgs = fromMaybe [] (testArgs.execArgs <|> testConf _.execArgs) + execArgs = fromMaybe [] (testArgs.execArgs <|> testConf _.exec_args) in { moduleName , execArgs diff --git a/core/src/Config.purs b/core/src/Config.purs index 1e5303336..3229998cb 100644 --- a/core/src/Config.purs +++ b/core/src/Config.purs @@ -39,7 +39,6 @@ module Spago.Core.Config import Spago.Core.Prelude -import Data.Array.NonEmpty (NonEmptyArray) import Data.Array.NonEmpty as NonEmptyArray import Data.Codec.Argonaut as CA import Data.Codec.Argonaut.Record as CAR @@ -57,6 +56,7 @@ import Registry.Range as Range import Registry.Sha256 as Sha256 import Registry.Version as Version import Spago.FS as FS +import Type.Proxy (Proxy(..)) type Config = { package :: Maybe PackageConfig @@ -64,10 +64,10 @@ type Config = } configCodec :: JsonCodec Config -configCodec = CAR.object "Config" - { package: CAR.optional packageConfigCodec - , workspace: CAR.optional workspaceConfigCodec - } +configCodec = CA.object "Config" + $ CA.recordPropOptional (Proxy :: _ "package") packageConfigCodec + $ CA.recordPropOptional (Proxy :: _ "workspace") workspaceConfigCodec + $ CA.record type PackageConfig = { name :: PackageName @@ -81,16 +81,16 @@ type PackageConfig = } packageConfigCodec :: JsonCodec PackageConfig -packageConfigCodec = CAR.object "PackageConfig" - { name: PackageName.codec - , description: CAR.optional CA.string - , dependencies: dependenciesCodec - , build: CAR.optional packageBuildOptionsCodec - , bundle: CAR.optional bundleConfigCodec - , run: CAR.optional runConfigCodec - , test: CAR.optional testConfigCodec - , publish: CAR.optional publishConfigCodec - } +packageConfigCodec = CA.object "PackageConfig" + $ CA.recordProp (Proxy :: _ "name") PackageName.codec + $ CA.recordPropOptional (Proxy :: _ "description") CA.string + $ CA.recordProp (Proxy :: _ "dependencies") dependenciesCodec + $ CA.recordPropOptional (Proxy :: _ "build") packageBuildOptionsCodec + $ CA.recordPropOptional (Proxy :: _ "bundle") bundleConfigCodec + $ CA.recordPropOptional (Proxy :: _ "run") runConfigCodec + $ CA.recordPropOptional (Proxy :: _ "test") testConfigCodec + $ CA.recordPropOptional (Proxy :: _ "publish") publishConfigCodec + $ CA.record type PublishConfig = { version :: Version @@ -101,28 +101,28 @@ type PublishConfig = } publishConfigCodec :: JsonCodec PublishConfig -publishConfigCodec = CAR.object "PublishConfig" - { version: Version.codec - , license: License.codec - , location: CAR.optional Location.codec - , include: CAR.optional (CA.array CA.string) - , exclude: CAR.optional (CA.array CA.string) - } +publishConfigCodec = CA.object "PublishConfig" + $ CA.recordProp (Proxy :: _ "version") Version.codec + $ CA.recordProp (Proxy :: _ "license") License.codec + $ CA.recordPropOptional (Proxy :: _ "location") Location.codec + $ CA.recordPropOptional (Proxy :: _ "include") (CA.array CA.string) + $ CA.recordPropOptional (Proxy :: _ "exclude") (CA.array CA.string) + $ CA.record type RunConfig = { main :: Maybe String - , execArgs :: Maybe (Array String) + , exec_args :: Maybe (Array String) } runConfigCodec :: JsonCodec RunConfig -runConfigCodec = CAR.object "RunConfig" - { main: CAR.optional CA.string - , execArgs: CAR.optional (CA.array CA.string) - } +runConfigCodec = CA.object "RunConfig" + $ CA.recordPropOptional (Proxy :: _ "main") CA.string + $ CA.recordPropOptional (Proxy :: _ "exec_args") (CA.array CA.string) + $ CA.record type TestConfig = { main :: String - , execArgs :: Maybe (Array String) + , exec_args :: Maybe (Array String) , dependencies :: Dependencies , censor_test_warnings :: Maybe CensorBuildWarnings , strict :: Maybe Boolean @@ -130,14 +130,14 @@ type TestConfig = } testConfigCodec :: JsonCodec TestConfig -testConfigCodec = CAR.object "TestConfig" - { main: CA.string - , execArgs: CAR.optional (CA.array CA.string) - , dependencies: dependenciesCodec - , censor_test_warnings: CAR.optional censorBuildWarningsCodec - , strict: CAR.optional CA.boolean - , pedantic_packages: CAR.optional CA.boolean - } +testConfigCodec = CA.object "TestConfig" + $ CA.recordProp (Proxy :: _ "main") CA.string + $ CA.recordPropOptional (Proxy :: _ "exec_args") (CA.array CA.string) + $ CA.recordPropOptional (Proxy :: _ "censor_test_warnings") censorBuildWarningsCodec + $ CA.recordPropOptional (Proxy :: _ "strict") CA.boolean + $ CA.recordPropOptional (Proxy :: _ "pedantic_packages") CA.boolean + $ CA.recordProp (Proxy :: _ "dependencies") dependenciesCodec + $ CA.record type BackendConfig = { cmd :: String @@ -145,10 +145,10 @@ type BackendConfig = } backendConfigCodec :: JsonCodec BackendConfig -backendConfigCodec = CAR.object "BackendConfig" - { cmd: CA.string - , args: CAR.optional (CA.array CA.string) - } +backendConfigCodec = CA.object "BackendConfig" + $ CA.recordProp (Proxy :: _ "cmd") CA.string + $ CA.recordPropOptional (Proxy :: _ "args") (CA.array CA.string) + $ CA.record type PackageBuildOptionsInput = { censor_project_warnings :: Maybe CensorBuildWarnings @@ -157,11 +157,11 @@ type PackageBuildOptionsInput = } packageBuildOptionsCodec :: JsonCodec PackageBuildOptionsInput -packageBuildOptionsCodec = CAR.object "PackageBuildOptionsInput" - { censor_project_warnings: CAR.optional censorBuildWarningsCodec - , strict: CAR.optional CA.boolean - , pedantic_packages: CAR.optional CA.boolean - } +packageBuildOptionsCodec = CA.object "PackageBuildOptionsInput" + $ CA.recordPropOptional (Proxy :: _ "censor_project_warnings") censorBuildWarningsCodec + $ CA.recordPropOptional (Proxy :: _ "strict") CA.boolean + $ CA.recordPropOptional (Proxy :: _ "pedantic_packages") CA.boolean + $ CA.record type BundleConfig = { minify :: Maybe Boolean @@ -173,14 +173,14 @@ type BundleConfig = } bundleConfigCodec :: JsonCodec BundleConfig -bundleConfigCodec = CAR.object "BundleConfig" - { minify: CAR.optional CA.boolean - , module: CAR.optional CA.string - , outfile: CAR.optional CA.string - , platform: CAR.optional bundlePlatformCodec - , type: CAR.optional bundleTypeCodec - , extra_args: CAR.optional (CA.array CA.string) - } +bundleConfigCodec = CA.object "BundleConfig" + $ CA.recordPropOptional (Proxy :: _ "minify") CA.boolean + $ CA.recordPropOptional (Proxy :: _ "module") CA.string + $ CA.recordPropOptional (Proxy :: _ "outfile") CA.string + $ CA.recordPropOptional (Proxy :: _ "platform") bundlePlatformCodec + $ CA.recordPropOptional (Proxy :: _ "type") bundleTypeCodec + $ CA.recordPropOptional (Proxy :: _ "extra_args") (CA.array CA.string) + $ CA.record data BundlePlatform = BundleNode | BundleBrowser @@ -292,13 +292,13 @@ type WorkspaceConfig = } workspaceConfigCodec :: JsonCodec WorkspaceConfig -workspaceConfigCodec = CAR.object "WorkspaceConfig" - { package_set: CAR.optional setAddressCodec - , extra_packages: CAR.optional (Internal.Codec.packageMap extraPackageCodec) - , backend: CAR.optional backendConfigCodec - , build_opts: CAR.optional buildOptionsCodec - , lock: CAR.optional CA.boolean - } +workspaceConfigCodec = CA.object "WorkspaceConfig" + $ CA.recordPropOptional (Proxy :: _ "lock") CA.boolean + $ CA.recordPropOptional (Proxy :: _ "package_set") setAddressCodec + $ CA.recordPropOptional (Proxy :: _ "backend") backendConfigCodec + $ CA.recordPropOptional (Proxy :: _ "build_opts") buildOptionsCodec + $ CA.recordPropOptional (Proxy :: _ "extra_packages") (Internal.Codec.packageMap extraPackageCodec) + $ CA.record type WorkspaceBuildOptionsInput = { output :: Maybe FilePath @@ -307,11 +307,11 @@ type WorkspaceBuildOptionsInput = } buildOptionsCodec :: JsonCodec WorkspaceBuildOptionsInput -buildOptionsCodec = CAR.object "WorkspaceBuildOptionsInput" - { output: CAR.optional CA.string - , censor_library_warnings: CAR.optional censorBuildWarningsCodec - , stat_verbosity: CAR.optional statVerbosityCodec - } +buildOptionsCodec = CA.object "WorkspaceBuildOptionsInput" + $ CA.recordPropOptional (Proxy :: _ "output") CA.string + $ CA.recordPropOptional (Proxy :: _ "censor_library_warnings") censorBuildWarningsCodec + $ CA.recordPropOptional (Proxy :: _ "stat_verbosity") statVerbosityCodec + $ CA.record data CensorBuildWarnings = CensorAllWarnings @@ -457,12 +457,12 @@ type GitPackage = } gitPackageCodec :: JsonCodec GitPackage -gitPackageCodec = CAR.object "GitPackage" - { git: CA.string - , ref: CA.string - , subdir: CAR.optional CA.string - , dependencies: CAR.optional dependenciesCodec - } +gitPackageCodec = CA.object "GitPackage" + $ CA.recordProp (Proxy :: _ "git") CA.string + $ CA.recordProp (Proxy :: _ "ref") CA.string + $ CA.recordPropOptional (Proxy :: _ "subdir") CA.string + $ CA.recordPropOptional (Proxy :: _ "dependencies") dependenciesCodec + $ CA.record -- | The format of a legacy packages.json package set entry for an individual -- | package. @@ -473,11 +473,11 @@ type LegacyPackageSetEntry = } legacyPackageSetEntryCodec :: JsonCodec LegacyPackageSetEntry -legacyPackageSetEntryCodec = CAR.object "LegacyPackageSetEntry" - { dependencies: CA.array PackageName.codec - , repo: CA.string - , version: CA.string - } +legacyPackageSetEntryCodec = CA.object "LegacyPackageSetEntry" + $ CA.recordProp (Proxy :: _ "repo") CA.string + $ CA.recordProp (Proxy :: _ "version") CA.string + $ CA.recordProp (Proxy :: _ "dependencies") (CA.array PackageName.codec) + $ CA.record readConfig :: forall a. FilePath -> Spago (LogEnv a) (Either String { doc :: YamlDoc Config, yaml :: Config }) readConfig path = do diff --git a/src/Spago/Command/Init.purs b/src/Spago/Command/Init.purs index 9d6114b76..5cc2adeb1 100644 --- a/src/Spago/Command/Init.purs +++ b/src/Spago/Command/Init.purs @@ -161,7 +161,7 @@ defaultConfig' opts = , run: Nothing , test: test <#> \{ moduleMain, censorTestWarnings, strict, pedanticPackages, dependencies: testDeps } -> { dependencies: fromMaybe (Dependencies Map.empty) testDeps - , execArgs: Nothing + , exec_args: Nothing , main: moduleMain , censor_test_warnings: censorTestWarnings , strict diff --git a/src/Spago/Config.js b/src/Spago/Config.js index 9e4460dd3..d722b4bac 100644 --- a/src/Spago/Config.js +++ b/src/Spago/Config.js @@ -12,7 +12,7 @@ export function addPackagesToConfigImpl(doc, isTest, newPkgs) { const deps = (() => { if (isTest) { - const test = getOrElse(pkg, "test", doc.createNode({ dependencies: [], main: "Test.Main" })); + const test = getOrElse(pkg, "test", doc.createNode({ main: "Test.Main", dependencies: [] })); return getOrElse(test, "dependencies", doc.createNode([])); } else { return getOrElse(pkg, "dependencies", doc.createNode([])) diff --git a/test-fixtures/check-strict.yaml b/test-fixtures/check-strict.yaml index d64bf8e32..62841a9b9 100644 --- a/test-fixtures/check-strict.yaml +++ b/test-fixtures/check-strict.yaml @@ -7,6 +7,6 @@ package: build: strict: true workspace: - extra_packages: {} package_set: registry: 41.5.0 + extra_packages: {} diff --git a/test-fixtures/list-dependencies.json b/test-fixtures/list-dependencies.json index c06ed2cc6..be20bd440 100644 --- a/test-fixtures/list-dependencies.json +++ b/test-fixtures/list-dependencies.json @@ -4,15 +4,15 @@ "value": { "hasTests": true, "package": { + "name": "aaa2", "dependencies": [ "console", "effect", "prelude" ], - "name": "aaa2", "test": { - "dependencies": [], - "main": "Subpackage.Test.Main" + "main": "Subpackage.Test.Main", + "dependencies": [] } }, "path": "subpackage" diff --git a/test-fixtures/list-packages.json b/test-fixtures/list-packages.json index 536edfa3a..1f578df65 100644 --- a/test-fixtures/list-packages.json +++ b/test-fixtures/list-packages.json @@ -4,16 +4,16 @@ "value": { "hasTests": true, "package": { + "name": "aaa", "dependencies": [ "aaa2", "console", "effect", "prelude" ], - "name": "aaa", "test": { - "dependencies": [], - "main": "Test.Main" + "main": "Test.Main", + "dependencies": [] } }, "path": "./" @@ -24,15 +24,15 @@ "value": { "hasTests": true, "package": { + "name": "aaa2", "dependencies": [ "console", "effect", "prelude" ], - "name": "aaa2", "test": { - "dependencies": [], - "main": "Subpackage.Test.Main" + "main": "Subpackage.Test.Main", + "dependencies": [] } }, "path": "subpackage" diff --git a/test-fixtures/local-package-set-config.yaml b/test-fixtures/local-package-set-config.yaml index fa14dd29a..0dde24b4a 100644 --- a/test-fixtures/local-package-set-config.yaml +++ b/test-fixtures/local-package-set-config.yaml @@ -1,13 +1,13 @@ package: + name: aaaa dependencies: - console - effect - prelude - name: aaaa test: - dependencies: [] main: Test.Main + dependencies: [] workspace: - extra_packages: {} package_set: path: local-package-set.json + extra_packages: {} diff --git a/test-fixtures/local-package-set-config2.yaml b/test-fixtures/local-package-set-config2.yaml index cd5a5b2a3..f7649e376 100644 --- a/test-fixtures/local-package-set-config2.yaml +++ b/test-fixtures/local-package-set-config2.yaml @@ -1,13 +1,13 @@ package: + name: aaaa dependencies: - console - effect - prelude - name: aaaa test: - dependencies: [] main: Test.Main + dependencies: [] workspace: - extra_packages: {} package_set: path: ../local-package-set.json + extra_packages: {} diff --git a/test-fixtures/no-test-section.yaml b/test-fixtures/no-test-section.yaml index 37d23d92f..4d519b943 100644 --- a/test-fixtures/no-test-section.yaml +++ b/test-fixtures/no-test-section.yaml @@ -1,10 +1,10 @@ package: + name: aaa dependencies: - console - effect - prelude - name: aaa workspace: - extra_packages: {} package_set: registry: 29.3.0 + extra_packages: {} diff --git a/test-fixtures/older-package-set-tag.yaml b/test-fixtures/older-package-set-tag.yaml index 9f7dbab2d..7cc3fa03e 100644 --- a/test-fixtures/older-package-set-tag.yaml +++ b/test-fixtures/older-package-set-tag.yaml @@ -1,13 +1,13 @@ package: + name: 7368613235362d47665357393342584955783641314b70674c dependencies: - console - effect - prelude - name: 7368613235362d47665357393342584955783641314b70674c test: - dependencies: [] main: Test.Main + dependencies: [] workspace: - extra_packages: {} package_set: registry: 9.0.0 + extra_packages: {} diff --git a/test-fixtures/spago-install-failure.yaml b/test-fixtures/spago-install-failure.yaml index e240a3b22..ee4cdbf39 100644 --- a/test-fixtures/spago-install-failure.yaml +++ b/test-fixtures/spago-install-failure.yaml @@ -1,13 +1,13 @@ package: + name: aaaa dependencies: - console - effect - prelude - name: aaaa test: - dependencies: [] main: Test.Main + dependencies: [] workspace: - extra_packages: {} package_set: registry: 29.3.0 + extra_packages: {} diff --git a/test-fixtures/spago-install-success.yaml b/test-fixtures/spago-install-success.yaml index 6f8cec6b8..f3130cbd6 100644 --- a/test-fixtures/spago-install-success.yaml +++ b/test-fixtures/spago-install-success.yaml @@ -1,14 +1,14 @@ package: + name: aaa dependencies: - console - effect - foreign - prelude - name: aaa test: - dependencies: [] main: Test.Main + dependencies: [] workspace: - extra_packages: {} package_set: registry: 29.3.0 + extra_packages: {} diff --git a/test-fixtures/spago-install-test-deps-success.yaml b/test-fixtures/spago-install-test-deps-success.yaml index 8b006dd08..653b26de6 100644 --- a/test-fixtures/spago-install-test-deps-success.yaml +++ b/test-fixtures/spago-install-test-deps-success.yaml @@ -1,14 +1,14 @@ package: + name: aaa dependencies: - console - effect - prelude - name: aaa test: + main: Test.Main dependencies: - foreign - main: Test.Main workspace: - extra_packages: {} package_set: registry: 29.3.0 + extra_packages: {} diff --git a/test-fixtures/spago-publish.yaml b/test-fixtures/spago-publish.yaml index 0d9c1d0fd..bd1e89f90 100644 --- a/test-fixtures/spago-publish.yaml +++ b/test-fixtures/spago-publish.yaml @@ -1,12 +1,12 @@ package: + name: aaa dependencies: - console: ">=6.0.0 <7.0.0" - effect: ">=4.0.0 <5.0.0" - prelude: ">=6.0.1 <7.0.0" - name: aaa test: - dependencies: [] main: Test.Main + dependencies: [] publish: version: 0.0.1 license: MIT @@ -14,7 +14,7 @@ package: githubOwner: purescript githubRepo: aaa workspace: - extra_packages: - console: "6.1.0" package_set: registry: 28.1.1 + extra_packages: + console: "6.1.0" diff --git a/test-fixtures/spago-subpackage-install-success.yaml b/test-fixtures/spago-subpackage-install-success.yaml index b5097c803..c1b602bcd 100644 --- a/test-fixtures/spago-subpackage-install-success.yaml +++ b/test-fixtures/spago-subpackage-install-success.yaml @@ -1,10 +1,10 @@ package: + name: subpackage dependencies: - console - effect - either - prelude - name: subpackage test: - dependencies: [] main: Subpackage.Test.Main + dependencies: [] diff --git a/test-fixtures/spago-with-hash.yaml b/test-fixtures/spago-with-hash.yaml index 31be11fff..99cc7d074 100644 --- a/test-fixtures/spago-with-hash.yaml +++ b/test-fixtures/spago-with-hash.yaml @@ -1,14 +1,14 @@ package: + name: aaa dependencies: - console - effect - prelude - name: aaa test: - dependencies: [] main: Test.Main + dependencies: [] workspace: - extra_packages: {} package_set: url: https://raw.githubusercontent.com/purescript/registry/main/package-sets/29.3.0.json hash: sha256-LJoXQjRcY0IkP1YJMwvhKAtb4NpxoJW5A6DxapTI+as= + extra_packages: {} diff --git a/test/Spago/Build.purs b/test/Spago/Build.purs index 9d9c7b467..3b9db3271 100644 --- a/test/Spago/Build.purs +++ b/test/Spago/Build.purs @@ -148,7 +148,7 @@ spec = Spec.around withTempDir do , strict: Nothing , censor_test_warnings: Nothing , dependencies: mkDependencies [ "newtype" ] - , execArgs: Nothing + , exec_args: Nothing } } }