dportabella/Ammonite
Rock-solid shell scripting
Ammonite

This is where the code for the Ammonite project lives; Both:
- Ammonite-REPL, the improved Scala REPL
- Ammonite-Ops, the Scala file-system library
- Ammonite-Shell, the Bash-replacement system shell
If you want to learn more about Ammonite or how to use it, check out the links above, or ask on the Gitter Channel. The remainder of this document is developer-docs for people who want to work on the Ammonite source code itself.
Developer Docs
The layout of the repository is roughly:
ops/is Ammonite-Opsrepl/is Ammonite-REPLshell/is Ammonite-Shellterminal/is the JLine re-implementation used by Ammonite-REPL to provide syntax highlighting and multiline editingreadme/is the source code for the Documentation, written in Scalatex.modules/is a synthetic project used for publishing, purely intended to exclude the readme
Common Commands
Manual Testing
Although most features should be unit tested, it's still useful to fire up a REPL from the current codebase to see things work (or not). There are a variety of shells you can spin up for testing different things:
sbt ~terminal/test:runis useful for manual testing the terminal interaction; it basically contains a minimal echo-anything terminal, with multiline input based on the count of open- and closed-parentheses. This lets you test all terminal interactions without all the complexity of the Scala compiler, classloaders, etc. that comes inrepl/sbt ~repl/test:runbrings up the Ammonite-REPL using the source code in the repository, and automatically restarts it on-exit if you have made a change to the code. Useful for manual testing both ofrepl/as well asops/, since you can justimport ammonite.ops._and start using them. Note that this does not bring in filesystem utilities like thewdvariable,cd!command.sbt ~shell/test:runbrings up a fully-loaded shell with all filesystem utilities included:wd,cd!, autocomplete for filesystem paths, and more. This usesreadme/resources/example-predef.scalainstead of your default predef, for easier experimentation and development.sbt ~integration/test:runruns the trivial main method in theintegrationsubproject, letting you manually test running Ammonite programmatically, whether throughrunordebugsbt ~integration/test:consolebrings up a console in theintegrationsubproject, loading Ammonite-REPL as a test console, as described in the readme. Similar tointegration/test:runbut useful for verifying the different classloader/execution environment we get by starting Ammonite inside the Scala REPL doesn't break things
Automated Testing
While working on a arbitrary xyz subproject, sbt ~xyz/test runs tests after every change. repl/test can be a bit slow because of the amount of code it compiles, so you may want to specify the test manually via repl/test-only -- ammonite.repl.TestObject.path.to.test.
ops/testtests the filesystem operations, without any REPL presentrepl/testtests the Ammonite-REPL, without filesystem-shell integration.terminal/testtests the readline re-implementation: keyboard navigation, shortcuts, editing, without any filesystem/scala-repl logicshell/testtests the integration between the standaloneops/andrepl/projects: features likecd!/wd, path-completion, ops-related pretty-printing and toolsintegration/testkicks off the integration tests, which bundlerepl/andshell/into their respective jars and invoke them as subprocesses. Somewhat slow, but exercises all the command-line-parsing stuff that the other unit tests do not exercise, and makes sure that everything works when run from.jars instead of loose class-files
Publishing
git clean -xdfto make sure you're building from a clean project- Update the
project/Constants.scalaversion number to the new version sbt ++2.11.8 repl/assembly ++2.10.5 repl/assemblyto bundle the REPL as a standalone distributionsbt +published/publishLocalorsbt +published/publishSignedis used for publishing.- Create a new release on https://github.com/lihaoyi/Ammonite/releases and upload the two executables for 2.11.8 and 2.10.5, as well as the
shell/src/main/resources/ammonite/shell/example-predef.scalafile. - Create short URLs for the 2.11.8 executable download and the
example-predef.scalafile and fix the readme code inreadme/Sample.scalato use these short URLs sbt ~readme/runbuilds the documentation inside its target folder, which you can view by openingreadme/target/scalatex/index.htmlin your browser.git commit -am $VERSIONwith the new version number, andgit tag $VERSIONgit checkout gh-pages && cp -r readme/target/scalatex/* . && git add -A && git commit -am . && git pushwill deploy the generated documentation to Github Pages- Swap
project/Constants.scalato$NEXT_VERSION-SNAPSHOTand commit it - Wait 30 minutes for things to and run through the curl-download flow and make sure it works
Issue Tags
I've started tagging open issues in the issue tracker to try and keep things neat. This is what the various tags mean:
Each issue should only have one of these:
bug: this behavior clearly wrong, and needs to be fixedenhancement: something relatively speccable, that can be worked on, finished, and will make Ammonite betterwishlist: could be totally awesome, but we're uncertain if it is worth doing at all, what it would look like, or if it will ever reach a "finished" state.
And possibly:
help wanted: I don't have context, hardware, or for some other reason am unlikely to ever do this. But I know people out there care, so one of you should step up and fix it.
Contribution Guidelines
- All code PRs should come with: a meaningful description, inline-comments for important things, unit tests (positive and negative), and a green build in CI
- Try to keep lines below 80 characters width, with a hard limit of 100 characters.
- PRs for features should generally come with something added to the Documentation, so people can discover that it exists
- Be prepared to discuss/argue-for your changes if you want them merged! You will probably need to refactor so your changes fit into the larger codebase
- If your code is hard to unit test, and you don't want to unit test it, that's ok. But be prepared to argue why that's the case!
- It's entirely possible your changes won't be merged, or will get ripped out later. This is also the case for my changes, as the Author!
- Even a rejected/reverted PR is valuable! It helps explore the solution space, and know what works and what doesn't. For every line in the repo, at least three lines were tried, committed, and reverted/refactored, and more than 10 were tried without committing.
- Feel free to send Proof-Of-Concept PRs that you don't intend to get merged.