Run Calva in Development Mode - BetterThanTomorrow/calva GitHub Wiki

Calva is a TypeScript project. Some things are written in ClojureScript. The ClojureScript code is compiled by shadow-cljs into a node-js library, which is required from the TypeScript code.

Please start by saying hello in #calva at the Clojurians Slack.

Prerequisites

  • VS Code
  • Node.js
  • Java
  • The CLojure CLI, see Install Clojure, although if you are a Windows user the better option may be to install deps.exe from deps.clj by @borkdude and rename it to clojure.exe, placing it somewhere on your system Path.

The Setup

  1. Install Mocha Test Explorer Extension
  2. Install Prettier Extension
  3. Clone your fork of https://github.com/BetterThanTomorrow/calva
  4. Checkout the dev branch. This is where all Calva development happens.

The dev process:

  1. Open the project root directory in VS Code.
  2. From the VS Code Terminal menu, choose: Run Build Task… (CTRL+Shift+B).
  3. Wait for it to
    1. Build :calva-lib, and run its tests
    2. Build the TypeScript code
    3. Start these watchers:
      1. Prettier Format watcher - formats the TypeScript code when save a file
      2. shadow-cljs watcher - watches :calva-lib and :test, and will rerun tests on save of a Calva ClojureScript file
      3. TypeScript watcher - this will recompile on save of a Calva TypeScript file
      4. TypeScript Tests watcher - this will run the TypeScript test suite on save of any TypeScript or ClojureScript file
      5. ESLint watcher - this will lint the TypeScript files
  4. When all watchers are stable (look at the terminals) start the extension in debug mode by selecting menu option Run > Start Debugging (F5). This will open a second VS Code window where your modified Calva runs.
  5. Back in the first VS Code window run the command "Calva: Connect to a running REPL in your project", choosing the calva project root and then the Calva project type, accepting the host and port to connect to.

It will look something like so:

Happy Calva Hacking! Restart the extension host when you have new TypeScript code to test (ClojureScript code will hot-reload, just as you are used to).

deps.clj Uncommited Changes

Calva bundles deps.clj.jar and also automatically downloads any new versions at Calva startup. So when you run Calva in development mode, and a new version is detected, your local git repository will get uncommitted changes of the jar and of the version file. You can either ignore this, and just avoid committing the files, or you can file a PR which bumps the deps.clj version. Check the CHANGELOG.md file for earlier such updates to see what you should put in the [Unreleased] section.

Save time with Calva Connect Sequences

When working with the TypeScript code, you are back in the land where developers haven't yet discovered Interactive Programming. It is a cycle of recompiling, restarting, retesting over and over again. With VS Code and Calva recompile and restart are quick, but restarting can be prolonged if you need to also start the REPL of the project you use for retesting.

You can save quite a lot of time using the Copy Jack-in command line command together with Calva Connect to a Running REPL in the session where you run the development version of Calva. Then you don't need to wait for the REPL to start when you have restarted the debug extension host. Use a Calva Connect Sequence, including the autoSelectForConnect feature to make the reconnection fully automatic.

Note: You can still run the copied jack-in command line in the VS Code integrated terminal. VS Code will keep any terminal sessions during such reloads.

Debugging

Depending on what parts of Calva you are working with, the debug options look differently. Generally:

  • TypeScript: Use the debugger and the debug console. So, when you have started the extension in debug mode as per above, you go back to the Calva code base and place debug breakpoints which you then trigger in the debugged instance. Note that you have three types of breakpoints at your disposal, and you can also mix them somewhat. Logpoints are a bit like Clojure's tap>.
  • ClojureScript: Here you have full Interactive Programming powers. Evaluate a function to change its behaviour, use shadow-cljs hot-reload, tap> values out to the shadow-cljs inspector, inspect values flowing through the functions using inline defs (see this video for an example of this technique), or whatever is your favorite trick.

Code that does not integrate with VS Code can also be explored from unit-tests:

  • TypesScript - src/extension-test/unit - Use the Mocha TestExplorer to get a super nice UI for this.)
  • ClojureScript - src/cljs-lib/test/calva - These tests run automatically every time you save a file. You can of course also run them using any Interactive Programming tricks you fancy.

See below for more on testing.

NB: A great Contribute to Calva opportunity.

If you are looking for ways to contribute to Calva, here is an area where you can make a huge difference: All too much of the TypeScript code is unnecessarily integrated with VS Code (imports vscode or operate on input that relies on vscode). Extracting such code out to modules that can be unit tested, and setting up some first unit tests, is a super opportunity to help the Calva project.

Our integration and e2e testing has saved us many times from shipping bugs. But it has also missed a lot of cases, because we have very low coverage. Please help with increasing this coverage! 🙏 ❤️

Testing

Calva has five bodies of automatic testing, all of which are run as part of the Calva CI pipeline:

  1. Unit tests for the ClojureScript library, calva-lb
  2. Unit tests for the TypeScript code.
  3. Integration tests for the Calva extension.
  4. End to End tests for the Calva extension (utilizing Joyride)
  5. Unit tests for the TMLanguage Syntax grammar.

calva-lib

The calva-lib tests are run automatically as part of the watcher processes.

TypsScript unit tests

You can run the TS unit tests in (at least) two ways:

  1. From the command line: npm run unit-test.
  2. Using the Mocha Test Explorer Extension.

It is recommended you use both methods.

The coverage is slim so far. Please consider helping the Calva project by adding test suites and adding to the existing ones.

Integration tests

These do not provide the coverage they could provide. Please help in adding some meaningful tests.

Running the integration tests is done from the command line npm run integration-test. However, you need to not have VS Code running when you do it.

End 2 end tests

These tests the Calva extension from ”outside”, starting it and firing commands at it. (Just one command so far, please help in increasing the coverage. The test runner can test both a built VSIX and the code on the file system.

Syntax grammar

Calva has two sets of grammars.

  1. One is the tokeniation used for structural editing, navigation, rainbow parens, and various features in Calva. That is tested via the TS unit tests mentioned above.
  2. The other grammar is the [tmLanguage]((https://macromates.com/manual/en/language_grammars) file that VS Code uses for basic syntax highlighting.
Updating the tmLanguge grammar

The tmLanguage Clojure grammar originated in Atom and still needs Atom for the automated testing:

  1. Open the src/calva-fmt/atom-language-clojure directory in Atom.
  2. Run Package Specs
  3. Update the grammar cson (I do this in VS Code, because I love VS Code).
  4. In Atom, Run Package Specs

You probably need to update the specs too, depending on the change. Consider writing a test that catches if your change to the grammar would be removed.

For actually making the grammar work in VS Code, you need to convert the CSON grammar file to JSON:

  1. From the root folder of the Calva repo run npm run update-grammar. This updates the clojure.tmLanguage.json file used by VS Code.
  2. Restart the debug session to test the grammar in VS Code.

Please don't hesitate to holler at @pez on the Clojurians slack.

Editing Documentation

The Calva source for the Calva documentation, located at calva.io, is in the docs/site directory. It's built using MkDocs + MkDocs Material and is hosted by GitHub Pages.

If you're making changes to the docs that are not associated with code changes, make the changes in a branch based on the published branch. If you're making doc changes associated with code changes, make them on the branch that contains the code changes.

  1. Install MkDocs + Material. From the Calva directory, run:

    pip install -r requirements.txt
    

    (Or your preferred method from https://squidfunk.github.io/mkdocs-material/getting-started/)

    If you get an error with the pip install method above, you may have an older version of python. If you install python 3.7 and run the following command, it should work:

    python3.7 -m pip install -r requirements.txt
    
  2. Run the MkDocs server:

    mkdocs serve
    
  3. Visit http://localhost:8000

  4. Edit docs. It's all Markdown (with MkDocs-materials add-ons). When you save, the changes will be reloaded in the browser.

Note: The MkDocs Markdown is a bit pickier than GitHub's, so make sure to use four indents, put an empty line before bulleted lists, and so on. The VS Code extension markdownlint helps with following the appropriate style. And make sure to check the results at your local site.

Before Sending Pull Requests

Feel invited to send us a PR just as a way to get feedback. You don't need to wait until your code works or the change is completed. Work in progress is totally PR-able.

Make sure you are directing the pull request at the dev branch, unless you have reasons to target some other branch. Also, ”some other branch” is never published, which is the default branch, unless your changes are only to documentation.

Also:

  1. Please strongly consider filing an issue for the thing you are fixing, whether it is a bug, a change to a feature, or a new feature. (Unless, of course, such an issue already exists.)
  2. If your PR is more than just fixing a typo, have your work in a feature branch. Since most PRs will be of a work-in-progress nature, you are welcome to follow our convention of naming our feature branches wip/<short-feature-title>.
  3. Update CHANGELOG.md under [Unreleased]. Link your entry to the issue you are fixing.
  4. In PR commit message, mention any issues you are addressing or fixing (maybe, as per 1.). Use the fixes/closes syntax, if applicable. (If you are not fixing the entire issue, say something like ”Addressing: #42”).
    • This will make people looking at that issue see that there is work being done, where it is carried out, and what is being changed. Also using the ”Fixes” syntax will make GitHub automatically close the issue, linking the commit that did it, when the commit is merged onto published. GitHub is awesome with this, let's leverage it!
  5. Keep the changes focused on the thing you are adding/fixing. This will make it smoother for us to consider whether the changes should be merged or not. If you see room for refactoring and code style changes and such (there is plenty of this), you are welcome to suggest these changes in separate PR.

Please also see:

After Sending Pull Requests

When you have issued your pull request, it is best to ping us about it to catch our attention. The #calva channel of the Clojurians Slack is a good place for this ping. Mention @pez and @bringe.

We will try to get back to you quickly with our assessment of whether this PR fits the Calva path. Depending on the nature of the change it might need some discussion.

We use Circle-CI to automatically build any updates to a PR. It will run the automated tests and give you feedback on the PR page on Github. It will also build a VSIX package for you. Every time you have pushed updates to the PR, please download it and smoke test it some. Our release process relies on that the VSIX packages are sanity checked along the development process. See Testing VSIX Packages.

To Get Your PR Merged

  1. The Calva team will have to agree it fits the path Calva is travelling along.
  2. All tests must pass. Please add some basic unit tests for the thing you are fixing.
    • Since much of the code is not factored for testing, this can be a bit tricky, so we do not always demand it.
  3. Any changes to README.md are done (or, if you prefer we write it, communicated to us).
  4. The VSIX package is tested by you.

Again, see the Pull Request Template for more.

See also: Testing VSIX Packages

Just One More Thing

Happy Calva Hacking! ❤️