{"id":13610478,"url":"https://github.com/purescript-contrib/pulp","last_synced_at":"2026-03-17T22:06:50.597Z","repository":{"id":516649,"uuid":"20595322","full_name":"purescript-contrib/pulp","owner":"purescript-contrib","description":"A build tool for PureScript projects","archived":false,"fork":false,"pushed_at":"2022-06-18T00:44:22.000Z","size":1025,"stargazers_count":444,"open_issues_count":39,"forks_count":82,"subscribers_count":11,"default_branch":"master","last_synced_at":"2026-02-17T00:25:41.850Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PureScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/purescript-contrib.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-06-07T14:49:36.000Z","updated_at":"2025-09-29T06:53:04.000Z","dependencies_parsed_at":"2022-08-16T10:25:30.239Z","dependency_job_id":null,"html_url":"https://github.com/purescript-contrib/pulp","commit_stats":null,"previous_names":["bodil/pulp"],"tags_count":73,"template":false,"template_full_name":null,"purl":"pkg:github/purescript-contrib/pulp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purescript-contrib%2Fpulp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purescript-contrib%2Fpulp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purescript-contrib%2Fpulp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purescript-contrib%2Fpulp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/purescript-contrib","download_url":"https://codeload.github.com/purescript-contrib/pulp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purescript-contrib%2Fpulp/sbom","scorecard":{"id":246676,"data":{"date":"2025-08-11","repo":{"name":"github.com/purescript-contrib/pulp","commit":"78f7aa6ae76337ea6f8362cac03fb1c8ee1858cd"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.9,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":4,"reason":"Found 13/29 approved changesets -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/purescript-contrib/pulp/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/purescript-contrib/pulp/ci.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:54","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: GNU Lesser General Public License v3.0: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 19 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"57 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-p6mr-pxg4-68hx","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-wg6g-ppvx-927h","Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2","Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc","Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-fvqr-27wr-82fm","Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574","Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-hxm2-r34f-qmc5","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-5g97-whc9-8g7j","Warn: Project is vulnerable to: GHSA-8r4g-cg4m-x23c","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-g6ww-v8xp-vmwg","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-g4rg-993r-mgx7","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-29xr-v42j-r956","Warn: Project is vulnerable to: GHSA-884p-74jh-xrg2","Warn: Project is vulnerable to: GHSA-j7fq-p9q7-5wfv","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T07:44:03.605Z","repository_id":516649,"created_at":"2025-08-17T07:44:03.605Z","updated_at":"2025-08-17T07:44:03.605Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30628720,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T17:32:55.572Z","status":"ssl_error","status_checked_at":"2026-03-17T17:32:38.732Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T19:01:45.070Z","updated_at":"2026-03-17T22:06:50.541Z","avatar_url":"https://github.com/purescript-contrib.png","language":"PureScript","funding_links":[],"categories":["PureScript","Libraries and Tools"],"sub_categories":["Other Useful Tools"],"readme":"# \u003ca href=\"https://travis-ci.org/purescript-contrib/pulp\"\u003e\u003cimg alt=\"Travis CI status\" align=\"right\" src=\"https://travis-ci.org/purescript-contrib/pulp.svg?branch=master\"\u003e\u003c/a\u003e \u003ca href=\"https://ci.appveyor.com/project/hdgarrood/pulp\"\u003e\u003cimg alt=\"AppVeyor CI status\" align=\"right\" src=\"https://ci.appveyor.com/api/projects/status/c1naeh5i9991na5k?svg=true\"\u003e\u003c/a\u003e Pulp\n\n[![Join the chat at https://gitter.im/bodil/pulp](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bodil/pulp?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nA build tool for PureScript.\n\n![Jarvis Cocker dancing](http://24.media.tumblr.com/77b76c557515a801a7e99ca5507b6548/tumblr_n5cx52oT831r4ba6to1_400.gif)\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n\n- [Installation](#installation)\n- [Getting Started with a Pulp Project](#getting-started-with-a-pulp-project)\n  - [What if I need something a bit more complicated?](#what-if-i-need-something-a-bit-more-complicated)\n- [Pulp Commands](#pulp-commands)\n  - [Global, Command Specific and Pass-Through Options](#global-command-specific-and-pass-through-options)\n    - [Pass-Through Options](#pass-through-options)\n- [Building Projects](#building-projects)\n  - [Making a JavaScript Bundle](#making-a-javascript-bundle)\n  - [Running Your PureScript Project](#running-your-purescript-project)\n  - [Running Test Suites](#running-test-suites)\n  - [Running Commands Before and After an Action](#running-commands-before-and-after-an-action)\n  - [CommonJS Aware Builds](#commonjs-aware-builds)\n    - [Optimising Code Size](#optimising-code-size)\n    - [Reimporting Browserified Bundles](#reimporting-browserified-bundles)\n  - [Building Documentation](#building-documentation)\n  - [Launching a REPL](#launching-a-repl)\n  - [Launching a Development Server](#launching-a-development-server)\n    - [A Quick Example](#a-quick-example)\n    - [I Need More](#i-need-more)\n- [Dependency Management](#dependency-management)\n  - [Dependency Management Cheat Sheet](#dependency-management-cheat-sheet)\n    - [Installing Dependencies](#installing-dependencies)\n    - [Housekeeping](#housekeeping)\n  - [Releasing Packages](#releasing-packages)\n    - [Publishing Packages](#publishing-packages)\n- [Development](#development)\n- [Licence](#licence)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Installation\n\nAssuming you already have [Node](https://nodejs.org/en/download/) set\nup (and we recommend you also set up NPM to\n[keep your global packages in your home directory](https://github.com/sindresorhus/guides/blob/master/npm-global-without-sudo.md)),\nall you need to do to get a working PureScript environment is:\n\n```sh\n$ npm install -g purescript pulp bower\n```\n\nThis installs the PureScript compiler, the Pulp build tool, and the\n[Bower](http://bower.io/) package manager.\n\n*Aside: if you're familiar with the JavaScript ecosystem and you're wondering\nwhy PureScript uses Bower and not npm, you might be interested to read [Why the\nPureScript community uses Bower](http://harry.garrood.me/blog/purescript-why-bower/).\nOtherwise, please ignore this and read on.*\n\n## Getting Started with a Pulp Project\n\nThe short version:\n\n```sh\n$ mkdir purescript-hello\n$ cd purescript-hello\n$ pulp init\n$ pulp run\n```\n\nThe structure of your project folder, after running `pulp init`, will\nlook like this:\n\n```\n  purescript-hello\n  - bower.json\n  - src/\n  - test/\n```\n\n`pulp` works by convention. It expects all projects to contain a manifest file\nfor package management (usually `bower.json`, since package management in\nPureScript is usually handled by [Bower](http://bower.io/)).\n\nYour project source files go in the `src` folder. Your test files go in the\n`test` folder. Project dependencies will be installed under the Bower standard\n`bower_components` folder, and are expected to have the same basic `src`/`test`\nstructure. That's all there is to a `pulp` project.\n\nWe employ the `purescript-` prefix as a convention to identify PureScript\nprojects when they're used as dependencies. You're welcome to call your project\nanything you like, but without the `purescript-` prefix it won't be picked up\nby `pulp` as a dependency.\n\n### What if I need something a bit more complicated?\n\nIf you want to change any of these defaults, you can—`pulp` offers a\nnumber of command line flags to alter its behaviour—but try to avoid using\nthem unless you have a good reason to.\n\nIf you get fed up with having to remember long `pulp` invocations, try\n[using `npm` as your build tool](http://substack.net/task_automation_with_npm_run).\n`pulp`'s numerous command line flags make it well suited for this.\n\nIf that's still not enough, you might try using a more generic build tool,\nsuch as [webpack](https://webpack.github.io/) with\n[purs-loader](https://github.com/ethul/purs-loader), or\n[gulp](http://gulpjs.com) with\n[gulp-purescript](https://github.com/purescript-contrib/gulp-purescript).\n\n## Pulp Commands\n\nTo get a quick overview of the things `pulp` can do, you can ask it to\ngive you a list of its available commands:\n\n```sh\n$ pulp --help\n```\n\nThis will print a list of `pulp`'s global command line options, and a\nlist of commands it will accept.\n\nTo see the available options for a specific command, you can invoke\nthe command with the `--help` flag, like this:\n\n```sh\n$ pulp build --help\n```\n\nThis will give you an exhaustive list of ways you can modify the basic\nbehaviour of the command.\n\n### Global, Command Specific and Pass-Through Options\n\nNotice that there's a distinction between _global_ command line\noptions and command specific options. Global options must appear\n_before_ the name of the command, and command specific options must\nappear _after_ it.\n\nThus, if you want to run the `build` command in watch mode (where it\nwill run the command once, then wait and re-run the command whenever\nyou change a source file) you need to put the `--watch` flag _before_\nthe command itself, like so:\n\n```sh\n$ pulp --watch build\n```\n\nOn the other hand, if you want to tell the build command to produce\noptimised code (performing dead code elimination), using the command\nspecific option `--optimise`, the flag needs to come _after_ the\ncommand name:\n\n```sh\n$ pulp build --optimise\n```\n\n#### Pass-Through Options\n\nFinally, `pulp` commands sometimes allows you to pass flags through to\nthe `purs` compiler. Any options appearing after `--` will be passed through to\nthe compiler, or whichever process a `pulp` command spawns. For instance, if\nyou want to tell `purs` to skip applying tail call optimisations, you would\ninvoke `pulp build` like this:\n\n```sh\n$ pulp build -- --no-tco\n```\n\n## Building Projects\n\nAt heart, `pulp` is just a frontend for the PureScript compiler,\n`purs`. Its basic function is to compile your project, which you can do\nby running `pulp build`. This will simply run `purs compile` with all your\nsource files, leaving the compiled JavaScript files in the `output`\nfolder. These files will all be CommonJS modules, which you can\n`require()` using anything which supports CommonJS, such as `node`.\n\nHowever, you will usually want to do more with your project than just\ncompile your PureScript code into a jumble of CommonJS modules. `pulp`\nprovides a number of commands and options for the most common use\ncases.\n\n### Making a JavaScript Bundle\n\n`pulp build` can also call `purs bundle` for you, which is a compiler\ntool whose job it is to take the output from `purs compile`, remove the code\nwhich isn't actually being used by your program, and bundle it all up\ninto a single compact JavaScript file.\n\nThere are two command line options you can give `pulp build` to\naccomplish this, depending on where you want the resulting code. You\ncan use the `--optimise` flag (or its shorthand alias, `-O`), which\nwill send the bundled result to standard output, or you can use the\n`--to` (or `-t`) option, passing it a file name, and `pulp` will store\nthe bundle in a file of that name.\n\nSo, you can use either of these methods, which in this example will\nboth have the same effect:\n\n```sh\n$ pulp build --optimise \u003e hello.js\n$ pulp build --to hello.js\n```\n\nNote that using both options (`pulp build --optimise --to hello.js`)\nis superfluous. The presence of `--to` implies the presence of\n`--optimise`.\n\n### Running Your PureScript Project\n\nIf you're developing a Node project using PureScript, you can tell\n`pulp` to run it after compiling using the `pulp run` command. This\ncommand will first run `pulp build` for you, if necessary, then launch\nyour compiled code using `node`. If you have used any pass-through\ncommand line options, these will be passed to the `node` process.\n\nSo, to run the hello world project you get from `pulp init`, you would\nsimply:\n\n```sh\n$ pulp run\n```\n\nIf you want to pass command line arguments to your application, `pulp`\nlets you do that too:\n\n```sh\n$ pulp run -- file1.txt file2.txt file3.txt\n```\n\nIf you want to run your application using something other than `node`,\n`pulp` lets you do that too, with the `--runtime` option. For instance,\nif you've written an application which runs on PhantomJS, you might\nlaunch it like this:\n\n```sh\n$ pulp run --runtime phantomjs\n```\n\n### Running Test Suites\n\n`pulp` has a command `pulp test`, which works much like `pulp run`,\nexcept it will also compile the code you've placed in your `test`\nfolder, and instead of running the `main` function in your `Main`\nmodule, it will use `Test.Main`. This module should be located in your\n`test` folder.\n\n`pulp` doesn't care what test framework you've chosen, as long as\nthere's a `main` function in your `Test.Main` module to be run. If the\nprocess exits with a non-zero return code, that means your test suite\nfailed, as far as `pulp` is concerned, and it will itself exit with an\nerror.\n\nIn short, to run your tests:\n\n```sh\n$ pulp test\n```\n\nTo continuously run your tests when you change the source code:\n\n```sh\n$ pulp --watch test\n```\n\n### Running Commands Before and After an Action\n\nIt's sometimes useful to kick off a command before or after an action,\nparticularly in combination with the `--watch` option above. To do\nthis, you can use `--before`, or `--then` and `--else` for successful\nor failing actions respectively:\n\n```sh\n$ pulp --watch --before clear build       # Clears the screen before builds.\n$ pulp --watch --then 'say Done' build    # On OS X, announces 'Done' after a successful build.\n$ pulp --watch --else 'say Failed' build  # Announces 'Failed' if a build failed.\n\n# A more long-winded example combining the three:\n$ pulp --watch --before clear --then \"say $(basename `pwd`) succeeded.\" --else 'say $(basename `pwd`) failed.' build\n```\n\n\n### CommonJS Aware Builds\n\nOften, you'll want to go outside PureScript and leverage some of the\nenormous body of JavaScript code available on\n[NPM](https://www.npmjs.com/). This is such a common use case that\n`pulp` provides a command for it: `pulp browserify`. As the name\nsuggests, this uses [Browserify](http://browserify.org/) to bundle up\nyour PureScript code with Node style CommonJS dependencies.\n\nFor instance, the majority of web UI libraries for PureScript these\ndays depend on either\n[virtual-dom](https://github.com/Matt-Esch/virtual-dom) or\n[React](https://facebook.github.io/react/) as a CommonJS dependency.\nHere is how you would add React to your project and build a JS bundle\nwith React included (assuming your PureScript code `require`s it):\n\n```sh\n$ npm install react\n$ pulp browserify --to hello.js\n```\n\nEssentially, `pulp browserify --to` works exactly like `pulp build\n--to`, except it also resolves CommonJS dependencies and includes them\nin the bundle. The resulting JS file can now be loaded directly into\nthe browser, and everything you need to run your application should be\nincluded.\n\nIf you omit the `--to` option, the bundle is piped to standard output.\nThis would thus have the same effect as the example above:\n\n```sh\n$ pulp browserify \u003e hello.js\n```\n\n#### Optimising Code Size\n\n`pulp browserify` will pull code in at the module level by default, so\nevery file `require`d from your entry point will appear in the bundle.\nThe PureScript compiler, as we know, is able to perform dead code\nelimination on your compiled PureScript code, and we can leverage this\nin `pulp browserify` using the `--optimise` flag.\n\n```sh\n$ pulp browserify --optimise --to hello.js\n```\n\nNote that, unlike `pulp build`, `--to` doesn't automatically imply\n`--optimise`. In fact, if you omit `--optimise`, `pulp browserify`\nwill not only omit the dead code elimination step, it will also run\nBrowserify as an incremental build, which means it will run\nconsiderably faster. You should use `--optimise` only when you're\nbuilding production code—when you're developing, you'll probably\nprefer the much faster compile times provided by Browserify's\nincremental mode.\n\n#### Reimporting Browserified Bundles\n\nWhile browserified bundles are intended to be consumed directly by\nbrowsers, you may sometimes prefer to access the bundle from some\nexternal code. While it's generally preferable to consume CommonJS\nmodules directly, there are use cases where you might want to provide\na single JS file ready to be `require`d by a consumer without needing\nto deal with installing and resolving dependencies. Browserify\nprovides the `--standalone` mechanism for that, and `pulp browserify`\nsupports it:\n\n```sh\n$ pulp browserify --standalone myBundle --to myBundle.js\n```\n\nThis makes a bundle which comes wrapped in a UMD header (meaning it\nsupports both CommonJS and AMD, and will install itself in the global\nnamespace under the name you provided if neither is present), and the\nexports it provides will be the same as those you export in your\n`Main` module.\n\nSo, given the example above produces a bundle where a PureScript\nfunction `Main.main` exists, you can access it from JavaScript via\nCommonJS like this:\n\n```javascript\nvar myBundle = require(\"./myBundle\");\nmyBundle.main();\n```\n\n### Building Documentation\n\nPureScript has an inline syntax for documentation, which can be\nextracted into Markdown or HTML files using the `purs docs` command. `pulp`\nprovides the `pulp docs` command to make this process easy:\n\n```sh\n$ pulp docs [--with-dependencies]\n```\n\nThis extracts the documentation from your source files, and places it\nin the `generated-docs` folder under your project's root folder. By\ndefault, dependencies are not included, but this can be enabled\nwith the `--with-dependencies` flag.\n\nYou can also extract documentation from your tests, if you like:\n\n```sh\n$ pulp docs --with-tests\n```\n\nThe `purs docs` command itself also accepts some options to modify its\nbehaviour, which can be specified by using pass-through options. The `--format`\noption is particularly useful, as it allows you to specify the desired output\nformat. In particular, you can generate nice hyperlinked Pursuit-style HTML\ndocs with the following command:\n\n```sh\n$ pulp docs -- --format html\n```\n\nIt is a good idea to run this command and browse the generated HTML\ndocumentation before publishing a library to Pursuit, as doing so will allow\nyou to spot any formatting issues or any declarations which are missing\ndocumentation.\n\n### Launching a REPL\n\nThe `purs repl` interactive shell for PureScript is fantastically useful,\nbut setting it up can be a bit of a chore, especially with a large\nnumber of dependencies. That's where `pulp repl` comes in.\n\n`pulp repl` will generate a `.purs-repl` file for your project\nautomatically whenever you invoke it, and launch `purs repl` for you\ndirectly. It's as simple as:\n\n```sh\n$ pulp repl\n```\n\n### Launching a Development Server\n\nA common need when developing client side web apps is a tightly integrated\ndevelopment web server, which takes care of compilation for you on the fly.\nThis is what `pulp server` is for: whenever you make a change to your source\nfiles, you just switch to your browser and hit the refresh button, and the\nserver will compile and deliver your assets on the fly. No need to wait for the\nPureScript compiler to finish before switching to the browser.\n\n`pulp server` only provides the most basic functionality: it will serve static\nassets from your project root, and it will serve your compiled JS bundle from\n`/app.js`.\n\n#### A Quick Example\n\nTo see how this works, let's set up a project for serving the default\nhello world app through `pulp server`.\n\n```sh\n$ mkdir hello-server\n$ cd hello-server\n$ pulp init\n```\n\nWe need an `index.html` file to load our compiled PureScript code.\nPlace this in your new `hello-server` folder:\n\n```html\n\u003c!doctype html\u003e\n\u003chtml\u003e\n  \u003cbody\u003e\n    \u003ch1\u003eHello sailor!\u003c/h1\u003e\n    \u003cscript src=\"/app.js\"\u003e\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nNow, start the server:\n\n```sh\n$ pulp server\n```\n\nIt will tell you that it's launched a web server at\n[http://localhost:1337/](http://localhost:1337/), and after a little while it\nwill tell you that it's finished compiling:\n\n```\n* Server listening on http://localhost:1337/\n* Building project in /home/harry/code/hello-serve\nCompiling Data.Symbol\nCompiling Type.Data.RowList\nCompiling Record.Unsafe\n\u003csnip\u003e\n* Build successful.\n* Bundling JavaScript...\n* Bundled.\n```\n\nIf you browse to\n[http://localhost:1337/](http://localhost:1337/), you should, in\naddition to the \"Hello sailor!\" header on the webpage, see that your\nPureScript code has printed the text \"Hello sailor!\" to the console.\n\n#### I Need More\n\nAs mentioned, this is a very bare bones development server, since `pulp server`\nis intended as a starting point only. You're likely to quickly need more\nfeatures if you plan on doing any kind of serious web development. At this\npoint, you'll need to look further afield; one option is to use\n[Webpack](https://webpack.github.io/) together with\n[purs-loader](https://github.com/ethul/purs-loader).\n\n## Dependency Management\n\n`pulp` is not a package manager, only a build tool. The PureScript community\nhas standardised on [Bower](http://bower.io/) as the default package manager,\nbut there are alternatives such as\n[psc-package](https://github.com/purescript/psc-package). Currently, `pulp`\nsupports both Bower and psc-package.\n\nPulp expects the presence of a project manifest file in your project root, in\nwhich your project’s dependencies and other metadata are recorded. If you're\nusing Bower, that file will be `bower.json`; if you're using psc-package, it\nwill be `psc-package.json`.\n\nWhen you run commands like `pulp build`, Pulp will locate PureScript source\nfiles from installed dependencies based on which of these two files it finds in\nyour project, and pass these files on to the relevant program (e.g. `purs\ncompile`). If your project has both `bower.json` and `psc-package.json` files,\nPulp uses the dependencies installed via Bower by default; if you want to use\ndependencies installed via psc-package, you can use the `--psc-package` flag,\ne.g.\n\n```sh\n$ pulp --psc-package build\n```\n\nYou can also run `pulp --psc-package init` to initialize a project with a\n`psc-package.json` file instead of a `bower.json` file.\n\n### Dependency Management Cheat Sheet\n\nThis document isn't going to explain how Bower works, or go into\ndetails about PureScript dependency management. However, a tl;dr is\noften enough to get you started and productive without having to dive\ninto yet another package management system. It's going to be\nespecially easy if you're already used to `npm`. So, here we go.\n\n#### Installing Dependencies\n\nTo install the `purescript-profunctor` package into your project:\n\n```sh\n$ bower install purescript-profunctor\n```\n\nTo also record this as a dependency in the `bower.json` file:\n\n```sh\n$ bower install --save purescript-profunctor\n```\n\nTo install every dependency which has been recorded in `bower.json` as\nneeded by your project:\n\n```sh\n$ bower install\n```\n\n#### Housekeeping\n\nTo remove an installed package:\n\n```sh\n$ bower uninstall purescript-profunctor\n```\n\nTo remove it from `bower.json` as well:\n\n```sh\n$ bower uninstall --save purescript-profunctor\n```\n\nTo list all packages installed in your project:\n\n```sh\n$ bower ls\n```\n\nTo update all installed packages to the most recent version allowed by\n`bower.json`:\n\n```sh\n$ bower update\n```\n\n### Releasing Packages\n\nImagine you've created a new PureScript library for working with\nzygohistomorphic prepromorphisms (because who doesn't need zygohistomorphic\nprepromorphisms), called `purescript-zygo`.\n\n`pulp init` will have installed a basic `bower.json` file for you along with\nthe project skeleton, but before you continue, you should read the [Bower\ndocumentation on the file\nformat](https://github.com/bower/spec/blob/master/json.md) and make sure you’ve\nconfigured it to your satisfaction before you publish your package. In\nparticular, mind that you’ve added a `license` field.\n\nNote that there is a convention of prefixing PureScript package names with\n`purescript-`. Please stick with that unless you have an especially good reason\nnot to, as `pulp` and many other tools expect installed dependencies to follow\nthis convention.\n\nYou would start by tagging an initial version:\n\n```sh\n$ cd /path/to/purescript-zygo\n$ pulp version 0.1.0\n```\n\nThis runs a few checks to ensure that your package is properly set up for\npublishing, and if they pass, creates a Git tag `v0.1.0`.\n\n#### Publishing Packages\n\nBower packages are installed directly from Git repositories, and versioning\nfollows Git tags. This means that once you've tagged a version, all you need to\ndo to make a new release is push that tag to GitHub, register your package\nand upload your package's documentation to Pursuit. \n\nOriginally, `pulp` was designed to work exclusively with the Bower registry but \nthings became complicated after it no longer accepted new PureScript\npackage submissions. Older packages are still registered in Bower but new packages need to be \nregistered in the [PureScript Registry](https://github.com/purescript/registry).\nThe upshot is that you will usually use a `spago` workflow to \nprepare the ground for publication and then use `pulp` for the actual publication step itself.\nFor this reason you should read [spago: Publish my library](https://github.com/purescript/spago#publish-my-library) before proceding. You may also find it useful to read the notes on\n[How to submit packages](https://pursuit.purescript.org/help/authors#submitting-packages) in the \nPursuit package authors guide.\n\nThe `pulp` publication commands are:\n\n```sh\n$ pulp login\n```\nfollowed by\n\n```sh\n$ pulp publish\n```\n\nFor subsequent releases, the process is the same: `pulp version \u003cnewversion\u003e`\nfollowed by `pulp publish`. When tagging a new version, `pulp version` also\nallows you to supply an argument of the form `patch`, `minor`, or `major`, in\naddition to specific versions. If you run `pulp version patch`, for example,\nPulp will look through your Git tags to find the version number for the latest\nrelease, and then generate the new verision number by bumping the patch\ncomponent.  The `minor` and `major` arguments respectively perform minor and\nmajor version bumps in the same way.\n\nPulp does not currently support publishing packages which use psc-package\nexclusively, because without having submitted your package to a registry such\nas the Bower registry, there is no way of making sure that people agree which\npackage a given package name refers to. This may change in the future.\n\n## Development\n\nTo work on `pulp`, after cloning the repository, run:\n\n```\n$ npm install\n$ bower install\n```\n\nto install dependencies. Then, you can run\n\n```\n$ npm run -s build\n```\n\nto compile `pulp`, and\n\n```\n$ npm test\n```\n\nto run the tests.\n\n## Licence\n\nCopyright 2014-2017 Bodil Stokke, Harry Garrood\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU Lesser General Public License as\npublished by the Free Software Foundation, either version 3 of the\nLicense, or (at your option) any later version.\n\nSee the [LICENSE](LICENSE.md) file for further details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurescript-contrib%2Fpulp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpurescript-contrib%2Fpulp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurescript-contrib%2Fpulp/lists"}