Skip to content

Latest commit

 

History

History
234 lines (194 loc) · 9.04 KB

README.org

File metadata and controls

234 lines (194 loc) · 9.04 KB

NoMake

*This project is deprecated.*​ See Rice instead, which has simplified code and provides a modular API thanks to flake-parts. After migrating all existing projects to it, this repository will be archived.

NoMake is a framework that runs various checks against Emacs Lisp packages. It is an alternative to Cask, makem.sh, melpazoid, emake, makel, etc., but Nix-oriented and based on twist. It is yet a new iteration of elinter (a.k.a. emacs-package-checker, melpa-check, etc.).

It is primarily developed for emacs-twist org and my other Emacs Lisp packages.

NoMake heavily depends on Nix flakes, and you will need an understanding of flakes to use it.

Features

Supported checks

The following is a list of checks I plan to support:

  • [X] package-lint
  • [X] byte-compile with multiple Emacs versions
  • [X] check-declare
  • [ ] checkdoc with custom settings
  • [ ] ELSA with custom rules

I wish to support the following checks as well, but they are not available as an Emacs Lisp library at the time of writing:

  • [ ] Experimental checks of melpazoid
  • [ ] Indentation

Installation

NoMake requires Nix with flakes enabled.

Because nomake depends on nix-emacs-ci even locally, it is recommended to enable its binary cache:

cachix use emacs-ci

Usage

Initial configuration

These steps are necessary for any nomake project.

Scaffold a project

To add nomake to an existing Emacs Lisp project, you can use nix flake init command:

nix flake init -t github:emacs-twist/nomake

Create a new branch for your MELPA recipe

If your package is already on MELPA, you can skip this subsubsection.

Whether you plan on releasing your package to MELPA or not, you will need to put the recipe for your package in a branch.

Fork the repository of MELPA, create a new branch from master, add a recipe (see the format), and push it to GitHub (or any code hosting service).

Edit flake.nix to point the melpa to your branch:

{
  description = "...";
  inputs = {
    melpa = {
      url = "github:OWNER/melpa/BRANCH";
      flake = false;
    };
    # More inputs
  };
}

Set package names

In the outputs section of flake.nix, set localPackages to a list of packages in the repository:

nomake.lib.mkFlake {
  src = ./.;
  localPackages = [
    # The name of your package
    "nice-mode"
  ];
}

Explicitly install packages

You may sometimes want to explicitly install a particular package. This applies if you depend on packages such as org and project. They are shipped with Emacs but also actively developed, so older versions of Emacs ship outdated versions of packages. In this situation, you should list them in extraPackages:

nomake.lib.mkFlake {
  src = ./.;
  localPackages = [
    "nice-mode"
  ];
  extraPackages = [
    # Explicitly install org packages rather than depending on the built-in
    # version
    "org"
  ];
}

Development workflow

This subsection describes how to use nomake locally during development.

First generate lock files for your package dependencies:

nix run .#lock --impure

The dependencies are inspected from the library header of your package. You should run this command every time you add a new dependency.

Linting and byte-compiling the package

For byte-compiling, a snapshot version of nix-emacs-ci is used. The following command runs all checks (currently package-lint and byte-compiling):

nix run .#nomake -- PACKAGE

PACKAGE should be the name of the package.

Scripts

To run tests, you have to define a script. Scripts are a feature that lets you run a shell script in a development environment. In scripts, you can run Emacs with package(s) under test. It is also possible to add extra packages for testing.

To define a script, edit flake.nix and add scripts attribute:

nomake.lib.mkFlake {
  src = ./.;
  localPackages = [
    "nice-mode"
  ];
  scripts = {
    test = {
      description = "Run buttercup tests";
      compile = true;
      extraPackages = [ "buttercup" ];
      runtimeInputsFromPkgs = pkgs: [
        pkgs.hello
      ];
      text = ''
        emacs -batch -l buttercup -L . -f buttercup-run-discover
      '';
    };
  };
};

In the example shown above, test script is defined, and buttercup is added for running the tests. compile = true; means that the user package is byte-compiled when the script is run. Tests are discovered from the working directory.

To run the script, you can use nix run:

nix run .#test

The application name (test in this case) is the same as the name of the script defined in the flake.

By adding runtimeInputsFromPkgs, you can specify executables which will become available in the runtime environment of the script.

Note that you can specify extraPackages either as a sibling of localPackages or inside a script block. Wherever you define extra packages, it has the same effect. If you define multiple extraPackages attributes in different places, they are merged.

Run a script with a different Emacs version

It is possible to run a script with different versions of Emacs. You can pick a version available from nix-emacs-ci, but only required executables are downloaded from the binary cache. The minimum Emacs version is determined from the library header of your local package.

To check a list of Emacs versions for your package, run the following command (test should be the name of your script):

nix eval .#packages.x86_64-linux.test.matrix --apply builtins.attrNames

To run the tests with Emacs 26.2, run the following command:

nix run .#test.matrix.emacs-26-2

Continuous integration

This subsection provides an instruction for setting up CI for Emacs Lisp projects. At present, only GitHub Actions is supported.

GitHub Actions

Generate workflows

While it is possible to run Nix for linting your package on CI, it is slow when binary cache is unavailable. Instead, you can use an experimental feature of nomake to generate GitHub workflows. The generated workflows uses setup-emacs and installs latest packages using package.el. This is a fairly standard setup in the Emacs community. It does not always produce the same result as Nix, and it also does not support multi-package repositories well, but it is even better for submission to MELPA.

To generate workflows, run the following command:

nix build .#github-workflows

The workflow files are available in result directory. To copy the files to the designated directory, you can use the following command:

install -m 644 result/*.* .github/workflows

Alternatives

See comparisons by the author of makem.

At present, nomake doesn’t have as many features as makem, nor is it mature. The goal of this project is to provide a framework for consistent quality control over Emacs Lisp library code. Consistency does not always mean the most strict or supporting as many as checks as possible.

Compared to the previous iteration, it avoids impure Nix code for maintainability.

Credits

Some of the Emacs Lisp code in this repository are based on the following projects:

License

Because this repository contains some linting code from GPL 3.0-licensed repositories, the entire repository is licensed under GPL v3. You will have to license your projects under GPL too.