From c253c51b05c952899506eeed7d07c6b26dcc16be Mon Sep 17 00:00:00 2001
From: Psionik K <73710933+psionic-k@users.noreply.github.com>
Date: Thu, 19 Oct 2023 09:53:12 -0500
Subject: [PATCH] Generated readme and texinfo manual
The documentation was moved to /doc and broken up so that there is now a manual
and the README includes sections of the manual. The contributing guide was
mostly left as-is.
Table of contents no longer relies on org-toc
Several helper commands to export and view the correct files were created.
ERK now reads its own attributes to decide how to perform author renaming and
also uses these during document generation
The documentation generation was documented. Oh god.
Lots of little documentation tweaks were done to format or support the exports.
generated documentation found in new README.md, CONTRIBUTING.md, and manual.texi
Signed-off-by: Psionik K <73710933+psionic-k@users.noreply.github.com>
---
.github/workflows/ci.yml | 2 +
.gitignore | 3 +-
CONTRIBUTING.md | 238 +++++
README.md | 572 ++++++++++
README.org | 492 ---------
CONTRIBUTING.org => docs/CONTRIBUTING.org | 74 +-
docs/README.org | 224 ++++
docs/manual.org | 715 +++++++++++++
docs/manual.texi | 1160 +++++++++++++++++++++
lisp/erk.el | 247 ++++-
10 files changed, 3174 insertions(+), 553 deletions(-)
create mode 100644 CONTRIBUTING.md
create mode 100644 README.md
delete mode 100644 README.org
rename CONTRIBUTING.org => docs/CONTRIBUTING.org (74%)
create mode 100644 docs/README.org
create mode 100644 docs/manual.org
create mode 100644 docs/manual.texi
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6055e3b..36072d4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -43,6 +43,8 @@ jobs:
os: [ubuntu-latest, macos-latest]
emacsPkg: [ emacs, emacsGit, ]
runs-on: ${{ matrix.os }}
+ # If you update steps, be sure to update the approved actions list in the
+ # manual and in your repositories!
steps:
- uses: actions/checkout@v3.2.0
with:
diff --git a/.gitignore b/.gitignore
index 6e37a15..5aa1681 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@
***autoloads.el
**trash
**~
-**.~undo-tree
\ No newline at end of file
+**.~undo-tree
+/docs/manual.info
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..035b736
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,238 @@
+[comment]: !!!THIS FILE HAS BEEN GENERATED!!! Edit README.org
+
+Development process & infrastructure guide.
+
+
+# Table of Contents
+
+- [Development](#org3ea5530)
+ - [Running tests](#org8b93397)
+ - [Lint and byte-compile code](#orgaf9de15)
+ - [Loading and re-loading your package](#orgfa05693)
+- [License](#org94a766b)
+- [Developer Certificate of Origin (DCO)](#orga76d644)
+ - [Sign-off](#orga4c7da0)
+ - [GPG signature](#org360d290)
+ - [User setup for submitting changes](#org50831e6)
+ - [Maintaining versions](#org3c71a76)
+
+
+
+
+# Development
+
+This repository was created with [elisp-repo-kit](https://github.com/positron-solutions/elisp-repo-kit/). You can use it to streamline
+development workflows.
+
+
+
+
+## Running tests
+
+Run `erk-ert-project` within this project. The tests will be
+discovered, rebuilt & reloaded if necessary, and run. There are a
+few other commands to augment the [ert](https://www.gnu.org/software/emacs/manual/html_node/ert/) package.
+
+
+### Running tests CI style
+
+If you cannot reproduce a failure (or success) on CI, then you may
+want to switch to using [nix](https://nixos.org/download.html) to get a reprodicible toolchain so you
+can further develop with frozen versions from the nix [flake's](https://nixos.wiki/wiki/Flakes)
+flake.lock.
+
+
+ nix develop .github# # loads the devShells.default from flake.nix
+ cd .github && direnv allow # same as above with file watching
+
+ emacs --quick --load .github/run-shim.el -- test # graphical
+ emacs --script .github/run-test.el -- test # terminal, batch style
+
+You can *totally* run the tests locally on whatever version of Emacs you
+have. **You do not need Nix to run tests pretty close to what CI does.** CI
+will use Nix to obtain Emacs & dependencies.
+
+
+
+
+## Lint and byte-compile code
+
+This package uses [elisp-lint](https://github.com/gonewest818/elisp-lint) to detect issues with byte compiling, package
+format, code structure and others.
+
+The configuration is found inside [.github/run-shim.el](../.github/run-shim.el). The CI run is invoked
+inside of [ci.yml](../.github/workflows/ci.yml) using Emacs in script mode. Most of the configuration is in
+the run shim.
+
+The tests are also linted, to a less restrictive standard, also found in
+[run-shim.el](../.github/run-shim.el)
+
+You can run the lints manually almost the same as running tests.
+
+
+ nix develop .github#
+ # nix develop .#emacs28
+ # nix develop .#emacsGit
+ emacs --script .github/run-shim.el -- lint
+ emacs --script .github/run-shim.el -- lint-tests
+
+
+
+
+## Loading and re-loading your package
+
+Run `erk-reload-package` in one of your project files. All features
+in the /lisp directory will be re-compiled and loaded appropriately.
+
+**Note**, during reloading, unloading the current module is forced. If other
+packages you use depend on the project feature, results may be unpredicatable.
+This is one reason batch style testing can be preferred.
+
+
+### Manual Loading & Reloading
+
+To manually unload, run built-in command `unload-feature` and select your
+package name. If you do not unload, reloading has no effect and you will see
+stale behavior.
+
+Next, add the package to your load-path and then require it or, more
+directly, call `emacs-lisp-byte-compile-and-load` or
+`emacs-lisp-native-compile-and-load`.
+
+
+
+
+# License
+
+This package is distributed under the terms of the [included license](./COPYING). The CI
+configuration and scripts are MIT licensed.
+
+
+
+
+# Developer Certificate of Origin (DCO)
+
+This project is distributed with a Developer Certificate of Origin. By adding
+a sign-off notice and GPG signature to each commit, you will provide means to
+authenticate your sign-off later strengthening your attestations stated in the
+DCO, upholding the overall integrity of the license coverage over the project.
+
+A [copy of the DCO](./DCO) is distributed with this project. Read its text to
+understand the significance of configuring for sign-off.
+
+
+
+
+## Sign-off
+
+A sign-off means adding a "trailer" to your commit that looks like the
+following:
+
+
+ Signed-off-by: Random J Developer
+
+
+
+
+## GPG signature
+
+A GPG signed commit shows that the owner of the private key submitted the
+changes. Wherever signatures are recorded in chains, they can demonstrate
+participation in changes elsewhere and awareness of what the submitter is
+participating in. Corroborating user's signature accross a history of works
+strengthens that user's attestation provided by DCO sign-off.
+
+
+
+
+## User setup for submitting changes
+
+Follow these instructions before you get ready to submit a pull-request.
+
+Refer to the [GitHub signing commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) instructions to set up your git client
+to add GPG signatures. File issues if you run into Emacs-specific problems.
+Be sure to use a Github verified email.
+
+Because signing is intended to be a conscious process, please remember to
+read and understand the [Developer Certificate of Origin](../DCO) before confinguring
+your client to automatically sign-off on commits.
+
+
+### Automatically add sign-off
+
+In magit, set the `-s` switch. Use `C-x C-s` (`transient-save`) to
+preserve this switch on future uses. (Note, this is not per-project).You
+can also set the signature flag this way.
+
+
+### Automatic GPG signing with per-project keys
+
+In order to specify which projects you intend to sign with which keys, you
+will want to configure your git client using path-specific configurations.
+
+Configuing git for this can be done with the following directory structure:
+
+
+ /home/rjdeveloper/
+ ├── .gitconfig
+ └── .gitconfig.d
+ ├── sco-linux-projects.conf
+ ├── other-projects.conf
+ └── gpg-signing-projects.conf
+
+In your root config, `.gitconfig`, add an `includeIf` directive that will
+load the configuration you use for projects you intend to GPG sign commits
+for.
+
+
+ [includeIf "gitdir:/home/rjdeveloper/**/gpg-signing/**/.git"]
+ path = "~/.gitconfig.d/gpg-signing-projects.conf"
+
+In the `gpg-signing-projects.conf` add your GPG signing configuration from
+earlier. `sign` adds the GPG signature automatically. File an issue if you
+need help with multiple GPG homes or other configurations.
+
+
+ [user]
+ name = "Random J Developer"
+ email = "random@developer.example.org"
+ signingkey = "5FF0EBDC623B3AD4"
+
+ [commit]
+ sign = true
+ gpgSign = true
+
+
+### Manually signing & adding sign-off
+
+If you don't like these configurations and want to individually indicate you
+have read and intend to apply the DCO to your changes, these commands are
+equivalent:
+
+ git commit -s -S --message "I don't like using .gitconfig"
+
+ # To clean up a commit
+ git commit --amend -s -S --no-message
+
+ # Combine with rebase to sign / sign-off multiple existing commits
+ git rebase -i
+
+
+
+
+## Maintaining versions
+
+The Nix [flake.nix](../github/flake.nix) is where versions are declared. The [flake.lock](../.github/flake.lock) stores a
+fixed value for these declarations. These fixed versions need periodic
+update. Nixpkgs has a new release about every six months. You can check
+their [branches](https://github.com/NixOS/nixpkgs/branches) and [tags](https://github.com/NixOS/nixpkgs/tags) to see what's current. The effect is similar to
+updating linux versions. The `nix` command has a lot of support for
+specifying versions besides just updating.
+
+ nix flake lock --update-input nixpkgs
+
+The `emacs-overlay`, which contains fixed versions of Emacs and snapshots of
+Elisp repository package sets can be updated by running:
+
+ nix flake lock --update-input emacs-overlay
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..22989f3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,572 @@
+[comment]: !!!THIS FILE HAS BEEN GENERATED!!! Edit README.org
+
+
+
+
+
+This repository is a kit to start a new elisp package repository on GitHub. The
+package contained has commands to streamline elisp development.
+
+
+# Quickly set up an Emacs Lisp repository on GitHub with:
+
+- An [elisp](https://www.youtube.com/watch?v=RQK_DaaX34Q&list=PLEoMzSkcN8oPQtn7FQEF3D7sroZbXuPZ7) package
+- CI with [GitHub Actions](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs), configured for Darwin (MacOS) and Linux
+- Built-in Emacs info manual generation
+- [Nix](https://nixos.org/#examples) environment for obtaining dependencies or reproducibly developing CI
+ locally
+- Licensing, [DCO](https://developercertificate.org/), DCO sign-off checks, PR template and [CONTRIBUTING](./CONTRIBUTING.md) instructions
+- [MELPA](https://github.com/melpa/melpa) publishing compatible
+
+**To get started:**
+
+Install the package and run `erk-new`, provide a directory, and
+answer all the questions.
+
+
+# Install ERK
+
+
+ (use-package erk) ; vanilla
+
+ ;; using elpaca's with explicit recipe
+ (use-package erk
+ :elpaca (erk :host github :repo "positron-solutions/elisp-repo-kit"))
+
+ ;; straight with explicit recipe
+ (use-package erk
+ :straight (erk :type git :host github :repo "positron-solutions/elisp-repo-kit"))
+
+ ;; or use melpa, manual load-path & require, you brave yak shaver
+
+
+## Manual cloning
+
+The standalone command, `erk-clone` will clone without renaming.
+
+This repo is also a [template repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template), so you can fork without forking
+(Bruce Lee).
+
+If you create via template or clone manually, it's presumed you know what
+you're doing at that point. Call `erk-rename` on its own to rename
+in these cases.
+
+There are some customize options that cause the renaming to be transitively
+consistent.
+
+
+## Manually add just CI
+
+Copy the .github folder and the contributing guide to your package. Set up
+your secrets for Cachix. Read the CI customization section.
+
+
+# Table of Contents
+
+- [Creating Packages](#org0f2af54)
+- [Using ERK for development](#org676fedf)
+ - [Find Files](#orgf767699)
+- [File contents and structure](#org4c92fb9)
+- [Finish setting up your new GitHub repo](#org8a88844)
+ - [Optional Steps](#orgb077195):item:
+- [Customizing CI](#orgbaee92e)
+- [Licensing, Developer Certificate of Origin](#org4588e78)
+- [Publishing to MELPA](#orge3fbd34)
+ - [Creating the recipe](#orgbe51fbc)
+ - [Testing package build](#orge78d4bd)
+ - [Testing stable package build](#orga7141b7)
+ - [MELPA Lints](#orgff9bde7)
+- [Maintaining versions](#orge882eac)
+- [Package scope and relation to other work](#org99ab29b)
+ - [Dependency Management](#orged0d5e7)
+ - [Discovering and Running Tests & Lints](#org7cbc864)
+ - [Comparisons](#org0d865f6)
+- [Contributing](#org2d1d884)
+- [Footnote on FSF and Emacs Core Licensing](#org527e83c)
+- [Shout-outs](#orgefbd677)
+
+
+# Creating Packages
+
+The simplest and intended way is to call `erk-new`. It will first
+ask you for:
+
+- Root directory you want to clone to
+- Package name
+- Package prefix
+- Author name
+- GitHub user or organization
+- Email address
+
+`erk-new` also calls `erk-rename-relicense` to rename all of the files, string
+replace names, and re-license to GPL3. It also changes the author and resets
+the git history. Now just follow the steps in [finish setting up](#org8a88844) Have fun!
+
+
+# Using ERK for development
+
+Elisp repo kit contains some convenience functions to reload your package and
+to discover and run ert tests. These shortcuts just make common cases faster.
+
+- Loading and re-loading your package
+
+ `erk-reload-project-package` will unload and recompile your package if
+ necessary and then reload it.
+
+ `erk-reload-project-tests` is the complementary command for reloading tests.
+
+- Run tests
+
+ `erk-ert-project` will discover, rebuild & reload if necessary, and run
+ tests. There are a few other commands to augment the [ert](https://www.gnu.org/software/emacs/manual/html_node/ert/) package.
+
+- Duplicating CI Locally
+ The CI configuration is all stored in [.github](../.github/). Usually you will want
+ development instructions in your new repository. The [CONTRIBUTING](./CONTRIBUTING.md) guide
+ contains instructions to reproduce the CI behavior.
+
+
+## Find Files
+
+Accidentally editing generated files or forgetting the path to a file is
+annoying. ERK provides a helper to find files based on their purpose.
+
+`erk-find` will ask you to pick the file based on what it does. It's
+choices:
+
+- ci-dco
+- ci-nix-flake
+- ci-run-shim
+- ci-tests
+- docs-contributing
+- docs-manual
+- docs-readme
+
+Generated files or extremely common files are not included. For each one of
+these choices, there is a corresponding command:
+
+- `erk-find-ci-dco`
+
+- `erk-find-ci-nix-flake`
+
+- `erk-find-ci-run-shim`
+
+- `erk-find-ci-test`
+
+- `erk-find-docs-contributing`
+
+- `erk-find-find-docs-manual`
+
+- `erk-find-docs-readme`
+
+
+# File contents and structure
+
+*After cloning and renaming,* you will have a file tree like this:
+
+
+ ├── .gitignore # ignores for byte compiles, autoloads etc
+ │
+ ├── README.md # this file
+ ├── CONTRIBUTING.md # typical instructions for development
+ ├── COPYING # a GPL3 license
+ ├── DCO # Developer Certificate of Origin
+ │
+ ├── .github
+ │ ├── .envrc # direnv integration with `nix develop`
+ │ ├── flake.nix # dependencies for this project
+ │ ├── flake.lock # version controlled lock of flake.nix input versions
+ │ ├── run-shim.el # elisp script with test & lint routines
+ │ ├── pull_request_template.md # reminders for PR contributors
+ │ └── workflows
+ │ ├── ci.yml # workflow for lints and tests
+ │ └── dco.yml # workflow to check DCO sign-offs
+ │
+ ├── docs
+ │ ├── README.org # generates README.md
+ │ ├── CONTRIBUTING.org # generates CONTRIBUTING.md
+ │ ├── manual.org # actual manual
+ │ └── manual.texi # generated manual for distribution
+ │
+ ├── lisp
+ │ └── erk.el # the package
+ │
+ └── test
+ └── erk-test.el # ERT unit tests for the package
+
+You can use either a multi-file or flat layout for lisp. Just name test files
+`something-test.el` and keep all lisp files in root, `/lisp` or `/test`
+directories.
+
+
+# Finish setting up your new GitHub repo
+
+You can copy this checklist to your org agenda files:
+
+- [X] Create a repository (from [install](#orga7f838f) instructions)
+- [ ] Create an empty GitHub repository and check the git remote configuration
+- [ ] Set up your git commit signing (and verification so that it's obvious)
+ **and** [sign-off](#org4588e78) so that it will be hypothetically [straightforward](README.md) for for FSF
+ to pull in your changes if they later change to DCO instead of copyright
+ assignment.
+- [ ] Sign up for [cachix](https://app.cachix.org/) and, create a binary cache with API tokens and public
+ read access
+
+\#+cindex nix enabling cachix
+\#+cindex github adding secrets
+
+- [ ] Add repository secrets necessary for your GitHub actions
+ `CACHIX_AUTH_TOKEN` and `CACHIX_CACHE_NAME` (settings -> secrets -> new
+ repository secret)
+
+\#+cindex github enabling actions
+
+- [ ] Enable actions and add the following actions to your allowed actions list:
+
+
+ actions/checkout@v3.2.0,
+ cachix/cachix-action@v12,
+ cachix/install-nix-action@v20,
+ actions/setup-python@v4,
+
+ **Note**, Python is used to run a DCO check script, nothing more.
+
+- [ ] Get your package working, pushed, actions run, and CI badges all green
+- [ ] [Publish](#orge3fbd34) to MELPA
+- [ ] Make a post on [reddit](https://reddit.com/r/emacs/) and [mastodon](https://emacs.ch/) about your new package
+
+
+## Optional Steps :item:
+
+- [ ] Branch protect and enable check requirements for your default branch
+ (usually master). Merge commits, verified only, and no force push are
+ recommended settings.
+- [ ] Enable requiring contributors to sign-off on web-based commits
+- [ ] For **security** of your Cachix secrets and any other secrets you may someday
+ add, require Actions approval for all outside contributors and leave
+ repository permissions at read-only
+
+Cachix is somewhat optional. It's free for open-source projects. It's
+about as easy to sign up and generate the token as to remove the step from
+the GitHub actions, so you won't save much time by avoiding it.
+
+If you opt out of cachix or any other binary cache, you will definitely want
+to turn off tests for `emacsGit` etc because the build times are about
+30min-1hr per run when a fresh Emacs must be built.
+
+
+# Customizing CI
+
+The [run-shim.el](../.github/run-shim.el) script is just provides a CLI interface for adding commands in
+the [ci.yml](../.github/workflows/ci.yml) CI declaration. Each action step just loads the shell, declared in
+the [flake.nix](../.github/flake.nix) and then runs the shim in Emacs. The shim consumes the CLI
+command arguments, so you can parameterize the invocations that way.
+
+- If you need extra elisp dependencies during CI, add them to the `epkgs` list
+ in the flake.nix.
+- If you need extra 3rd party dependencies, add them to `packages` in the call
+ to `mkShell`.
+- To invoke different elisp operations, add / modify the commands in
+ [run-shim.el](../.github/run-shim.el).
+
+There's more information in [CONTRIBUTING](../CONTRIBUTING.md) about running commands locally. You
+will want this information in your new repository.
+
+
+# Licensing, Developer Certificate of Origin
+
+This template project is distributed with the MIT license. `erk-new` will also
+run `erk-rename-relicense`, which will automatically switch to the GPL3
+license. **The MIT license allows re-licensing, and so this change is
+compatible.** If you accept non-trivial changes to your project, it will be
+very hard to change to the GPL3 later, so consider this choice.
+
+The new repository will also come with DCO sign-off checking on PR's. The
+instructions are in the [CONTRIBUTING](../CONTRIBUTING.md) guide. A DCO sign-off policy will give
+your project a clear attestation of sufficient direct or transitive authority
+from each contributor to submit changes under the terms of your project's
+license. This can only improve your legal protection from incidentally
+handling copyrighted code.
+
+The DCO choice in this repository is also meant to encourage & push stodgy
+organizations whose responsibility it was to invent better processes towards
+lower friction paths to contribute code. If you fail to implement the DCO
+sign-off scheme, there is less hope that the FSF will someday independently
+merge changes that accumulate in your package because there will not be a
+clear chain of license compliance.
+
+
+# Publishing to MELPA
+
+If you have green CI, you have already passed many requirements of publishing a
+MELPA package. **You still need to build your package and verify your recipe.**
+You are going to clone melpa in order to make your PR. You can use the clone to
+verify the recipe.
+
+
+## Creating the recipe
+
+Fork MELPA personally (not for organization) and clone it to wherever you keep
+your upstreams. It's a good idea to separate upstreams from projects you
+actively maintain so you can see and delete upstreams when not in use.
+
+
+ mkdir -p upstream
+ cd upstream
+ git clone git@github.com:$GITHUB_USER/melpa.git # replace $GITHUB_USER
+
+Install package-build
+
+ (use-package package-build)
+
+`package-build-create-recipe` will give you something like:
+
+ (erk :fetcher github :repo "positron-solutions/elisp-repo-kit")
+
+The following template can be filled in and pull-requested to MELPA to publish.
+You don't need to touch `:files`. The `commit` and `branch` are optional
+depending on how you version / develop / tag your releases.
+
+Copy the recipe into `recipes/erk` inside your MELPA clone.
+
+
+## Testing package build
+
+Inside the MELPA clone root:
+
+
+ # Builds the package
+ make recipes/erk
+ # Test sandbox installation (will affect ~/.emacs.d/elpa So much for sandbox ¯\_(ツ)_/¯
+ EMACS_COMMAND=$(which emacs) make sandbox INSTALL=erk
+
+
+## Testing stable package build
+
+You need a tag on your default (usually master) branch of your repo,
+`positron-solutions/elisp-repo-kit`. Use `git tag -S v0.1.0` and `git push
+ origin v0.1.0`. You can also just create a release in the GitHub interface.
+
+
+ # Test stable builds against your tags
+ STABLE=t make recipes/erk
+
+
+## MELPA Lints
+
+Lastly, install [melpazoid](https://github.com/riscy/melpazoid) and call `melpazoid` on your main feature. It does
+some additional lints. You may need to install `package-lint` if you don't have
+it. It's not declared in melpazoid's requirements. Getting the package in Nix
+is not easy yet since melpazoid is not yet on Melpa.
+
+
+ ;; using elpaca's with explicit recipe
+ (use-package melapzoid
+ :elpaca (melpazoid :host github :repo "riscy/melpazoid"))
+
+ ;; using straight
+ (straight-use-package
+ '(melpazoid :type git :host github :repo "riscy/melpazoid" :files ("melpazoid/melpazoid.el")))
+
+If everything works, you are ready to make a pull request to MELPA. Push your
+changes and check all the boxes in the PR template except the one that requires
+you to read the instructions.
+
+
+# Maintaining versions
+
+The Nix [flake.nix](../github/flake.nix) is where versions are declared. The [flake.lock](../.github/flake.lock) stores a
+fixed value for these declarations. These fixed versions need periodic
+update. Nixpkgs has a new release about every six months. You can check
+their [branches](https://github.com/NixOS/nixpkgs/branches) and [tags](https://github.com/NixOS/nixpkgs/tags) to see what's current. The effect is similar to
+updating linux versions. The `nix` command has a lot of support for
+specifying versions besides just updating.
+
+ nix flake lock --update-input nixpkgs
+
+The `emacs-overlay`, which contains fixed versions of Emacs and snapshots of
+Elisp repository package sets can be updated by running:
+
+ nix flake lock --update-input emacs-overlay
+
+
+# Package scope and relation to other work
+
+There are two functional goals of this repository:
+
+- Automate the annoying work necessary to set up a new repository
+- Streamline common elisp development workflows
+
+Commands within this package will focus on cleaner integration of the tests
+and lints with Emacs. There has been a lot of work in this area, but much of
+it is tangled with dependency management and sandbox creation. Much of it is
+done in languages other than elisp and focused on non-interactive workflows
+with no interactive integration on top.
+
+Providing close to out-of-box CI is a big focus. By making it easier to
+qualify changes from other users, it becomes less burdonsome to maintain
+software, and by extension, less burdensom to publish and create software. The
+effect is to drive creation of elisp in a way that can accelerate the flow of
+elisp into Emacs itself.
+
+
+## Dependency Management
+
+This repository uses pure dependency management and then leverages it to
+provide dependencies for development and CI environments. The resulting user
+experience is built around CI for reproducibility and interactive testing for
+development speed.
+
+Because most elisp dependencies can be obtained without extensive system
+dependency management, many tools for testing Emacs packages provide
+dependency management and loading those dependencies into a fresh Emacs
+instance. This aligns well with ad-hoc sandboxed local testing. This was
+fine in the old days of impure dependency management and dirty environments.
+
+The [Emacs Nix Overlay](https://github.com/nix-community/emacs-overlay) and Emacs support within nixpkgs make it possible to
+stating and obtaining elisp dependencies in a completely pure way. Non-elisp
+dependencies are trivially provided form nixpkgs. Nix is extremely reliable
+at dependency management, and it is no surprise that much complexity is
+normalized away by just the basic behavior model of Nix. In addition, **if
+your project needs or includes additional binary dependencies or modules**,
+Nix is an excellent way to provide them to CI and users.
+
+
+## Discovering and Running Tests & Lints
+
+During development, the commands provided under the `erk-` prefix make it
+more convenient to reload your package and test features. You can run the
+ert tests for a project while working on multiple packages.
+
+During CI, this repository uses an elisp shim for discovering and running
+tests. The commands within the package for convenience during development
+are not depeneded upon during CI.
+
+The CI actions obtain an environment with dependencies using Nix, so this can
+also be done locally using Nix, meaning re-creating environments is available
+to the user without leaning on CI.
+
+
+## Comparisons
+
+There are many tools for running Elisp tests. Most of them are well
+integrated with some dependency management. Most of them have some published
+CI integrations to draw inspiration from. These patterns are common because
+the needs arise together.
+
+
+### ERK's Key Characteristics
+
+- Quickly spin up nearly complete starter projects
+- Fully working CI, packaging, and documentation manual scheme
+- Immediately run tests and get into the virtuous feedback loop
+- Nix dependency management, bringing both Elisp and 3rd party dependencies
+ under full control
+
+As a template for your project, **ERK leans towards being opinionated** in
+order to provide complete behavior out of the box. The trade-off of being
+closer to a completed project while still being minimal is only supporting
+one hosting platform, **Github, and its Github Actions CI infrastructure.** You
+can adapt around this easily because it's not a complex project, but you will
+do it on your own.
+
+This project favors the **Nix dependency tooling** for extreme reproducibility
+and access to a **huge** number of 3rd party dependencies on most platforms.
+If you want to implement sandboxed tests or test with a specific version of
+dependencies, you can do it in a pollution-free way across numerous versions
+with Nix. Everyone on most platforms can reproduce your work in a way that
+doesn't pollute their system either (beyond installing Nix).
+
+
+### Other Comparisons
+
+There are many comparisons available to understand the roles of similar tools
+and how they relate to each other.
+
+- [makem.sh](https://github.com/alphapapa/makem.sh#comparisons)
+- [Eldev](https://github.com/doublep/eldev#see-also)
+- [nomake](https://github.com/emacs-twist/nomake) Is another project with Nix work
+
+[nix-emacs-ci](https://github.com/purcell/nix-emacs-ci) capture the work needed to provide a running Emacs to CI. Tools
+like [eldev](https://github.com/doublep/eldev#continuous-integration) and [makem.sh](https://github.com/alphapapa/makem.sh/blob/master/test.yml) have support for providing dependencies to that Emacs.
+The Nix flake [in this project](../flake.nix) describes both of these tasks. Makem and Eldev
+etc document Gihub workflows, but **the workflows in this repository are meant to
+be used out-of-the-box after cloning**, although to be fair, there's more
+decisions than actual work.
+
+Nix-emacs-ci provides a lot of backwards-compatibility versions of Emacs.
+The emacs-nix-overlay that this project employs is more forward looking,
+providing `emacsGit` and sometimes other upstream branches when a big
+feature like native compilation is in the pipeline. Nix-emacs-ci is also
+still using legacy Nix, without flakes. Flakes are just nicer and the way
+Nix is going.
+
+
+# Contributing
+
+For turn-key contribution to the software ecosystem that keeps you moving, see
+the [funding links](https://github.com/sponsors/positron-solutions).
+
+For code-based contribution, first decide if you want to work on this
+repository or fork it to something entirely different.
+
+The [CONTRIBUTING](./CONTRIBUTING.md) guide in this repo contains development instructions,
+including singing & sign-off configuration. You will usually want this file
+in your own repositories.
+
+Non-exhaustive list of changes that are very welcome:
+
+- More interactive integrations with high-value elisp development workflows
+- Running additional or better kinds of tests & lints
+- Fix bugs
+- Expose trivial options where a structural choice has limited them
+ unnecessarily
+- Behave the same, but with a less complicated code
+- Guix or other pure dependency management support
+
+Changes will likely be rejected if it is aimed at:
+
+- Non-elisp interfaces meant for invocation outside of Emacs or with scripting
+ implemented in a language besides elisp.
+- Managing dependencies outside of Nix (or other pure dependency management)
+ expressions
+- CI infrastructure support for non-Actions infrastructure (which cannot be
+ tested in this repo)
+- Backwards compatibility for Emacs two versions behind next release. Master,
+ current stable release, and release - 1 are the only versions being supported
+- pre-flake Nix support
+- Guix support **if it interferes with Nix support**
+
+
+# Footnote on FSF and Emacs Core Licensing
+
+Free Software Foundation (FSF) frequently requires copyright assignment on all
+code that goes into Emacs core. Many free software projects formerly requiring
+copyright assignment have since switched to using a Developer Certificate of
+Origin. DCO sign-off is a practice accepted by git, GCC, and the [Linux
+Kernel](https://wiki.linuxfoundation.org/dco).
+
+Doing DCO sign-off is not the same as copyright assignment, and serves a
+slightly different purpose. DCO sign-off is an attestation from the submitter
+stating that they have sufficient direct or transitive authority make their
+submission under the terms of the license of the recieving project. Copyright
+assignment serves a more offensive role in the case of GPL non-compliance,
+giving FSF alone legal standing. If you don't care about FSF being able to
+sue people, the DCO should suffice.
+
+Using the DCO **may** make it easier for code in your project to be included in
+Emacs core later. **It is the intent of this choice to steer FSF towards
+DCO-like solutions in order to accelerate code flow into Emacs.** Regardless of
+FSF's ongoing position on use of DCO's, by requiring DCO sign-off and GPG
+signature, you can be assured that changes submitted to a code base you
+control are strongly attested to be covered by the license you chose.
+
+
+# Shout-outs
+
+- [alphapapa](https://github.com/alphapapa) for being super prolific at everything, including package writing,
+ documentation, and activity on various social platforms
+- [adisbladis](https://github.com/adisbladis) for the Nix overlay that makes the CI and local development so nice
+- [NobbZ](https://github.com/NobbZ) for being all over the Nix & Emacs interwebs
+- [FSF](https://www.fsf.org/) and all contributors to Emacs & packages for the Yak shaving club
+
diff --git a/README.org b/README.org
deleted file mode 100644
index 07e2fe5..0000000
--- a/README.org
+++ /dev/null
@@ -1,492 +0,0 @@
-#+TITLE: Elisp Repo Kit (ERK)
-
-#+HTML:
-#+HTML:
-#+HTML:
-
-This repository is a kit to start a new elisp package repository on GitHub. The
-package contained has commands to streamline elisp development.
-
-* Quickly set up an Emacs Lisp repository on GitHub with:
-
-- An [[https://www.youtube.com/watch?v=RQK_DaaX34Q&list=PLEoMzSkcN8oPQtn7FQEF3D7sroZbXuPZ7][elisp]] package
-- CI with [[https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs][GitHub Actions]], configured for Darwin (MacOS) and Linux
-- [[https://nixos.org/#examples][Nix]] environment for obtaining dependencies or reproducibly developing CI
- locally
-- Licensing, [[https://developercertificate.org/][DCO]], DCO sign-off checks, PR template and [[./CONTRIBUTING.org][CONTRIBUTING]] instructions
-- [[https://github.com/melpa/melpa][MELPA]] publishing compatible
-
-*To get started:*
-
-Install the package and run =erk-new=, provide a directory, and
-answer all the questions.
-
-** Install ERK
-
- #+begin_src elisp
-
- (use-package erk) ; vanilla
-
- ;; using elpaca's with explicit recipe
- (use-package erk
- :elpaca (erk :host github :repo "positron-solutions/elisp-repo-kit"))
-
- ;; straight with explicit recipe
- (use-package erk
- :straight (erk :type git :host github :repo "positron-solutions/elisp-repo-kit"))
-
- ;; or use melpa, manual load-path & require, you brave yak shaver
-
- #+end_src
-
- =erk-new= will ask for:
-
- - Root directory you want to clone to
- - Package name
- - Package prefix
- - Author name
- - GitHub user or organization
- - Email address
-
- The =erk-new= calls =erk-rename-relicense= to rename all of the files, string
- replace names, and re-license to GPL3. Now just follow the steps in
- [[#finish-setting-up-your-new-github-repo][finish setting up]] Have fun!
-
-*** Manual cloning
-
- The standalone command, =erk-clone= will clone without renaming.
-
- This repo is also a [[https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template][template repository]], so you can fork without forking
- (Bruce Lee).
-
- If you create via template or clone manually, it's presumed you know what
- you're doing at that point. Call =erk-rename= on its own to rename
- in these cases.
-
- There are some customize options that cause the renaming to be transitively
- consistent.
-
-*** Manually Add Just CI
-
- Copy the .github folder and the contributing guide to your package. Set up
- your secrets for Cachix. Read the CI customization section.
-
-* Contents
-:PROPERTIES:
-:TOC: :include siblings :ignore this
-:END:
-:CONTENTS:
-- [[#using-erk-for-development][Using ERK for development]]
- - [[#run-tests][Run tests]]
- - [[#loading-and-re-loading-your-package][Loading and re-loading your package]]
- - [[#duplicating-ci-locally][Duplicating CI Locally]]
-- [[#finish-setting-up-your-new-github-repo][Finish setting up your new GitHub repo]]
- - [[#optional-steps][Optional Steps]]
-- [[#overview-of-file-contents-and-structure][Overview of file contents and structure]]
-- [[#customizing-ci][Customizing CI]]
-- [[#licensing-developer-certificate-of-origin][Licensing, Developer Certificate of Origin]]
-- [[#publishing-to-melpa][Publishing to MELPA]]
- - [[#creating-the-recipe][Creating the recipe]]
- - [[#testing-package-build][Testing package build]]
- - [[#testing-stable-package-build][Testing stable package build]]
- - [[#melpa-lints][MELPA Lints]]
-- [[#maintaining-nixpkgs-versions][Maintaining nixpkgs versions]]
-- [[#package-scope-and-relation-to-other-work][Package scope and relation to other work]]
- - [[#dependency-management][Dependency Management]]
- - [[#discovering-and-running-tests--lints][Discovering and Running Tests & Lints]]
- - [[#comparisons][Comparisons]]
-- [[#contributing][Contributing]]
-- [[#footnote-on-fsf-and-emacs-core-licensing][Footnote on FSF and Emacs Core Licensing]]
-- [[#shout-outs][Shout-outs]]
-:END:
-
-* Using ERK for development
-
- Elisp repo kit contains some convenience functions to reload your package and
- to discover and run ert tests. These shortcuts just make common cases faster.
-
-** Run tests
-
- Run =erk-ert-project= within your project. The tests will be discovered,
- rebuilt & reloaded if necessary, and run. There are a few other commands to
- augment the [[https://www.gnu.org/software/emacs/manual/html_node/ert/][ert]] package.
-
-** Loading and re-loading your package
-
- Run =erk-reload-project-package= in one of your project files. The features
- will be recompiled and reloaded.
-
- The =erk-reload-project-tests= is the complementary command for tests.
-
-** Duplicating CI Locally
-
- The CI configuration is all stored in [[.github/][.github]]. Usually you will want
- development instructions in your new repository. The [[./CONTRIBUTING.org][CONTRIBUTING]] guide
- contains instructions to reproduce the CI behavior.
-
-* Finish setting up your new GitHub repo
-
- You can copy this checklist to your org agenda files:
-
- - [X] Create a repository (from [[#Install erk][install]] instructions)
- - [ ] Create an empty GitHub repository and check the git remote configuration
- - [ ] Set up your git commit signing (and verification so that it's obvious)
- *and* [[#sign-off][sign-off]] so that it will be [[#Footnote-on-FSF-and-Emacs-Core-Licensing][straightforward]] for for FSF to pull in your
- changes if they later change to DCO instead of copyright assignment.
- - [ ] Sign up for [[https://app.cachix.org/][cachix]] and, create a binary cache with API tokens and public
- read access
- - [ ] Add repository secrets necessary for your GitHub actions =CACHIX_AUTH_TOKEN= and
- =CACHIX_CACHE_NAME= (settings -> secrets -> new repository secret)
- - [ ] Enable actions and add the following actions to your allowed actions
- list:
-
- #+begin_src
-
- actions/checkout@v3.2.0,
- cachix/cachix-action@v12,
- cachix/install-nix-action@v20,
- actions/setup-python@v4,
-
- #+end_src
-
- *Note*, Python is used to run a DCO check script, nothing more.
-
- - [ ] Get your package working, pushed, actions run, and CI badges all green
- - [ ] [[#Publishing-to-melpa][Publish]] to MELPA
- - [ ] Make a post on [[https://old.reddit.com/r/emacs/][reddit]] and [[https://emacs.ch/][mastodon]] about your new package
-
-** Optional Steps
-
- - [ ] Install =org-make-toc= for the automatic TOC generation in this org
- document to work.
- - [ ] Branch protect and enable check requirements for your default branch
- (usually master). Merge commits, verified only, and no force push are
- recommended settings.
- - [ ] Enable requiring contributors to sign-off on web-based commits
- - [ ] For security of your Cachix secrets and any other secrets you may someday
- add, require Actions approval for all outside contributors and leave
- repository permissions at read-only
-
- Cachix is somewhat optional. It's free for open-source projects. It's about as
- easy to sign up and generate the token as to remove the step from the GitHub
- actions, so you won't save much time by avoiding it.
-
- *If you opt out of cachix or any other binary cache, you will
- definitely want to turn off tests for =emacsGit= etc because the
- build times are about 30min-1hr per run when a fresh Emacs must be
- built.*
-
-* Overview of file contents and structure
-
- /After cloning and renaming,/ you will have a file tree like this:
-
- #+begin_src shell
-
- ├── .gitignore # ignores for byte compiles, autoloads etc
- │
- ├── README.org # this file
- ├── CONTRIBUTING.org # typical instructions for development
- ├── COPYING # a GPL3 license
- ├── DCO # Developer Certificate of Origin
- │
- ├── .github
- │ ├── .envrc # direnv integration with `nix develop`
- │ ├── flake.nix # dependencies for this project
- │ ├── flake.lock # version controlled lock of flake.nix input versions
- │ ├── run-shim.el # elisp script with test & lint routines
- │ ├── pull_request_template.md # reminders for PR contributors
- │ └── workflows
- │ ├── ci.yml # workflow for lints and tests
- │ └── dco.yml # workflow to check DCO sign-offs
- │
- ├── lisp
- │ └── erk.el # the package
- │
- └── test
- └── erk-test.el # ERT unit tests
-
- #+end_src
-
- You can use either a multi-file or flat layout for lisp. Just name test files
- ~something-test.el~ and keep all lisp files in root, ~/lisp~ or ~/test~
- directories.
-
-* Customizing CI
-
- The [[.github/run-shim.el][run-shim.el]] script is just provides a CLI interface for adding commands in
- the [[.github/workflows/ci.yml][ci.yml]] CI declaration. Each action step just loads the shell, declared in
- the [[.github/flake.nix][flake.nix]] and then runs the shim in Emacs. The shim consumes the CLI
- command arguments, so you can parameterize the invocations that way.
-
- - If you need extra elisp dependencies during CI, add them to the =epkgs= list
- in the flake.nix.
- - If you need extra 3rd party dependencies, add them to =packages= in the call
- to =mkShell=.
- - To invoke different elisp operations, add / modify the commands in
- [[.github/run-shim.el][run-shim.el]].
-
- There's more information in [[CONTRIBUTING.org][CONTRIBUTING]] about running commands locally. You
- will want this information in your new repository.
-
-* Licensing, Developer Certificate of Origin
-
- This template project is distributed with the MIT license. =erk-new= will also
- run =erk-rename-relicense=, which will automatically switch to the GPL3
- license. *The MIT license allows re-licensing, and so this change is
- compatible.* If you accept non-trivial changes to your project, it will be
- very hard to change to the GPL3 later, so consider this choice.
-
- The new repository will also come with DCO sign-off checking on PR's. The
- instructions are in the [[./CONTRIBUTING.org][CONTRIBUTING]] guide. A DCO sign-off policy will give
- your project a clear attestation of sufficient direct or transitive authority
- from each contributor to submit changes under the terms of your project's
- license. This can only improve your legal protection from incidentally
- handling copyrighted code.
-
- The DCO choice in this repository is also meant to encourage & push stodgy
- organizations whose responsibility it was to invent better processes towards
- lower friction paths to contribute code. If you fail to implement the DCO
- sign-off scheme, there is less hope that the FSF will someday independently
- merge changes that accumulate in your package because there will not be a
- .
-
-* Publishing to MELPA
-
- If you have green CI, you have already passed many requirements of publishing a
- MELPA package. *You still need to build your package and verify your recipe.*
- You are going to clone melpa in order to make your PR. You can use the clone to
- verify the recipe.
-
-** Creating the recipe
-
- Fork MELPA personally (not for organization) and clone it to wherever you keep
- your upstreams. It's a good idea to separate upstreams from projects you
- actively maintain so you can see and delete upstreams when not in use.
-
- #+begin_src shell
-
- mkdir -p upstream
- cd upstream
- git clone git@github.com:$GITHUB_USER/melpa.git # replace $GITHUB_USER
-
- #+end_src
-
- Install package-build
-
- #+begin_src elisp
- (use-package package-build)
- #+end_src
-
- =package-build-create-recipe= will give you something like:
-
- #+begin_src elisp
- (erk :fetcher github :repo "positron-solutions/elisp-repo-kit")
- #+end_src
-
- The following template can be filled in and pull-requested to MELPA to publish.
- You don't need to touch ~:files~. The ~commit~ and ~branch~ are optional
- depending on how you version / develop / tag your releases.
-
- Copy the recipe into =recipes/erk= inside your MELPA clone.
-
-** Testing package build
-
- Inside the MELPA clone root:
-
- #+begin_src shell
-
- # Builds the package
- make recipes/erk
- # Test sandbox installation (will affect ~/.emacs.d/elpa So much for sandbox ¯\_(ツ)_/¯
- EMACS_COMMAND=$(which emacs) make sandbox INSTALL=erk
-
- #+end_src
-
-** Testing stable package build
-
- You need a tag on your default (usually master) branch of your repo,
- =positron-solutions/elisp-repo-kit=. Use =git tag -S v0.1.0= and =git push
- origin v0.1.0=. You can also just create a release in the GitHub interface.
-
- #+begin_src shell
-
- # Test stable builds against your tags
- STABLE=t make recipes/erk
-
- #+end_src
-
-** MELPA Lints
-
- Lastly, install [[https://github.com/riscy/melpazoid][melpazoid]] and call =melpazoid= on your main feature. It does
- some additional lints. You may need to install =package-lint= if you don't have
- it. It's not declared in melpazoid's requirements. Getting the package in Nix
- is not easy yet since melpazoid is not yet on Melpa.
-
- #+begin_src elisp
-
- (straight-use-package
- '(melpazoid :type git :host github :repo "riscy/melpazoid" :files ("melpazoid/melpazoid.el")))
-
- #+end_src
-
- If everything works, you are ready to make a pull request to MELPA. Push your
- changes and check all the boxes in the PR template except the one that requires
- you to read the instructions.
-
-* Maintaining nixpkgs versions
-
- Nixpkgs has a new release about every six months. You can check their [[https://github.com/NixOS/nixpkgs/branches][branches]]
- and [[https://github.com/NixOS/nixpkgs/tags][tags]] to see what's current. To get updated dependencies from MELPA, it's
- necessary to update the emacs-overlay with =nix flake lock --update-input
- emacs-overlay=. You can also specify revs and branches if you need to roll
- back. There is a make shortcut: =make flake-update= MacOS tends to get a little
- less test emphasis, and so =nixpkgs-darwin-= branches exist and are
- required to pass more Darwin tests before merging. This is more stable if you
- are on MacOS. =nixpkgs-unstable= or =master= are your other less common options.
-
-* Package scope and relation to other work
-
- There are two functional goals of this repository:
-
- - Automate the annoying work necessary to set up a new repository
- - Streamline common elisp development workflows
-
- Commands within this package will focus on cleaner integration of the tests
- and lints with Emacs. There has been a lot of work in this area, but much of
- it is tangled with dependency management and sandbox creation. Much of it is
- done in languages other than elisp and focused on non-interactive workflows
- with no interactive integration on top.
-
- Providing close to out-of-box CI is a big focus. By making it easier to
- qualify changes from other users, it becomes less burdonsome to maintain
- software, and by extension, less burdensom to publish and create software. The
- effect is to drive creation of elisp in a way that can accelerate the flow of
- elisp into Emacs itself.
-
-** Dependency Management
-
- This repository uses pure dependency management and then levarages it to
- provide dependencies for development and CI environments. The resulting user
- experience is built around CI for reproducibility and interactive testing for
- development speed.
-
- Because most elisp dependencies can be obtained without extensive system
- dependency management, many tools for testing Emacs packages provide
- dependency management and loading those dependencies into a fresh Emacs
- instance. This aligns well with ad-hoc sandboxed local testing. This was
- fine in the old days of impure dependency management and dirty environments.
-
- The [[https://github.com/nix-community/emacs-overlay][Emacs Nix Overlay]] and Emacs support within nixpkgs make it possible to
- stating and obtaining elisp dependencies in a completely pure way. Non-elisp
- dependencies are trivially provided form nixpkgs. Nix is extremely reliable
- at dependency management, and it is no surprise that much complexity is
- normalized away by just the basic behavior model of Nix. In addition, *if
- your project needs or includes additional binary dependencies or modules*,
- Nix is an excellent way to provide them to CI and users.
-
-** Discovering and Running Tests & Lints
-
- During development, the commands provided under the =erk-= prefix make it
- more convenient to reload your package and test features. You can run the
- ert tests for a project while working on multiple packages.
-
- During CI, this repository uses an elisp shim for discovering and running
- tests. The commands within the package for convenience during development
- are not depeneded upon during CI.
-
- The CI actions obtain an environment with dependencies using Nix, so this can
- also be done locally using Nix, meaning re-creating environments is available
- to the user without leaning on CI.
-
-** Comparisons
-
- There are many comparisons available to understand the roles of similar tools
- and how they relate to each other.
-
- - [[https://github.com/alphapapa/makem.sh#comparisons][makem.sh]]
- - [[https://github.com/doublep/eldev#see-also][Eldev]]
- - [[https://github.com/emacs-twist/nomake][nomake]] Is another project with Nix work
-
- [[https://github.com/purcell/nix-emacs-ci][nix-emacs-ci]] capture the work needed to provide a running Emacs to CI. Tools
- like [[https://github.com/doublep/eldev#continuous-integration][eldev]] and [[https://github.com/alphapapa/makem.sh/blob/master/test.yml][makem.sh]] have support for providing dependencies to that Emacs.
- The Nix flake [[./flake.nix][in this project]] describes both of these tasks. Makem and Eldev
- etc document Gihub workflows, but *the workflows in this repository are meant to
- be used out-of-the-box after cloning*, although to be fair, there's more
- decisions than actual work.
-
- Nix-emacs-ci provides a lot of backwards-compatibility versions of Emacs. The
- nix-overlay is more forward looking, providing =emacsGit= and sometimes other
- upstream branches when a big feature like native compilation is in the pipeline.
- Nix-emacs-ci is also still using legacy Nix, without flakes. Flakes are just
- nicer and the way Nix is going.
-
-* Contributing
-
- For turn-key contribution to the software ecosystem that keeps you moving, see
- the funding links.
-
- For code-based contribution, first decide if you want to work on this
- repository or fork it to something entirely different.
-
- The [[./CONTRIBUTING.org][CONTRIBUTING]] guide in this repo contains development instructions,
- including singing & sign-off configuration. You will usually want this file
- in your own repositories.
-
- Non-exhaustive list of changes that are very welcome:
-
- - More interactive integrations with high-value elisp development workflows
- - Running additional or better kinds of tests & lints
- - Fix bugs
- - Expose trivial options where a structural choice has limited them
- unnecessarily
- - Behave the same, but with a less complicated code
- - Guix or other pure dependency management support
-
- Changes will likely be rejected if it is aimed at:
-
- - Non-elisp interfaces meant for invocation outside of Emacs or with scripting
- implemented in a language besides elisp.
- - Managing dependencies outside of Nix (or other pure dependency management)
- expressions
- - CI infrastructure support for non-Actions infrastructure (which cannot be
- tested in this repo)
- - Backwards compatibility for Emacs two versions behind next release. Master,
- current stable release, and release - 1 are the only versions being supported
- - pre-flake Nix support
- - Guix support that interferes with Nix support
-
-* Footnote on FSF and Emacs Core Licensing
-
- Free Software Foundation (FSF) frequently requires copyright assignment on all
- code that goes into Emacs core. Many free software projects formerly requiring
- copyright assignment have since switched to using a Developer Certificate of
- Origin. DCO sign-off is a practice accepted by git, GCC, and the [[https://wiki.linuxfoundation.org/dco][Linux
- Kernel]].
-
- Doing DCO sign-off is not the same as copyright assignment, and serves a
- slightly different purpose. DCO sign-off is an attestation from the submitter
- stating that they have sufficient direct or transitive authority make their
- submission under the terms of the license of the recieving project. Copyright
- assignment serves a more offensive role in the case of GPL non-compliance,
- giving FSF alone legal standing. If you don't care about FSF being able to
- sue people, the DCO should suffice.
-
- Using the DCO *may* make it easier for code in your project to be included in
- Emacs core later. *It is the intent of this choice to steer FSF towards
- DCO-like solutions in order to accelerate code flow into Emacs.* Regardless of
- FSF's ongoing position on use of DCO's, by requiring DCO sign-off and GPG
- signature, you can be assured that changes submitted to a code base you
- control are strongly attested to be covered by the license you chose.
-
-* Shout-outs
-
- - [[https://github.com/alphapapa][alphapapa]] for being super prolific at everything, including package writing,
- documentation, and activity on various social platforms
- - [[https://github.com/adisbladis][adisbladis]] for the Nix overlay that makes the CI and local development so nice
- - [[https://github.com/NobbZ][NobbZ]] for being all over the Nix & Emacs interwebs
- - [[https://www.fsf.org/][FSF]] and all contributors to Emacs & packages for the Yak shaving club
-
-# Local Variables:
-# before-save-hook: (lambda () (when (require 'org-make-toc nil t) (org-make-toc)))
-# org-make-toc-link-type-fn: org-make-toc--link-entry-github
-# End:
diff --git a/CONTRIBUTING.org b/docs/CONTRIBUTING.org
similarity index 74%
rename from CONTRIBUTING.org
rename to docs/CONTRIBUTING.org
index 14ceb23..e86bdf0 100644
--- a/CONTRIBUTING.org
+++ b/docs/CONTRIBUTING.org
@@ -1,28 +1,12 @@
#+TITLE: Contributing
+#+EXPORT_FILE_NAME: ../CONTRIBUTING.md
+#+OPTIONS: toc:nil broken-links:mark num:nil
+
+[comment]: !!!THIS FILE HAS BEEN GENERATED!!! Edit README.org
Development process & infrastructure guide.
-* Contents
-:PROPERTIES:
-:TOC: :include siblings :ignore this
-:END:
-:CONTENTS:
-- [[#development][Development]]
- - [[#running-tests][Running tests]]
- - [[#running-tests-ci-style][Running tests CI style]]
- - [[#lint-and-byte-compile-code][Lint and byte-compile code]]
- - [[#loading-and-re-loading-your-package][Loading and re-loading your package]]
- - [[#manual-loading--reloading][Manual Loading & Reloading]]
-- [[#license][License]]
-- [[#developer-certificate-of-origin-dco][Developer Certificate of Origin (DCO)]]
- - [[#sign-off][Sign-off]]
- - [[#gpg-signature][GPG signature]]
- - [[#user-setup-for-submitting-changes][User setup for submitting changes]]
- - [[#automatically-add-sign-off][Automatically add sign-off]]
- - [[#automatic-gpg-signing-with-per-project-keys][Automatic GPG signing with per-project keys]]
- - [[#manually-signing--adding-sign-off][Manually signing & adding sign-off]]
-- [[#maintaining-nixpkgs-versions][Maintaining nixpkgs versions]]
-:END:
+#+TOC: headlines 2
* Development
@@ -61,12 +45,12 @@ Development process & infrastructure guide.
This package uses [[https://github.com/gonewest818/elisp-lint][elisp-lint]] to detect issues with byte compiling, package
format, code structure and others.
- The configuration is found inside [[.github/run-shim.el][.github/run-shim.el]]. The CI run is invoked
- inside of [[.github/workflows/ci.yml][ci.yml]] using Emacs in script mode. Most of the configuration is in
+ The configuration is found inside [[../.github/run-shim.el][.github/run-shim.el]]. The CI run is invoked
+ inside of [[../.github/workflows/ci.yml][ci.yml]] using Emacs in script mode. Most of the configuration is in
the run shim.
The tests are also linted, to a less restrictive standard, also found in
- [[.github/run-shim.el][run-shim.el]]
+ [[../.github/run-shim.el][run-shim.el]]
You can run the lints manually almost the same as running tests.
#+begin_src bash
@@ -138,9 +122,10 @@ Development process & infrastructure guide.
Refer to the [[https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits][GitHub signing commits]] instructions to set up your git client
to add GPG signatures. File issues if you run into Emacs-specific problems.
+ Be sure to use a Github verified email.
Because signing is intended to be a conscious process, please remember to
- read and understand the [[./DCO][Developer Certificate of Origin]] before confinguring
+ read and understand the [[../DCO][Developer Certificate of Origin]] before confinguring
your client to automatically sign-off on commits.
*** Automatically add sign-off
@@ -211,18 +196,31 @@ Development process & infrastructure guide.
git rebase -i
#+end_src
-* Maintaining nixpkgs versions
-
- Nixpkgs has a new release about every six months. You can check their [[https://github.com/NixOS/nixpkgs/branches][branches]]
- and [[https://github.com/NixOS/nixpkgs/tags][tags]] to see what's current. To get updated dependencies from MELPA, it's
- necessary to update the emacs-overlay with =nix flake lock --update-input
- emacs-overlay=. You can also specify revs and branches if you need to roll
- back. There is a make shortcut: =make flake-update= MacOS tends to get a little
- less test emphasis, and so =nixpkgs-darwin-= branches exist and are
- required to pass more Darwin tests before merging. This is more stable if you
- are on MacOS. =nixpkgs-unstable= or =master= are your other less common options.
-
+** Maintaining versions
+#+begin_comment
+This heading is duplicated in the manual.org. The Contributing guide is
+frequently copied around whole because it's not that unique between
+repositories using ERK tooling.
+#+end_comment
+
+ The Nix [[../github/flake.nix][flake.nix]] is where versions are declared. The [[../.github/flake.lock][flake.lock]] stores a
+ fixed value for these declarations. These fixed versions need periodic
+ update. Nixpkgs has a new release about every six months. You can check
+ their [[https://github.com/NixOS/nixpkgs/branches][branches]] and [[https://github.com/NixOS/nixpkgs/tags][tags]] to see what's current. The effect is similar to
+ updating linux versions. The ~nix~ command has a lot of support for
+ specifying versions besides just updating.
+
+ #+begin_src shell
+ nix flake lock --update-input nixpkgs
+ #+end_src
+
+ The ~emacs-overlay~, which contains fixed versions of Emacs and snapshots of
+ Elisp repository package sets can be updated by running:
+
+ #+begin_src shell
+ nix flake lock --update-input emacs-overlay
+ #+end_src
+
# Local Variables:
-# before-save-hook: (lambda () (when (require 'org-make-toc nil t) (org-make-toc)))
-# org-make-toc-link-type-fn: org-make-toc--link-entry-github
+# after-save-hook: (erk-export-contributing)
# End:
diff --git a/docs/README.org b/docs/README.org
new file mode 100644
index 0000000..e338e50
--- /dev/null
+++ b/docs/README.org
@@ -0,0 +1,224 @@
+#+title: Elisp Repo Kit (ERK)
+#+export_file_name: ../README.md
+#+options: toc:nil broken-links:mark num:nil
+
+[comment]: !!!THIS FILE HAS BEEN GENERATED!!! Edit README.org
+
+#+begin_export html
+
+
+
+#+end_export
+
+This repository is a kit to start a new elisp package repository on GitHub. The
+package contained has commands to streamline elisp development.
+
+* Quickly set up an Emacs Lisp repository on GitHub with:
+ :PROPERTIES:
+ :UNNUMBERED: notoc
+ :END:
+
+- An [[https://www.youtube.com/watch?v=RQK_DaaX34Q&list=PLEoMzSkcN8oPQtn7FQEF3D7sroZbXuPZ7][elisp]] package
+- CI with [[https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs][GitHub Actions]], configured for Darwin (MacOS) and Linux
+- Built-in Emacs info manual generation
+- [[https://nixos.org/#examples][Nix]] environment for obtaining dependencies or reproducibly developing CI
+ locally
+- Licensing, [[https://developercertificate.org/][DCO]], DCO sign-off checks, PR template and [[./CONTRIBUTING.org][CONTRIBUTING]] instructions
+- [[https://github.com/melpa/melpa][MELPA]] publishing compatible
+
+*To get started:*
+
+Install the package and run =erk-new=, provide a directory, and
+answer all the questions.
+
+* Install ERK
+ :PROPERTIES:
+ :UNNUMBERED: notoc
+ :END:
+#+include: "manual.org::*Install ERK" :only-contents t
+#+toc: headlines 2
+#+include: "manual.org::*Creating Packages" :minlevel 1
+#+include: "manual.org::*Using ERK for development" :minlevel 1
+#+include: "manual.org::*File contents and structure" :minlevel 1
+
+* Finish setting up your new GitHub repo
+#+include: "manual.org::*Setting Up Your Github Repository" :only-contents t
+
+#+include: "manual.org::*Customizing CI" :minlevel 1
+#+include: "manual.org::*Licensing, Developer Certificate of Origin" :minlevel 1
+#+include: "manual.org::*Publishing to MELPA" :minlevel 1
+#+include: "manual.org::*Maintaining versions" :minlevel 1
+
+* Package scope and relation to other work
+
+ There are two functional goals of this repository:
+
+ - Automate the annoying work necessary to set up a new repository
+ - Streamline common elisp development workflows
+
+ Commands within this package will focus on cleaner integration of the tests
+ and lints with Emacs. There has been a lot of work in this area, but much of
+ it is tangled with dependency management and sandbox creation. Much of it is
+ done in languages other than elisp and focused on non-interactive workflows
+ with no interactive integration on top.
+
+ Providing close to out-of-box CI is a big focus. By making it easier to
+ qualify changes from other users, it becomes less burdonsome to maintain
+ software, and by extension, less burdensom to publish and create software. The
+ effect is to drive creation of elisp in a way that can accelerate the flow of
+ elisp into Emacs itself.
+
+** Dependency Management
+
+ This repository uses pure dependency management and then leverages it to
+ provide dependencies for development and CI environments. The resulting user
+ experience is built around CI for reproducibility and interactive testing for
+ development speed.
+
+ Because most elisp dependencies can be obtained without extensive system
+ dependency management, many tools for testing Emacs packages provide
+ dependency management and loading those dependencies into a fresh Emacs
+ instance. This aligns well with ad-hoc sandboxed local testing. This was
+ fine in the old days of impure dependency management and dirty environments.
+
+ The [[https://github.com/nix-community/emacs-overlay][Emacs Nix Overlay]] and Emacs support within nixpkgs make it possible to
+ stating and obtaining elisp dependencies in a completely pure way. Non-elisp
+ dependencies are trivially provided form nixpkgs. Nix is extremely reliable
+ at dependency management, and it is no surprise that much complexity is
+ normalized away by just the basic behavior model of Nix. In addition, *if
+ your project needs or includes additional binary dependencies or modules*,
+ Nix is an excellent way to provide them to CI and users.
+
+** Discovering and Running Tests & Lints
+
+ During development, the commands provided under the =erk-= prefix make it
+ more convenient to reload your package and test features. You can run the
+ ert tests for a project while working on multiple packages.
+
+ During CI, this repository uses an elisp shim for discovering and running
+ tests. The commands within the package for convenience during development
+ are not depeneded upon during CI.
+
+ The CI actions obtain an environment with dependencies using Nix, so this can
+ also be done locally using Nix, meaning re-creating environments is available
+ to the user without leaning on CI.
+
+** Comparisons
+ There are many tools for running Elisp tests. Most of them are well
+ integrated with some dependency management. Most of them have some published
+ CI integrations to draw inspiration from. These patterns are common because
+ the needs arise together.
+*** ERK's Key Characteristics
+
+ - Quickly spin up nearly complete starter projects
+ - Fully working CI, packaging, and documentation manual scheme
+ - Immediately run tests and get into the virtuous feedback loop
+ - Nix dependency management, bringing both Elisp and 3rd party dependencies
+ under full control
+
+ As a template for your project, *ERK leans towards being opinionated* in
+ order to provide complete behavior out of the box. The trade-off of being
+ closer to a completed project while still being minimal is only supporting
+ one hosting platform, *Github, and its Github Actions CI infrastructure.* You
+ can adapt around this easily because it's not a complex project, but you will
+ do it on your own.
+
+ This project favors the *Nix dependency tooling* for extreme reproducibility
+ and access to a *huge* number of 3rd party dependencies on most platforms.
+ If you want to implement sandboxed tests or test with a specific version of
+ dependencies, you can do it in a pollution-free way across numerous versions
+ with Nix. Everyone on most platforms can reproduce your work in a way that
+ doesn't pollute their system either (beyond installing Nix).
+
+*** Other Comparisons
+
+ There are many comparisons available to understand the roles of similar tools
+ and how they relate to each other.
+
+ - [[https://github.com/alphapapa/makem.sh#comparisons][makem.sh]]
+ - [[https://github.com/doublep/eldev#see-also][Eldev]]
+ - [[https://github.com/emacs-twist/nomake][nomake]] Is another project with Nix work
+
+ [[https://github.com/purcell/nix-emacs-ci][nix-emacs-ci]] capture the work needed to provide a running Emacs to CI. Tools
+ like [[https://github.com/doublep/eldev#continuous-integration][eldev]] and [[https://github.com/alphapapa/makem.sh/blob/master/test.yml][makem.sh]] have support for providing dependencies to that Emacs.
+ The Nix flake [[../flake.nix][in this project]] describes both of these tasks. Makem and Eldev
+ etc document Gihub workflows, but *the workflows in this repository are meant to
+ be used out-of-the-box after cloning*, although to be fair, there's more
+ decisions than actual work.
+
+ Nix-emacs-ci provides a lot of backwards-compatibility versions of Emacs.
+ The emacs-nix-overlay that this project employs is more forward looking,
+ providing =emacsGit= and sometimes other upstream branches when a big
+ feature like native compilation is in the pipeline. Nix-emacs-ci is also
+ still using legacy Nix, without flakes. Flakes are just nicer and the way
+ Nix is going.
+
+* Contributing
+
+ For turn-key contribution to the software ecosystem that keeps you moving, see
+ the [[https://github.com/sponsors/positron-solutions][funding links]].
+
+ For code-based contribution, first decide if you want to work on this
+ repository or fork it to something entirely different.
+
+ The [[./CONTRIBUTING.org][CONTRIBUTING]] guide in this repo contains development instructions,
+ including singing & sign-off configuration. You will usually want this file
+ in your own repositories.
+
+ Non-exhaustive list of changes that are very welcome:
+
+ - More interactive integrations with high-value elisp development workflows
+ - Running additional or better kinds of tests & lints
+ - Fix bugs
+ - Expose trivial options where a structural choice has limited them
+ unnecessarily
+ - Behave the same, but with a less complicated code
+ - Guix or other pure dependency management support
+
+ Changes will likely be rejected if it is aimed at:
+
+ - Non-elisp interfaces meant for invocation outside of Emacs or with scripting
+ implemented in a language besides elisp.
+ - Managing dependencies outside of Nix (or other pure dependency management)
+ expressions
+ - CI infrastructure support for non-Actions infrastructure (which cannot be
+ tested in this repo)
+ - Backwards compatibility for Emacs two versions behind next release. Master,
+ current stable release, and release - 1 are the only versions being supported
+ - pre-flake Nix support
+ - Guix support *if it interferes with Nix support*
+
+* Footnote on FSF and Emacs Core Licensing
+
+ Free Software Foundation (FSF) frequently requires copyright assignment on all
+ code that goes into Emacs core. Many free software projects formerly requiring
+ copyright assignment have since switched to using a Developer Certificate of
+ Origin. DCO sign-off is a practice accepted by git, GCC, and the [[https://wiki.linuxfoundation.org/dco][Linux
+ Kernel]].
+
+ Doing DCO sign-off is not the same as copyright assignment, and serves a
+ slightly different purpose. DCO sign-off is an attestation from the submitter
+ stating that they have sufficient direct or transitive authority make their
+ submission under the terms of the license of the recieving project. Copyright
+ assignment serves a more offensive role in the case of GPL non-compliance,
+ giving FSF alone legal standing. If you don't care about FSF being able to
+ sue people, the DCO should suffice.
+
+ Using the DCO *may* make it easier for code in your project to be included in
+ Emacs core later. *It is the intent of this choice to steer FSF towards
+ DCO-like solutions in order to accelerate code flow into Emacs.* Regardless of
+ FSF's ongoing position on use of DCO's, by requiring DCO sign-off and GPG
+ signature, you can be assured that changes submitted to a code base you
+ control are strongly attested to be covered by the license you chose.
+
+* Shout-outs
+
+ - [[https://github.com/alphapapa][alphapapa]] for being super prolific at everything, including package writing,
+ documentation, and activity on various social platforms
+ - [[https://github.com/adisbladis][adisbladis]] for the Nix overlay that makes the CI and local development so nice
+ - [[https://github.com/NobbZ][NobbZ]] for being all over the Nix & Emacs interwebs
+ - [[https://www.fsf.org/][FSF]] and all contributors to Emacs & packages for the Yak shaving club
+
+# Local Variables:
+# after-save-hook: (erk-export-readme)
+# End:
diff --git a/docs/manual.org b/docs/manual.org
new file mode 100644
index 0000000..f4beeee
--- /dev/null
+++ b/docs/manual.org
@@ -0,0 +1,715 @@
+#+title: Elisp Repo Kit
+#+subtitle: for version {{{package-version}}}
+#+author: {{{package-author}}}
+#+email: {{{package-email}}}
+#+date: 2022-{{{year}}}
+#+property: header-args :eval no`
+#+options: broken-links:warn \n:nil ::t |:t ^:nil -:t f:t *:t <:t e:t ':t
+#+options: d:nil todo:nil pri:nil tags:not-in-toc stat:nil
+#+language: en
+#+texinfo_dir_category: Emacs
+#+texinfo_dir_title: Elisp Repo Kit: (erk)
+#+texinfo_dir_desc: Create, distribute, and maintain Emacs Lisp packages
+#+macro: package-version (eval (progn (require 'erk) (erk-package-version)))
+#+macro: package-author (eval (progn (require 'erk) (erk-package-author)))
+#+macro: package-email (eval (progn (require 'erk) (erk-package-email)))
+#+macro: year (eval (format-time-string "%Y"))
+#+texinfo_header: @comment !!!THIS FILE HAS BEEN GENERATED!!! Edit manual.org instead!
+
+Setting up a /complete/ Emacs Lisp package doesn't need to be a lot of work.
+Elisp Repo Kit provides a convenient starting point for collaborating on a
+public Elisp package repository:
+
+- An Elisp package
+- Tests
+- CI & dependency management
+- README and manual
+- Licensing
+
+Furthermore, to get rid of pitfalls and streamline productive workflows when
+working with Elisp packages, Elisp Repo Kit provides shortcuts:
+
+- Loading and unloading modules
+- Compiling
+- Running tests
+- Re-generating documentation
+- Navigating the project
+
+* High Level Overview
+
+ - As a repository, Elisp Repo Kit is a template for how to organize and
+ distribute your project.
+
+ - As an Elisp package, Elisp Repo Kit (erk) provides shortcuts for working on
+ package using the Elisp Repo Kit organization structure (as well as other
+ Elisp packages).
+
+** File contents and structure
+#+cindex: project layout
+
+ /After cloning and renaming,/ you will have a file tree like this:
+
+ #+begin_src shell
+
+ ├── .gitignore # ignores for byte compiles, autoloads etc
+ │
+ ├── README.md # this file
+ ├── CONTRIBUTING.md # typical instructions for development
+ ├── COPYING # a GPL3 license
+ ├── DCO # Developer Certificate of Origin
+ │
+ ├── .github
+ │ ├── .envrc # direnv integration with `nix develop`
+ │ ├── flake.nix # dependencies for this project
+ │ ├── flake.lock # version controlled lock of flake.nix input versions
+ │ ├── run-shim.el # elisp script with test & lint routines
+ │ ├── pull_request_template.md # reminders for PR contributors
+ │ └── workflows
+ │ ├── ci.yml # workflow for lints and tests
+ │ └── dco.yml # workflow to check DCO sign-offs
+ │
+ ├── docs
+ │ ├── README.org # generates README.md
+ │ ├── CONTRIBUTING.org # generates CONTRIBUTING.md
+ │ ├── manual.org # actual manual
+ │ └── manual.texi # generated manual for distribution
+ │
+ ├── lisp
+ │ └── erk.el # the package
+ │
+ └── test
+ └── erk-test.el # ERT unit tests for the package
+
+ #+end_src
+
+ You can use either a multi-file or flat layout for lisp. Just name test files
+ ~something-test.el~ and keep all lisp files in root, ~/lisp~ or ~/test~
+ directories.
+** Developing
+ - The package is stored in /lisp and its tests in /test.
+ - Many shortcuts are provided to run tests or rebuild and reload the package
+ or to visit the unit tests for a function under point etc.
+ - Most of the Elisp shortcuts lean on Emacs settings or packages such as
+ ~auto-compile~ and ~ert~.
+** Documenting
+ - The document inputs are stored in /docs.
+ - They are *written* in org format
+ - The README for the Github home page is *exported* to markdown
+ - The Manual, which can be used to supplement the README, is itself
+ *exported* to texi which is converted to info for viewing within Emacs
+ - The CONTRIBUTING guide is *exported* to markdown
+** Distributing
+ - The repository is designed to be hosted on Github
+ - All CI files are stored under [[../.github/][./github]]. (You can include this directory
+ with minor modifications into other Elisp projects.)
+ - Github actions are included for CI.
+ - Dependencies for CI are obtained via Nix.
+ - You are free to submit your package for distribution on MELPA etc. This
+ package is made available on MELPA partly to maintain the structure and
+ workflows for doing so.
+* Install ERK
+
+ #+begin_src elisp
+
+ (use-package erk) ; vanilla
+
+ ;; using elpaca's with explicit recipe
+ (use-package erk
+ :elpaca (erk :host github :repo "positron-solutions/elisp-repo-kit"))
+
+ ;; straight with explicit recipe
+ (use-package erk
+ :straight (erk :type git :host github :repo "positron-solutions/elisp-repo-kit"))
+
+ ;; or use melpa, manual load-path & require, you brave yak shaver
+
+ #+end_src
+
+** Manual cloning
+
+ #+findex: erk-clone
+ The standalone command, ~erk-clone~ will clone without renaming.
+
+ This repo is also a [[https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template][template repository]], so you can fork without forking
+ (Bruce Lee).
+
+ #+findex: erk-rename
+ If you create via template or clone manually, it's presumed you know what
+ you're doing at that point. Call ~erk-rename~ on its own to rename
+ in these cases.
+
+ There are some customize options that cause the renaming to be transitively
+ consistent.
+
+** Manually add just CI
+
+ Copy the .github folder and the contributing guide to your package. Set up
+ your secrets for Cachix. Read the CI customization section.
+
+* Creating Packages
+
+ #+findex: erk-new
+ The simplest and intended way is to call ~erk-new~. It will first
+ ask you for:
+
+ - Root directory you want to clone to
+ - Package name
+ - Package prefix
+ - Author name
+ - GitHub user or organization
+ - Email address
+
+ #+findex: erk-rename-relicense
+ ~erk-new~ also calls ~erk-rename-relicense~ to rename all of the files, string
+ replace names, and re-license to GPL3. It also changes the author and resets
+ the git history. Now just follow the steps in [[*Finish setting up your new GitHub repo][finish setting up]] Have fun!
+* Using ERK for development
+ Elisp repo kit contains some convenience functions to reload your package and
+ to discover and run ert tests. These shortcuts just make common cases faster.
+ - Loading and re-loading your package
+ #+findex: erk-reload-project-package
+ ~erk-reload-project-package~ will unload and recompile your package if
+ necessary and then reload it.
+
+ #+findex: erk-reload-project-tests
+ ~erk-reload-project-tests~ is the complementary command for reloading tests.
+ - Run tests
+ #+findex: erk-ert-project~
+ ~erk-ert-project~ will discover, rebuild & reload if necessary, and run
+ tests. There are a few other commands to augment the [[https://www.gnu.org/software/emacs/manual/html_node/ert/][ert]] package.
+
+ - Duplicating CI Locally
+ The CI configuration is all stored in [[../.github/][.github]]. Usually you will want
+ development instructions in your new repository. The [[./CONTRIBUTING.org][CONTRIBUTING]] guide
+ contains instructions to reproduce the CI behavior.
+** Find Files
+ Accidentally editing generated files or forgetting the path to a file is
+ annoying. ERK provides a helper to find files based on their purpose.
+
+ #+findex: erk-find
+ ~erk-find~ will ask you to pick the file based on what it does. It's
+ choices:
+
+ - ci-dco
+ - ci-nix-flake
+ - ci-run-shim
+ - ci-tests
+ - docs-contributing
+ - docs-manual
+ - docs-readme
+
+ Generated files or extremely common files are not included. For each one of
+ these choices, there is a corresponding command:
+
+ #+findex: erk-find-ci-dco
+ - ~erk-find-ci-dco~
+ #+findex: erk-find-ci-nix-flake
+ - ~erk-find-ci-nix-flake~
+ #+findex: erk-find-ci-run-shim
+ - ~erk-find-ci-run-shim~
+ #+findex: erk-find-ci-test
+ - ~erk-find-ci-test~
+ #+findex: erk-find-docs-contributing
+ - ~erk-find-docs-contributing~
+ #+findex: erk-find-docs-manual
+ - ~erk-find-find-docs-manual~
+ #+findex: erk-find-docs-readme
+ - ~erk-find-docs-readme~
+
+* Documenting Your Package
+#+cindex: document re-structuring
+#+cindex: document export
+How this manual is created and maintained. Elisp Repo Kit's manual scheme
+overview:
+- Contents for the README and built-in manual are mostly stored in
+ [[./manual.org][/docs/manual.org]]
+- Each document stitches together the contents of [[./manual.org][/docs/manual.org]] using
+ =#+include:= directives. Some of the header, footer, and export information
+ just controls formatting.
+- The [[../README.md][README.md]] for your repository's home page is generated from [[./README.org][/docs/README.org]]
+- The [[./manual.texi]] is generated from [[./manual.org][/docs/manual.org]]
+- Re-generation-on-save is automatically configured at the end of each document
+- The .gitignore will ignore any intermediate outputs, so there's no need to
+ store them in /tmp or clean them
+
+** What makes a good manual
+ #+cindex: what makes a good manual
+ Manuals can do four things that code and code-based automatic indices are
+ fundamentally terrible at:
+
+ - Describe ideas at higher levels of abstraction, concepts which may have no
+ correct docstring to live in. This includes providing several levels of
+ abstraction or abstraction from different perspectives.
+ - Describe behavior or state models in implementations or external systems,
+ things that aren't even apparent from reading the code. Think
+ microprocessor behavior, 3rd party API behavior, or a code convention
+ implemented in multiple functions
+ - Examples that distill and illustrate ideas in isolation instead of how they
+ are naturally composed and become complex when applied in practice.
+ - Illuminate workflows and paths of understanding that do not follow the
+ linear ordering of code or any natural automatic index.
+
+ In short, a good manual ties together the very large or uncovers what is
+ opaque. Neither of these types of information have a 1:1 correspondence to
+ the definitions in your code.
+
+ From this lack of correspondence, we can also conclude that good manuals are
+ in fact *not exhaustive*. Exhaustive manuals are merely *exhausting*,
+ requiring tremendous maintenance to do what is already available through
+ automation or even just reading the code.
+
+*** Generative AI and manuals
+ One thing manuals had been good at was linking to concepts based on
+ conceptual relationship. While semantic search queries have been around for
+ a while, large language models have transformed the process, providing the
+ semantic output to the semantic search. As semantic search and semantic synthesis of
+ output become more accessible, it's becoming less important to conceptually
+ relating information to bridge the limitations of more exact types of search.
+
+ Increasingly, machine learning is becoming able to synthesize information
+ from numerous sources and present it via *natural language queryable
+ indices*. Keep in mind, when writing a manual, if the information you are
+ providing doesn't add information that is easily decideable from the other
+ information already available about your package, your manual is likely to
+ become increasingly redundant information.
+*** Automatic indexing
+ Your package's code also already has a ton of automatic indexing via Emacs
+ discovery:
+
+ - ~describe-function~ etc
+ - completions for functions, variables, commands, macros etc
+ - signature hints from eldoc
+ - searching within the code
+ - symbol-based navigation within the code
+
+ Documenting full enumerations of things in the same order that they live in
+ code or in the same order as automatic indexing commonly produces throughout
+ normal development is rarely useful. This information *does* have a natural
+ 1:1 correspondence to readily available information, and is therefore likely
+ redundant. If you wind up with a manual like this, it would be better to
+ leave the information in the code and generate the manual from the docstrings.
+** Re-Generating
+ Re-generation is configured to occur on save at the end of each document.
+ You can manually re-generate the documentation using the elisp-repo-kit
+ commands:
+
+ #+findex: erk-export-contributing
+ - ~erk-export-contributing~
+ #+findex: erk-export-manual
+ - ~erk-export-manual~
+ #+findex: erk-export-readme
+ - ~erk-export-readme~
+ #+findex: erk-export-docs
+ - ~erk-export-docs~ is just a shortcut to just export all documents.
+
+ With a prefix argument, the export commands will also show the resulting
+ output.
+*** Finding and Editing
+ The inputs for exported documentation has shortcuts:
+ - ~erk-find-readme~
+ - ~erk-find-manual~
+ Using Org mode settings, these manuals will automatically trigger
+ re-generation when you save, helping you avoid shipping a stale or broken
+ manual.
+*** Previewing
+ Additionally, if you want to re-export and preview in one command, there are
+ shortcuts that export and then open the result, either in view mode for
+ markdown or info mode for the manual.
+
+ #+findex: erk-export-preview-manual
+ - ~erk-export-preview-manual~
+ This will export the manual.org to texi, process it to info, and finally
+ load the manual.info file.
+ #+findex: erk-export-preview-contributing
+ - ~erk-export-preview-contributing~
+ #+findex: erk-export-preview-readme
+ - ~erk-export-preview-readme~
+** Formatting
+#+cindex: document formatting
+ Texi supports a lot of features specific to automatic manual maintenance. Be
+ sure that your beautiful org document also generates a useful manual.
+*** Quoting symbols :item:
+ Symbols will \~display\~ `quoted' in the manual. Mentioning a symbol will
+ *not* place it in the manual's index.
+*** Elisp Source Blocks :item:
+ #+begin_src elisp
+ (let ((truth "Source blocks will render inside the manual like this"))
+ (message true))
+ #+end_src
+
+ You can use ~org-insert-structure-template~ etc to create these easily.
+*** Links :item:
+ Hyperlinks thankfully can be written like you expect, though many org
+ formats such as running elisp expressions through links may not work.
+
+ [[https://git.sr.ht/~ushin/hyperdrive.el/tree/master/item/doc/hyperdrive-manual.org][This link to the hyperdrive manual]] works like you expect.
+
+ The syntax is =[[http://somewhere.com][label for my link]]= if you are
+ unfamiliar.
+** Indices
+#+cindex: document indices
+ Texi has a lot of built-in support for indexes. Until we have GPT for your
+ manual, indexes are a good way to provide alternative views into your
+ manual, arranged by entities of similar type.
+
+ Have a look at the docs generation for org, magit, transient, and
+ hyperdrive for more extensive examples. Typically the are using a setup file
+ to declare export options.
+*** Creating Indices :item:
+ Texinfo includes six *predefined* index types:
+
+ - concept
+ - function
+ - variables
+ - keystroke
+ - program
+ - data type
+
+ You can also declare a new index with @defindex or @defcodeindex. The only
+ difference is that a code index will render entries in monospace, like
+ code.
+
+ #+begin_src org
+ #+TEXINFO_HEADER: @defindex foo
+ #+TEXINFO_HEADER: @defcodeindex foo
+ #+end_src
+
+ Creating entries with a custom index could be tricky. Good luck!
+
+*** Adding Entries :item:
+
+ Quoting a symbol will not result in an index entry. Which quoted symbol
+ would such an index point to? You have to manually create index entries.
+
+ To cause an index entry to be created and to link to a heading, add a
+ property within that heading. Adding to the predefined indexes:
+
+ - #+cindex: my-concept
+ - #+findex: my-function
+ - #+vindex: my-variable
+ - #+kindex: my-key
+ - #+pindex: my-program
+ - #+tindex: my-type
+
+ These will create index entries that can be used to navigate your manual by
+ listings of related entities.
+
+*** Render the Index :item:
+ Just use a regular header like so:
+
+ #+begin_src org
+ ,** Keystroke index
+ :PROPERTIES:
+ :INDEX: ky
+ :END:
+ #+end_src
+
+ The built-in index keys are =ky=, =fn=, =vr=, =cp=, =pg=, and =tp=.
+* Distributing Your Package
+** Setting Up Your Github Repository
+ You can copy this checklist to your org agenda files:
+
+ - [X] Create a repository (from [[*Install ERK][install]] instructions)
+ - [ ] Create an empty GitHub repository and check the git remote configuration
+ - [ ] Set up your git commit signing (and verification so that it's obvious)
+ *and* [[*Licensing, Developer Certificate of Origin][sign-off]] so that it will be hypothetically [[file:README.org::*Footnote on FSF and Emacs Core Licensing][straightforward]] for for FSF
+ to pull in your changes if they later change to DCO instead of copyright
+ assignment.
+ - [ ] Sign up for [[https://app.cachix.org/][cachix]] and, create a binary cache with API tokens and public
+ read access
+ #+cindex nix enabling cachix
+ #+cindex github adding secrets
+ - [ ] Add repository secrets necessary for your GitHub actions
+ ~CACHIX_AUTH_TOKEN~ and ~CACHIX_CACHE_NAME~ (settings -> secrets -> new
+ repository secret)
+ #+cindex github enabling actions
+ - [ ] Enable actions and add the following actions to your allowed actions list:
+
+ #+begin_src txt
+
+ actions/checkout@v3.2.0,
+ cachix/cachix-action@v12,
+ cachix/install-nix-action@v20,
+ actions/setup-python@v4,
+
+ #+end_src
+
+ *Note*, Python is used to run a DCO check script, nothing more.
+
+ - [ ] Get your package working, pushed, actions run, and CI badges all green
+ - [ ] [[*Publishing to MELPA][Publish]] to MELPA
+ - [ ] Make a post on [[https://reddit.com/r/emacs/][reddit]] and [[https://emacs.ch/][mastodon]] about your new package
+
+*** Optional Steps :item:
+#+cindex: security github actions
+ - [ ] Branch protect and enable check requirements for your default branch
+ (usually master). Merge commits, verified only, and no force push are
+ recommended settings.
+ - [ ] Enable requiring contributors to sign-off on web-based commits
+ - [ ] For *security* of your Cachix secrets and any other secrets you may someday
+ add, require Actions approval for all outside contributors and leave
+ repository permissions at read-only
+
+ Cachix is somewhat optional. It's free for open-source projects. It's
+ about as easy to sign up and generate the token as to remove the step from
+ the GitHub actions, so you won't save much time by avoiding it.
+
+ If you opt out of cachix or any other binary cache, you will definitely want
+ to turn off tests for ~emacsGit~ etc because the build times are about
+ 30min-1hr per run when a fresh Emacs must be built.
+
+** Customizing CI
+
+ The [[../.github/run-shim.el][run-shim.el]] script is just provides a CLI interface for adding commands in
+ the [[../.github/workflows/ci.yml][ci.yml]] CI declaration. Each action step just loads the shell, declared in
+ the [[../.github/flake.nix][flake.nix]] and then runs the shim in Emacs. The shim consumes the CLI
+ command arguments, so you can parameterize the invocations that way.
+
+ - If you need extra elisp dependencies during CI, add them to the ~epkgs~ list
+ in the flake.nix.
+ - If you need extra 3rd party dependencies, add them to ~packages~ in the call
+ to ~mkShell~.
+ - To invoke different elisp operations, add / modify the commands in
+ [[../.github/run-shim.el][run-shim.el]].
+
+ There's more information in [[../CONTRIBUTING.md][CONTRIBUTING]] about running commands locally. You
+ will want this information in your new repository.
+
+** Licensing, Developer Certificate of Origin
+ This template project is distributed with the MIT license. ~erk-new~ will also
+ run ~erk-rename-relicense~, which will automatically switch to the GPL3
+ license. *The MIT license allows re-licensing, and so this change is
+ compatible.* If you accept non-trivial changes to your project, it will be
+ very hard to change to the GPL3 later, so consider this choice.
+
+ The new repository will also come with DCO sign-off checking on PR's. The
+ instructions are in the [[../CONTRIBUTING.md][CONTRIBUTING]] guide. A DCO sign-off policy will give
+ your project a clear attestation of sufficient direct or transitive authority
+ from each contributor to submit changes under the terms of your project's
+ license. This can only improve your legal protection from incidentally
+ handling copyrighted code.
+
+ The DCO choice in this repository is also meant to encourage & push stodgy
+ organizations whose responsibility it was to invent better processes towards
+ lower friction paths to contribute code. If you fail to implement the DCO
+ sign-off scheme, there is less hope that the FSF will someday independently
+ merge changes that accumulate in your package because there will not be a
+ clear chain of license compliance.
+
+** Publishing to MELPA
+
+ If you have green CI, you have already passed many requirements of publishing a
+ MELPA package. *You still need to build your package and verify your recipe.*
+ You are going to clone melpa in order to make your PR. You can use the clone to
+ verify the recipe.
+
+*** Creating the recipe
+
+ Fork MELPA personally (not for organization) and clone it to wherever you keep
+ your upstreams. It's a good idea to separate upstreams from projects you
+ actively maintain so you can see and delete upstreams when not in use.
+
+ #+begin_src shell
+
+ mkdir -p upstream
+ cd upstream
+ git clone git@github.com:$GITHUB_USER/melpa.git # replace $GITHUB_USER
+
+ #+end_src
+
+ Install package-build
+
+ #+begin_src elisp
+ (use-package package-build)
+ #+end_src
+
+ ~package-build-create-recipe~ will give you something like:
+
+ #+begin_src elisp
+ (erk :fetcher github :repo "positron-solutions/elisp-repo-kit")
+ #+end_src
+
+ The following template can be filled in and pull-requested to MELPA to publish.
+ You don't need to touch ~:files~. The ~commit~ and ~branch~ are optional
+ depending on how you version / develop / tag your releases.
+
+ Copy the recipe into =recipes/erk= inside your MELPA clone.
+
+*** Testing package build
+
+ Inside the MELPA clone root:
+
+ #+begin_src shell
+
+ # Builds the package
+ make recipes/erk
+ # Test sandbox installation (will affect ~/.emacs.d/elpa So much for sandbox ¯\_(ツ)_/¯
+ EMACS_COMMAND=$(which emacs) make sandbox INSTALL=erk
+
+ #+end_src
+
+*** Testing stable package build
+
+ You need a tag on your default (usually master) branch of your repo,
+ =positron-solutions/elisp-repo-kit=. Use ~git tag -S v0.1.0~ and ~git push
+ origin v0.1.0~. You can also just create a release in the GitHub interface.
+
+ #+begin_src shell
+
+ # Test stable builds against your tags
+ STABLE=t make recipes/erk
+
+ #+end_src
+
+*** MELPA Lints
+
+ Lastly, install [[https://github.com/riscy/melpazoid][melpazoid]] and call =melpazoid= on your main feature. It does
+ some additional lints. You may need to install =package-lint= if you don't have
+ it. It's not declared in melpazoid's requirements. Getting the package in Nix
+ is not easy yet since melpazoid is not yet on Melpa.
+
+ #+begin_src elisp
+
+ ;; using elpaca's with explicit recipe
+ (use-package melapzoid
+ :elpaca (melpazoid :host github :repo "riscy/melpazoid"))
+
+ ;; using straight
+ (straight-use-package
+ '(melpazoid :type git :host github :repo "riscy/melpazoid" :files ("melpazoid/melpazoid.el")))
+
+ #+end_src
+
+ If everything works, you are ready to make a pull request to MELPA. Push your
+ changes and check all the boxes in the PR template except the one that requires
+ you to read the instructions.
+
+* Nix
+ By using Nix, your repository can declare a fixed set of dependencies for
+ development and testing. Not just Elisp dependencies, but also 3rd party
+ dependencies.
+
+** Maintaining versions
+#+cindex: nix dependency updating
+
+ The Nix [[../github/flake.nix][flake.nix]] is where versions are declared. The [[../.github/flake.lock][flake.lock]] stores a
+ fixed value for these declarations. These fixed versions need periodic
+ update. Nixpkgs has a new release about every six months. You can check
+ their [[https://github.com/NixOS/nixpkgs/branches][branches]] and [[https://github.com/NixOS/nixpkgs/tags][tags]] to see what's current. The effect is similar to
+ updating linux versions. The ~nix~ command has a lot of support for
+ specifying versions besides just updating.
+
+ #+begin_src shell
+ nix flake lock --update-input nixpkgs
+ #+end_src
+
+ The ~emacs-overlay~, which contains fixed versions of Emacs and snapshots of
+ Elisp repository package sets can be updated by running:
+
+ #+begin_src shell
+ nix flake lock --update-input emacs-overlay
+ #+end_src
+
+** Customizing Versions
+
+ #+cindex: nix custom Emacs versions
+ There are a lot of ways to declare specific versions of Emacs in Nix. You
+ can customize the build as much as you want if you go deep.
+
+ The ~emacs-overlay~ already contains many versions, which are updated over
+ time. You can view which attributes are available by inspecting the current
+ version of the flake in the ~nix repl~:
+
+ #+begin_src nix
+
+ # is known in your flake registry
+ pkgs = import { system = builtins.currentSystem; overlays = [ (builtins.getFlake ("emacs-overlay")).overlay ];}
+
+ # pkgs.emacs will tab complete
+ pkgs.version
+ # "28.2"
+ pkgs.emacsUnstable.version
+ # "29.1"
+
+ # Have fun inspecting the various versions. Checking their declarations in
+ # emacs-overlay source can be insightful.
+
+ #+end_src
+
+ To obtain truly specific Emacs versions, specify the Emacs source as a flake
+ input and then override the attributes of an Emacs package:
+
+ #+begin_src nix
+
+ inputs = {
+ # declare the exact source you want
+ emacs29-src = {
+ url = "github:emacs-mirror/emacs/emacs-29.1";
+ flake = false;
+ };
+ #... other inputs
+ };
+
+ # In your outputs, override one of the existing Emacs to make a new one:
+ emacs29 = pkgs.emacs.overrideAttrs (old: {
+ name = "emacs29";
+ version = emacs29-src.shortRev;
+ src = emacs29-src;
+ });
+ # It's nix expressions. It's programming.
+ # Ask your favorite large langauge model!
+
+ #+end_src
+
+ #+cindex: nix binary cache
+ #+cindex: security binary cache
+ Just keep in mind that highly specific versions also means that the first
+ CI run with those versions will not be cached. You can use Cachix or you own
+ binary cache to share builds among users. *Only trusted users should ever be
+ authorized to push to a binary cache.*
+
+ MacOS tends to get a little less test emphasis, and so
+ ~nixpkgs-darwin-~ branches exist and are required to pass more
+ Darwin tests before merging. This is more stable if you are on
+ MacOS.
+
+ ~nixpkgs-unstable~ or ~master~ are your other less common choices. Usually
+ when you need bleeding-edge or custom packages, instead of changing the whole
+ nixpkgs version, you override the specific packages by writing an overlay.
+ If you need help, file an issue and [[https://github.com/sponsors/positron-solutions][consider donating to maintenance]].
+
+** Reproducing Issues
+ #+cindex: nix handling version mismaches
+
+ Without Nix, users may have difficulty reproducing or describing exact
+ situations. This creates two issues:
+
+ - They can't tell you if the issue is caused by version mismatches
+ - They can't give you a method to reproduce their issue using versions that
+ would allow you to confirm a fix
+
+ By changing the versions within the flake to match the versions in question
+ that are breaking, the user can try versions to confirm a version mismatch and
+ then give you their flake so that you can reproduce and confirm a fix.
+
+* Indices
+** Command and Function index
+ :PROPERTIES:
+ :INDEX: fn
+ :END:
+
+** Concept index
+ :PROPERTIES:
+ :INDEX: cp
+ :END:
+
+* Licensing
+:PROPERTIES:
+:COPYING: t
+:END:
+
+#+include: "../COPYING"
+
+# Local Variables:
+# after-save-hook: (erk-export-docs)
+# End:
diff --git a/docs/manual.texi b/docs/manual.texi
new file mode 100644
index 0000000..f91193d
--- /dev/null
+++ b/docs/manual.texi
@@ -0,0 +1,1160 @@
+\input texinfo @c -*- texinfo -*-
+@c %**start of header
+@setfilename manual.info
+@settitle Elisp Repo Kit
+@documentencoding UTF-8
+@documentlanguage en
+@comment !!!THIS FILE HAS BEEN GENERATED!!! Edit manual.org instead!
+@c %**end of header
+
+@copying
+Copyright (C) 2022 Positron Solutions
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the ``Software''), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT@. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE@.
+@end copying
+
+@dircategory Emacs
+@direntry
+* Elisp Repo Kit: (erk). Create, distribute, and maintain Emacs Lisp packages.
+@end direntry
+
+@finalout
+@titlepage
+@title Elisp Repo Kit
+@subtitle for version 0.2.0
+@author Positron Solutions
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@contents
+
+@ifnottex
+@node Top
+@top Elisp Repo Kit
+
+Setting up a @emph{complete} Emacs Lisp package doesn't need to be a lot of work.
+Elisp Repo Kit provides a convenient starting point for collaborating on a
+public Elisp package repository:
+
+@itemize
+@item
+An Elisp package
+@item
+Tests
+@item
+CI & dependency management
+@item
+README and manual
+@item
+Licensing
+@end itemize
+
+Furthermore, to get rid of pitfalls and streamline productive workflows when
+working with Elisp packages, Elisp Repo Kit provides shortcuts:
+
+@itemize
+@item
+Loading and unloading modules
+@item
+Compiling
+@item
+Running tests
+@item
+Re-generating documentation
+@item
+Navigating the project
+@end itemize
+@end ifnottex
+
+@menu
+* High Level Overview::
+* Install ERK::
+* Creating Packages::
+* Using ERK for development::
+* Documenting Your Package::
+* Distributing Your Package::
+* Nix::
+* Indices: Indices (1).
+
+@detailmenu
+--- The Detailed Node Listing ---
+
+High Level Overview
+
+* File contents and structure::
+* Developing::
+* Documenting::
+* Distributing::
+
+Install ERK
+
+* Manual cloning::
+* Manually add just CI::
+
+Using ERK for development
+
+* Find Files::
+
+Documenting Your Package
+
+* What makes a good manual::
+* Re-Generating::
+* Formatting::
+* Indices::
+
+What makes a good manual
+
+* Generative AI and manuals::
+* Automatic indexing::
+
+Re-Generating
+
+* Finding and Editing::
+* Previewing::
+
+Formatting
+
+* Quoting symbols::
+* Elisp Source Blocks::
+* Links::
+
+Indices
+
+* Creating Indices::
+* Adding Entries::
+* Render the Index::
+
+Distributing Your Package
+
+* Setting Up Your Github Repository::
+* Customizing CI::
+* Licensing, Developer Certificate of Origin: Licensing Developer Certificate of Origin.
+* Publishing to MELPA::
+
+Setting Up Your Github Repository
+
+* Optional Steps::
+
+Publishing to MELPA
+
+* Creating the recipe::
+* Testing package build::
+* Testing stable package build::
+* MELPA Lints::
+
+Nix
+
+* Maintaining versions::
+* Customizing Versions::
+* Reproducing Issues::
+
+Indices
+
+* Command and Function index::
+* Concept index::
+
+@end detailmenu
+@end menu
+
+@node High Level Overview
+@chapter High Level Overview
+
+@itemize
+@item
+As a repository, Elisp Repo Kit is a template for how to organize and
+distribute your project.
+
+@item
+As an Elisp package, Elisp Repo Kit (erk) provides shortcuts for working on
+package using the Elisp Repo Kit organization structure (as well as other
+Elisp packages).
+@end itemize
+
+@menu
+* File contents and structure::
+* Developing::
+* Documenting::
+* Distributing::
+@end menu
+
+@node File contents and structure
+@section File contents and structure
+
+@cindex project layout
+
+@emph{After cloning and renaming,} you will have a file tree like this:
+
+@example
+
+├── .gitignore # ignores for byte compiles, autoloads etc
+│
+├── README.md # this file
+├── CONTRIBUTING.md # typical instructions for development
+├── COPYING # a GPL3 license
+├── DCO # Developer Certificate of Origin
+│
+├── .github
+│ ├── .envrc # direnv integration with `nix develop`
+│ ├── flake.nix # dependencies for this project
+│ ├── flake.lock # version controlled lock of flake.nix input versions
+│ ├── run-shim.el # elisp script with test & lint routines
+│ ├── pull_request_template.md # reminders for PR contributors
+│ └── workflows
+│ ├── ci.yml # workflow for lints and tests
+│ └── dco.yml # workflow to check DCO sign-offs
+│
+├── docs
+│ ├── README.org # generates README.md
+│ ├── CONTRIBUTING.org # generates CONTRIBUTING.md
+│ ├── manual.org # actual manual
+│ └── manual.texi # generated manual for distribution
+│
+├── lisp
+│ └── erk.el # the package
+│
+└── test
+ └── erk-test.el # ERT unit tests for the package
+
+@end example
+
+You can use either a multi-file or flat layout for lisp. Just name test files
+@code{something-test.el} and keep all lisp files in root, @code{/lisp} or @code{/test}
+directories.
+
+@node Developing
+@section Developing
+
+@itemize
+@item
+The package is stored in /lisp and its tests in /test.
+@item
+Many shortcuts are provided to run tests or rebuild and reload the package
+or to visit the unit tests for a function under point etc.
+@item
+Most of the Elisp shortcuts lean on Emacs settings or packages such as
+@code{auto-compile} and @code{ert}.
+@end itemize
+
+@node Documenting
+@section Documenting
+
+@itemize
+@item
+The document inputs are stored in /docs.
+@item
+They are @strong{written} in org format
+@item
+The README for the Github home page is @strong{exported} to markdown
+@item
+The Manual, which can be used to supplement the README, is itself
+@strong{exported} to texi which is converted to info for viewing within Emacs
+@item
+The CONTRIBUTING guide is @strong{exported} to markdown
+@end itemize
+
+@node Distributing
+@section Distributing
+
+@itemize
+@item
+The repository is designed to be hosted on Github
+@item
+All CI files are stored under @uref{../.github/, ./github}. (You can include this directory
+with minor modifications into other Elisp projects.)
+@item
+Github actions are included for CI@.
+@item
+Dependencies for CI are obtained via Nix.
+@item
+You are free to submit your package for distribution on MELPA etc. This
+package is made available on MELPA partly to maintain the structure and
+workflows for doing so.
+@end itemize
+
+@node Install ERK
+@chapter Install ERK
+
+@lisp
+
+(use-package erk) ; vanilla
+
+;; using elpaca's with explicit recipe
+(use-package erk
+ :elpaca (erk :host github :repo "positron-solutions/elisp-repo-kit"))
+
+;; straight with explicit recipe
+(use-package erk
+ :straight (erk :type git :host github :repo "positron-solutions/elisp-repo-kit"))
+
+;; or use melpa, manual load-path & require, you brave yak shaver
+
+@end lisp
+
+@menu
+* Manual cloning::
+* Manually add just CI::
+@end menu
+
+@node Manual cloning
+@section Manual cloning
+
+@findex erk-clone
+The standalone command, @code{erk-clone} will clone without renaming.
+
+This repo is also a @uref{https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template, template repository}, so you can fork without forking
+(Bruce Lee).
+
+@findex erk-rename
+If you create via template or clone manually, it's presumed you know what
+you're doing at that point. Call @code{erk-rename} on its own to rename
+in these cases.
+
+There are some customize options that cause the renaming to be transitively
+consistent.
+
+@node Manually add just CI
+@section Manually add just CI
+
+Copy the .github folder and the contributing guide to your package. Set up
+your secrets for Cachix. Read the CI customization section.
+
+@node Creating Packages
+@chapter Creating Packages
+
+@findex erk-new
+The simplest and intended way is to call @code{erk-new}. It will first
+ask you for:
+
+@itemize
+@item
+Root directory you want to clone to
+@item
+Package name
+@item
+Package prefix
+@item
+Author name
+@item
+GitHub user or organization
+@item
+Email address
+@end itemize
+
+@findex erk-rename-relicense
+@code{erk-new} also calls @code{erk-rename-relicense} to rename all of the files, string
+replace names, and re-license to GPL3. It also changes the author and resets
+the git history. Now just follow the steps in Have fun!
+
+@node Using ERK for development
+@chapter Using ERK for development
+
+Elisp repo kit contains some convenience functions to reload your package and
+to discover and run ert tests. These shortcuts just make common cases faster.
+@itemize
+@item
+Loading and re-loading your package
+@findex erk-reload-project-package
+@code{erk-reload-project-package} will unload and recompile your package if
+necessary and then reload it.
+
+@findex erk-reload-project-tests
+@code{erk-reload-project-tests} is the complementary command for reloading tests.
+@end itemize
+@itemize
+@item
+Run tests
+@findex erk-ert-project~
+@code{erk-ert-project} will discover, rebuild & reload if necessary, and run
+tests. There are a few other commands to augment the @uref{https://www.gnu.org/software/emacs/manual/html_node/ert/, ert} package.
+
+@item
+Duplicating CI Locally
+The CI configuration is all stored in @uref{../.github/, .github}. Usually you will want
+development instructions in your new repository. The @uref{./CONTRIBUTING.org, CONTRIBUTING} guide
+contains instructions to reproduce the CI behavior.
+@end itemize
+
+@menu
+* Find Files::
+@end menu
+
+@node Find Files
+@section Find Files
+
+Accidentally editing generated files or forgetting the path to a file is
+annoying. ERK provides a helper to find files based on their purpose.
+
+@findex erk-find
+@code{erk-find} will ask you to pick the file based on what it does. It's
+choices:
+
+@itemize
+@item
+ci-dco
+@item
+ci-nix-flake
+@item
+ci-run-shim
+@item
+ci-tests
+@item
+docs-contributing
+@item
+docs-manual
+@item
+docs-readme
+@end itemize
+
+Generated files or extremely common files are not included. For each one of
+these choices, there is a corresponding command:
+
+@findex erk-find-ci-dco
+@itemize
+@item
+@code{erk-find-ci-dco}
+@end itemize
+@findex erk-find-ci-nix-flake
+@itemize
+@item
+@code{erk-find-ci-nix-flake}
+@end itemize
+@findex erk-find-ci-run-shim
+@itemize
+@item
+@code{erk-find-ci-run-shim}
+@end itemize
+@findex erk-find-ci-test
+@itemize
+@item
+@code{erk-find-ci-test}
+@end itemize
+@findex erk-find-docs-contributing
+@itemize
+@item
+@code{erk-find-docs-contributing}
+@end itemize
+@findex erk-find-docs-manual
+@itemize
+@item
+@code{erk-find-find-docs-manual}
+@end itemize
+@findex erk-find-docs-readme
+@itemize
+@item
+@code{erk-find-docs-readme}
+@end itemize
+
+@node Documenting Your Package
+@chapter Documenting Your Package
+
+@cindex document re-structuring
+@cindex document export
+How this manual is created and maintained. Elisp Repo Kit's manual scheme
+overview:
+@itemize
+@item
+Contents for the README and built-in manual are mostly stored in
+@uref{./manual.org, /docs/manual.org}
+@item
+Each document stitches together the contents of @uref{./manual.org, /docs/manual.org} using
+@samp{#+include:} directives. Some of the header, footer, and export information
+just controls formatting.
+@item
+The @uref{../README.md, README.md} for your repository's home page is generated from @uref{./README.org, /docs/README.org}
+@item
+The @uref{./manual.texi} is generated from @uref{./manual.org, /docs/manual.org}
+@item
+Re-generation-on-save is automatically configured at the end of each document
+@item
+The .gitignore will ignore any intermediate outputs, so there's no need to
+store them in /tmp or clean them
+@end itemize
+
+@menu
+* What makes a good manual::
+* Re-Generating::
+* Formatting::
+* Indices::
+@end menu
+
+@node What makes a good manual
+@section What makes a good manual
+
+@cindex what makes a good manual
+Manuals can do four things that code and code-based automatic indices are
+fundamentally terrible at:
+
+@itemize
+@item
+Describe ideas at higher levels of abstraction, concepts which may have no
+correct docstring to live in. This includes providing several levels of
+abstraction or abstraction from different perspectives.
+@item
+Describe behavior or state models in implementations or external systems,
+things that aren't even apparent from reading the code. Think
+microprocessor behavior, 3rd party API behavior, or a code convention
+implemented in multiple functions
+@item
+Examples that distill and illustrate ideas in isolation instead of how they
+are naturally composed and become complex when applied in practice.
+@item
+Illuminate workflows and paths of understanding that do not follow the
+linear ordering of code or any natural automatic index.
+
+In short, a good manual ties together the very large or uncovers what is
+opaque. Neither of these types of information have a 1:1 correspondence to
+the definitions in your code.
+
+From this lack of correspondence, we can also conclude that good manuals are
+in fact @strong{not exhaustive}. Exhaustive manuals are merely @strong{exhausting},
+requiring tremendous maintenance to do what is already available through
+automation or even just reading the code.
+@end itemize
+
+@menu
+* Generative AI and manuals::
+* Automatic indexing::
+@end menu
+
+@node Generative AI and manuals
+@subsection Generative AI and manuals
+
+One thing manuals had been good at was linking to concepts based on
+conceptual relationship. While semantic search queries have been around for
+a while, large language models have transformed the process, providing the
+semantic output to the semantic search. As semantic search and semantic synthesis of
+output become more accessible, it's becoming less important to conceptually
+relating information to bridge the limitations of more exact types of search.
+
+Increasingly, machine learning is becoming able to synthesize information
+from numerous sources and present it via @strong{natural language queryable
+indices}. Keep in mind, when writing a manual, if the information you are
+providing doesn't add information that is easily decideable from the other
+information already available about your package, your manual is likely to
+become increasingly redundant information.
+
+@node Automatic indexing
+@subsection Automatic indexing
+
+Your package's code also already has a ton of automatic indexing via Emacs
+discovery:
+
+@itemize
+@item
+@code{describe-function} etc
+@item
+completions for functions, variables, commands, macros etc
+@item
+signature hints from eldoc
+@item
+searching within the code
+@item
+symbol-based navigation within the code
+@end itemize
+
+Documenting full enumerations of things in the same order that they live in
+code or in the same order as automatic indexing commonly produces throughout
+normal development is rarely useful. This information @strong{does} have a natural
+1:1 correspondence to readily available information, and is therefore likely
+redundant. If you wind up with a manual like this, it would be better to
+leave the information in the code and generate the manual from the docstrings.
+
+@node Re-Generating
+@section Re-Generating
+
+Re-generation is configured to occur on save at the end of each document.
+You can manually re-generate the documentation using the elisp-repo-kit
+commands:
+
+@findex erk-export-contributing
+@itemize
+@item
+@code{erk-export-contributing}
+@end itemize
+@findex erk-export-manual
+@itemize
+@item
+@code{erk-export-manual}
+@end itemize
+@findex erk-export-readme
+@itemize
+@item
+@code{erk-export-readme}
+@end itemize
+@findex erk-export-docs
+@itemize
+@item
+@code{erk-export-docs} is just a shortcut to just export all documents.
+@end itemize
+
+@menu
+* Finding and Editing::
+* Previewing::
+@end menu
+
+@node Finding and Editing
+@subsection Finding and Editing
+
+The inputs for exported documentation has shortcuts:
+@itemize
+@item
+@code{erk-find-readme}
+@item
+@code{erk-find-manual}
+@end itemize
+Using Org mode settings, these manuals will automatically trigger
+re-generation when you save, helping you avoid shipping a stale or broken
+manual.
+
+@node Previewing
+@subsection Previewing
+
+Additionally, if you want to re-export and preview in one command, there are
+shortcuts that export and then open the result, either in view mode for
+markdown or info mode for the manual.
+
+@findex erk-export-preview-manual
+@itemize
+@item
+@code{erk-export-preview-manual}
+This will export the manual.org to texi, process it to info, and finally
+load the manual.info file.
+@end itemize
+@findex erk-export-preview-contributing
+@itemize
+@item
+@code{erk-export-preview-contributing}
+@end itemize
+@findex erk-export-preview-readme
+@itemize
+@item
+@code{erk-export-preview-readme}
+@end itemize
+
+@node Formatting
+@section Formatting
+
+@cindex document formatting
+Texi supports a lot of features specific to automatic manual maintenance. Be
+sure that your beautiful org document also generates a useful manual.
+
+@menu
+* Quoting symbols::
+* Elisp Source Blocks::
+* Links::
+@end menu
+
+@node Quoting symbols
+@subsection Quoting symbols :item:
+
+Symbols will \~display\~ `quoted' in the manual. Mentioning a symbol will
+@strong{not} place it in the manual's index.
+
+@node Elisp Source Blocks
+@subsection Elisp Source Blocks :item:
+
+@lisp
+(let ((truth "Source blocks will render inside the manual like this"))
+ (message true))
+@end lisp
+
+You can use @code{org-insert-structure-template} etc to create these easily.
+
+@node Links
+@subsection Links :item:
+
+Hyperlinks thankfully can be written like you expect, though many org
+formats such as running elisp expressions through links may not work.
+
+@uref{https://git.sr.ht/~ushin/hyperdrive.el/tree/master/item/doc/hyperdrive-manual.org, This link to the hyperdrive manual} works like you expect.
+
+The syntax is @samp{[[http://somewhere.com][label for my link]]} if you are
+unfamiliar.
+
+@node Indices
+@section Indices
+
+@cindex document indices
+Texi has a lot of built-in support for indexes. Until we have GPT for your
+manual, indexes are a good way to provide alternative views into your
+manual, arranged by entities of similar type.
+
+Have a look at the docs generation for org, magit, transient, and
+hyperdrive for more extensive examples. Typically the are using a setup file
+to declare export options.
+
+@menu
+* Creating Indices::
+* Adding Entries::
+* Render the Index::
+@end menu
+
+@node Creating Indices
+@subsection Creating Indices :item:
+
+Texinfo includes six @strong{predefined} index types:
+
+@itemize
+@item
+concept
+@item
+function
+@item
+variables
+@item
+keystroke
+@item
+program
+@item
+data type
+@end itemize
+
+You can also declare a new index with @@defindex or @@defcodeindex. The only
+difference is that a code index will render entries in monospace, like
+code.
+
+@example
+#+TEXINFO_HEADER: @@defindex foo
+#+TEXINFO_HEADER: @@defcodeindex foo
+@end example
+
+Creating entries with a custom index could be tricky. Good luck!
+
+@node Adding Entries
+@subsection Adding Entries :item:
+
+Quoting a symbol will not result in an index entry. Which quoted symbol
+would such an index point to? You have to manually create index entries.
+
+To cause an index entry to be created and to link to a heading, add a
+property within that heading. Adding to the predefined indexes:
+
+@itemize
+@item
+#+cindex: my-concept
+@item
+#+findex: my-function
+@item
+#+vindex: my-variable
+@item
+#+kindex: my-key
+@item
+#+pindex: my-program
+@item
+#+tindex: my-type
+@end itemize
+
+These will create index entries that can be used to navigate your manual by
+listings of related entities.
+
+@node Render the Index
+@subsection Render the Index :item:
+
+Just use a regular header like so:
+
+@example
+** Keystroke index
+:PROPERTIES:
+:INDEX: ky
+:END:
+@end example
+
+The built-in index keys are @samp{ky}, @samp{fn}, @samp{vr}, @samp{cp}, @samp{pg}, and @samp{tp}.
+
+@node Distributing Your Package
+@chapter Distributing Your Package
+
+@menu
+* Setting Up Your Github Repository::
+* Customizing CI::
+* Licensing, Developer Certificate of Origin: Licensing Developer Certificate of Origin.
+* Publishing to MELPA::
+@end menu
+
+@node Setting Up Your Github Repository
+@section Setting Up Your Github Repository
+
+You can copy this checklist to your org agenda files:
+
+@itemize
+@item
+Create a repository (from @ref{Install ERK, , install} instructions)
+@item
+Create an empty GitHub repository and check the git remote configuration
+@item
+Set up your git commit signing (and verification so that it's obvious)
+@strong{and} @ref{Licensing Developer Certificate of Origin, , sign-off} so that it will be hypothetically @uref{README.org, straightforward} for for FSF
+to pull in your changes if they later change to DCO instead of copyright
+assignment.
+@item
+Sign up for @uref{https://app.cachix.org/, cachix} and, create a binary cache with API tokens and public
+read access
+@end itemize
+#+cindex nix enabling cachix
+#+cindex github adding secrets
+@itemize
+@item
+Add repository secrets necessary for your GitHub actions
+@code{CACHIX_AUTH_TOKEN} and @code{CACHIX_CACHE_NAME} (settings -> secrets -> new
+repository secret)
+@end itemize
+#+cindex github enabling actions
+@itemize
+@item
+Enable actions and add the following actions to your allowed actions list:
+
+@example
+
+actions/checkout@@v3.2.0,
+cachix/cachix-action@@v12,
+cachix/install-nix-action@@v20,
+actions/setup-python@@v4,
+
+@end example
+
+@strong{Note}, Python is used to run a DCO check script, nothing more.
+
+@item
+Get your package working, pushed, actions run, and CI badges all green
+@item
+@ref{Publishing to MELPA, , Publish} to MELPA
+@item
+Make a post on @uref{https://reddit.com/r/emacs/, reddit} and @uref{https://emacs.ch/, mastodon} about your new package
+@end itemize
+
+@menu
+* Optional Steps::
+@end menu
+
+@node Optional Steps
+@subsection Optional Steps :item:
+
+@cindex security github actions
+@itemize
+@item
+Branch protect and enable check requirements for your default branch
+(usually master). Merge commits, verified only, and no force push are
+recommended settings.
+@item
+Enable requiring contributors to sign-off on web-based commits
+@item
+For @strong{security} of your Cachix secrets and any other secrets you may someday
+add, require Actions approval for all outside contributors and leave
+repository permissions at read-only
+@end itemize
+
+Cachix is somewhat optional. It's free for open-source projects. It's
+about as easy to sign up and generate the token as to remove the step from
+the GitHub actions, so you won't save much time by avoiding it.
+
+If you opt out of cachix or any other binary cache, you will definitely want
+to turn off tests for @code{emacsGit} etc because the build times are about
+30min-1hr per run when a fresh Emacs must be built.
+
+@node Customizing CI
+@section Customizing CI
+
+The @uref{../.github/run-shim.el, run-shim.el} script is just provides a CLI interface for adding commands in
+the @uref{../.github/workflows/ci.yml, ci.yml} CI declaration. Each action step just loads the shell, declared in
+the @uref{../.github/flake.nix, flake.nix} and then runs the shim in Emacs. The shim consumes the CLI
+command arguments, so you can parameterize the invocations that way.
+
+@itemize
+@item
+If you need extra elisp dependencies during CI, add them to the @code{epkgs} list
+in the flake.nix.
+@item
+If you need extra 3rd party dependencies, add them to @code{packages} in the call
+to @code{mkShell}.
+@item
+To invoke different elisp operations, add / modify the commands in
+@uref{../.github/run-shim.el, run-shim.el}.
+@end itemize
+
+There's more information in @uref{../CONTRIBUTING.md, CONTRIBUTING} about running commands locally. You
+will want this information in your new repository.
+
+@node Licensing Developer Certificate of Origin
+@section Licensing, Developer Certificate of Origin
+
+This template project is distributed with the MIT license. @code{erk-new} will also
+run @code{erk-rename-relicense}, which will automatically switch to the GPL3
+license. @strong{The MIT license allows re-licensing, and so this change is
+compatible.} If you accept non-trivial changes to your project, it will be
+very hard to change to the GPL3 later, so consider this choice.
+
+The new repository will also come with DCO sign-off checking on PR's. The
+instructions are in the @uref{../CONTRIBUTING.md, CONTRIBUTING} guide. A DCO sign-off policy will give
+your project a clear attestation of sufficient direct or transitive authority
+from each contributor to submit changes under the terms of your project's
+license. This can only improve your legal protection from incidentally
+handling copyrighted code.
+
+The DCO choice in this repository is also meant to encourage & push stodgy
+organizations whose responsibility it was to invent better processes towards
+lower friction paths to contribute code. If you fail to implement the DCO
+sign-off scheme, there is less hope that the FSF will someday independently
+merge changes that accumulate in your package because there will not be a
+clear chain of license compliance.
+
+@node Publishing to MELPA
+@section Publishing to MELPA
+
+If you have green CI, you have already passed many requirements of publishing a
+MELPA package. @strong{You still need to build your package and verify your recipe.}
+You are going to clone melpa in order to make your PR@. You can use the clone to
+verify the recipe.
+
+@menu
+* Creating the recipe::
+* Testing package build::
+* Testing stable package build::
+* MELPA Lints::
+@end menu
+
+@node Creating the recipe
+@subsection Creating the recipe
+
+Fork MELPA personally (not for organization) and clone it to wherever you keep
+your upstreams. It's a good idea to separate upstreams from projects you
+actively maintain so you can see and delete upstreams when not in use.
+
+@example
+
+mkdir -p upstream
+cd upstream
+git clone git@@github.com:$GITHUB_USER/melpa.git # replace $GITHUB_USER
+
+@end example
+
+Install package-build
+
+@lisp
+(use-package package-build)
+@end lisp
+
+@code{package-build-create-recipe} will give you something like:
+
+@lisp
+(erk :fetcher github :repo "positron-solutions/elisp-repo-kit")
+@end lisp
+
+The following template can be filled in and pull-requested to MELPA to publish.
+You don't need to touch @code{:files}. The @code{commit} and @code{branch} are optional
+depending on how you version / develop / tag your releases.
+
+Copy the recipe into @samp{recipes/erk} inside your MELPA clone.
+
+@node Testing package build
+@subsection Testing package build
+
+Inside the MELPA clone root:
+
+@example
+
+# Builds the package
+make recipes/erk
+# Test sandbox installation (will affect ~/.emacs.d/elpa So much for sandbox ¯\_(ツ)_/¯
+EMACS_COMMAND=$(which emacs) make sandbox INSTALL=erk
+
+@end example
+
+@node Testing stable package build
+@subsection Testing stable package build
+
+You need a tag on your default (usually master) branch of your repo,
+@samp{positron-solutions/elisp-repo-kit}. Use @code{git tag -S v0.1.0} and @code{git push
+ origin v0.1.0}. You can also just create a release in the GitHub interface.
+
+@example
+
+# Test stable builds against your tags
+STABLE=t make recipes/erk
+
+@end example
+
+@node MELPA Lints
+@subsection MELPA Lints
+
+Lastly, install @uref{https://github.com/riscy/melpazoid, melpazoid} and call @samp{melpazoid} on your main feature. It does
+some additional lints. You may need to install @samp{package-lint} if you don't have
+it. It's not declared in melpazoid's requirements. Getting the package in Nix
+is not easy yet since melpazoid is not yet on Melpa.
+
+@lisp
+
+;; using elpaca's with explicit recipe
+(use-package melapzoid
+ :elpaca (melpazoid :host github :repo "riscy/melpazoid"))
+
+;; using straight
+(straight-use-package
+ '(melpazoid :type git :host github :repo "riscy/melpazoid" :files ("melpazoid/melpazoid.el")))
+
+@end lisp
+
+If everything works, you are ready to make a pull request to MELPA@. Push your
+changes and check all the boxes in the PR template except the one that requires
+you to read the instructions.
+
+@node Nix
+@chapter Nix
+
+By using Nix, your repository can declare a fixed set of dependencies for
+development and testing. Not just Elisp dependencies, but also 3rd party
+dependencies.
+
+@menu
+* Maintaining versions::
+* Customizing Versions::
+* Reproducing Issues::
+@end menu
+
+@node Maintaining versions
+@section Maintaining versions
+
+@cindex nix dependency updating
+
+The Nix @uref{../github/flake.nix, flake.nix} is where versions are declared. The @uref{../.github/flake.lock, flake.lock} stores a
+fixed value for these declarations. These fixed versions need periodic
+update. Nixpkgs has a new release about every six months. You can check
+their @uref{https://github.com/NixOS/nixpkgs/branches, branches} and @uref{https://github.com/NixOS/nixpkgs/tags, tags} to see what's current. The effect is similar to
+updating linux versions. The @code{nix} command has a lot of support for
+specifying versions besides just updating.
+
+@example
+nix flake lock --update-input nixpkgs
+@end example
+
+The @code{emacs-overlay}, which contains fixed versions of Emacs and snapshots of
+Elisp repository package sets can be updated by running:
+
+@example
+nix flake lock --update-input emacs-overlay
+@end example
+
+@node Customizing Versions
+@section Customizing Versions
+
+@cindex nix custom Emacs versions
+There are a lot of ways to declare specific versions of Emacs in Nix. You
+can customize the build as much as you want if you go deep.
+
+The @code{emacs-overlay} already contains many versions, which are updated over
+time. You can view which attributes are available by inspecting the current
+version of the flake in the @code{nix repl}:
+
+@example
+
+# is known in your flake registry
+pkgs = import @{ system = builtins.currentSystem; overlays = [ (builtins.getFlake ("emacs-overlay")).overlay ];@}
+
+# pkgs.emacs will tab complete
+pkgs.version
+# "28.2"
+pkgs.emacsUnstable.version
+# "29.1"
+
+# Have fun inspecting the various versions. Checking their declarations in
+# emacs-overlay source can be insightful.
+
+@end example
+
+To obtain truly specific Emacs versions, specify the Emacs source as a flake
+input and then override the attributes of an Emacs package:
+
+@example
+
+inputs = @{
+ # declare the exact source you want
+ emacs29-src = @{
+ url = "github:emacs-mirror/emacs/emacs-29.1";
+ flake = false;
+ @};
+ #... other inputs
+@};
+
+# In your outputs, override one of the existing Emacs to make a new one:
+emacs29 = pkgs.emacs.overrideAttrs (old: @{
+ name = "emacs29";
+ version = emacs29-src.shortRev;
+ src = emacs29-src;
+@});
+# It's nix expressions. It's programming.
+# Ask your favorite large langauge model!
+
+@end example
+
+@cindex nix binary cache
+@cindex security binary cache
+Just keep in mind that highly specific versions also means that the first
+CI run with those versions will not be cached. You can use Cachix or you own
+binary cache to share builds among users. @strong{Only trusted users should ever be
+authorized to push to a binary cache.}
+
+MacOS tends to get a little less test emphasis, and so
+@code{nixpkgs-darwin-} branches exist and are required to pass more
+Darwin tests before merging. This is more stable if you are on
+MacOS@.
+
+@code{nixpkgs-unstable} or @code{master} are your other less common choices. Usually
+when you need bleeding-edge or custom packages, instead of changing the whole
+nixpkgs version, you override the specific packages by writing an overlay.
+If you need help, file an issue and @uref{https://github.com/sponsors/positron-solutions, consider donating to maintenance}.
+
+@node Reproducing Issues
+@section Reproducing Issues
+
+@cindex nix handling version mismaches
+
+Without Nix, users may have difficulty reproducing or describing exact
+situations. This creates two issues:
+
+@itemize
+@item
+They can't tell you if the issue is caused by version mismatches
+@item
+They can't give you a method to reproduce their issue using versions that
+would allow you to confirm a fix
+@end itemize
+
+By changing the versions within the flake to match the versions in question
+that are breaking, the user can try versions to confirm a version mismatch and
+then give you their flake so that you can reproduce and confirm a fix.
+
+@node Indices (1)
+@chapter Indices
+
+@menu
+* Command and Function index::
+* Concept index::
+@end menu
+
+@node Command and Function index
+@section Command and Function index
+
+@printindex fn
+
+@node Concept index
+@section Concept index
+
+@printindex cp
+
+@bye
\ No newline at end of file
diff --git a/lisp/erk.el b/lisp/erk.el
index 9f008d3..2576ebe 100644
--- a/lisp/erk.el
+++ b/lisp/erk.el
@@ -1,9 +1,9 @@
;;; erk.el --- Elisp (GitHub) Repository Kit -*- lexical-binding: t; -*-
-;; Copyright (C) 2022 Positron Solutions
+;; Copyright (C) 2023 Positron Solutions
-;; Author:
-;; Keywords: convenience
+;; Author: Positron Solutions
+;; Keywords: convenience, programming
;; Version: 0.2.0
;; Package-Requires: ((emacs "28.1") (auto-compile "1.2.0") (dash "2.18.0"))
;; Homepage: http://github.com/positron-solutions/elisp-repo-kit
@@ -48,30 +48,43 @@
;;; Code:
;; see flake.nix for providing dependencies for CI and local development.
-(require 'project)
(require 'auto-compile)
(require 'dash)
(require 'ert)
+(require 'finder)
+(require 'lisp-mnt)
+(require 'project)
(require 'vc)
+(require 'org)
+(require 'info)
(eval-when-compile (require 'subr-x))
-(defgroup erk nil "Elisp repository kit." :prefix 'erk :group 'erk)
+(defgroup erk nil "Elisp repository kit." :prefix 'erk :group 'programming)
-(defcustom erk-github-package-name "elisp-repo-kit"
- "Default GitHub for cloning templates.
+(defcustom erk-replace-author
+ (let ((first-author (car (lm-authors (or load-file-name buffer-file-name)))))
+ (format "%s <%s>" (car first-author) (cdr first-author)))
+ "Default author for renaming."
+ :group 'erk
+ :type 'string)
+
+(defcustom erk-replace-github-package-name "elisp-repo-kit"
+ "Default GitHub project for renaming.
If you rename this repository after forking, you need to set this
to clone from within the fork."
:group 'erk
:type 'string)
-(defcustom erk-package-prefix "erk"
+(defcustom erk-replace-package-prefix
+ (lm-with-file (or load-file-name buffer-file-name)
+ (lm-get-package-name))
"The prefix is used to features and file names."
:group 'erk
:type 'string)
-(defcustom erk-github-userorg "positron-solutions"
- "Default GitHub for cloning templates.
+(defcustom erk-replace-github-userorg "positron-solutions"
+ "Default GitHub user-or-org for renaming.
If you fork this repository, you need to set this to clone it
from within the fork."
:group 'erk
@@ -98,8 +111,8 @@ you can redistribute it and/or modify
"List of (directory file replacement-file) forms.")
(defconst erk--files-with-strings
- '("README.org"
- "CONTRIBUTING.org"
+ '("docs/manual.org"
+ "docs/README.org"
"lisp/erk.el"
"test/erk-test.el"
".github/run-shim.el"))
@@ -156,12 +169,48 @@ This assumes the convention of one elisp file per feature and
feature name derived file name"
(erk--dir-features (concat (erk--project-root) "lisp" )))
+(defun erk--package-root-feature ()
+ "Return the shortest feature in the package root."
+ (car (sort (erk--package-features)
+ (lambda (l r)
+ (< (length (symbol-name l))
+ (length (symbol-name r)))))))
+
(defun erk--test-features ()
"List the features defined in project's test packages.
This assumes the convention of one elisp file per feature and
feature name derived file name"
(erk--dir-features (concat (erk--project-root) "test" )))
+(defun erk--project-elisp-dir ()
+ "Return the location of elisp files.
+Only understands project root or root/lisp."
+ (let* ((project-root (erk--project-root))
+ (lisp-subdir (concat project-root "lisp")))
+ (if (file-exists-p lisp-subdir) lisp-subdir
+ project-root)))
+
+(defun erk--project-root-feature-file ()
+ "Return the path of the root feature for the project."
+ (let* ((project-elisp-dir (erk--project-elisp-dir))
+ (package-files (directory-files project-elisp-dir nil (rx ".el" string-end)))
+ (package-files (->> package-files
+ (--reject (string-match-p (rx "autoloads.el" string-end) it))))
+ (root-feature-file (car (sort package-files #'string<))))
+ (concat project-elisp-dir "/" root-feature-file)))
+
+(defun erk-package-author ()
+ "Return the author of this project's package."
+ (car (car (lm-authors (erk--project-root-feature-file)))))
+
+(defun erk-package-email ()
+ "Return the email of this project's package."
+ (cdr (car (lm-authors (erk--project-root-feature-file)))))
+
+(defun erk-package-version ()
+ "Return the version of this project's package."
+ (lm-version (erk--project-root-feature-file)))
+
;;;###autoload
(defun erk-reload-project-package ()
"Reload the features this project provides.
@@ -308,18 +357,18 @@ used in copyright notices. USER-ORG will be used as the first
part of the new github path. EMAIL is shown after AUTHOR in
package headers."
(let ((default-directory dir)
- (erk-github-path (concat erk-github-userorg "/"
- erk-github-package-name))
+ (erk-github-path (concat erk-replace-github-userorg "/"
+ erk-replace-github-package-name))
(github-path (concat user-org "/" package-name))
(package-prefix package-prefix)
- (replace-prefix (erk--prefix-match erk-package-prefix))
+ (replace-prefix (erk--prefix-match erk-replace-package-prefix))
(capitalized-package-title
(string-join (mapcar #'capitalize
(split-string package-name "-"))
" "))
(replace-package-title
(string-join (mapcar #'capitalize
- (split-string erk-github-package-name "-"))
+ (split-string erk-replace-github-package-name "-"))
" ")))
(mapc
(lambda (file)
@@ -335,7 +384,7 @@ package headers."
(end-of-line)
(insert ", " author))
(goto-char (point-min))
- (when (re-search-forward (rx "" eol) nil t)
+ (when (re-search-forward (rx (literal erk-replace-author) eol) nil t)
(replace-match (concat author " <" email ">") nil t))
(goto-char (point-min))
;; replace license with GPL3 notice
@@ -351,7 +400,7 @@ package headers."
(replace-match package-prefix nil t nil 1))
(goto-char (point-min))
;; update remaining package name strings.
- (while (re-search-forward erk-github-package-name nil t)
+ (while (re-search-forward erk-replace-github-package-name nil t)
(replace-match package-name nil t))
(goto-char (point-min))
(while (re-search-forward replace-package-title nil t)
@@ -378,7 +427,7 @@ itself, as a quine and for forking as a new template repository."
git-bin nil output nil
"clone"
(format "https://github.com/%s/%s.git"
- erk-github-userorg erk-github-package-name)
+ erk-replace-github-userorg erk-replace-github-package-name)
(concat default-directory "/" package-name))
"Clone failed")
(let ((default-directory (concat clone-root "/" package-name))
@@ -429,7 +478,7 @@ by the author of this repository."
\nsGitHub organization or username: \nsEmail: ")
(erk--replace-strings
clone-dir package-name package-prefix author user-org email)
- (erk--rename-package clone-dir erk-package-prefix package-name))
+ (erk--rename-package clone-dir erk-replace-package-prefix package-name))
;;;###autoload
(defun erk-new (package-name package-prefix clone-root author user-org email &optional rev)
@@ -450,12 +499,12 @@ implementation information and more details about argument usage."
(let*
((package-name
(read-string
- (format "Package name, such as %s: " erk-github-package-name)
+ (format "Package name, such as %s: " erk-replace-github-package-name)
"foo"))
(package-prefix
(erk--nodash
(read-string
- (format "Package prefix, such as %s: " erk-package-prefix))))
+ (format "Package prefix, such as %s: " erk-replace-package-prefix))))
(clone-root
(directory-file-name
(read-directory-name "Clone root: " default-directory)))
@@ -477,5 +526,159 @@ implementation information and more details about argument usage."
(erk-clone clone-root package-name user-org rev)
package-name package-prefix author user-org email))
+;;;###autoload
+(defun erk-insert-package-keyword (keyword)
+ "Insert package KEYWORD, from `finder-known-keywords'.
+This list's name is easy to forget, so here's a shortcut."
+ (interactive
+ (list
+ (completing-read
+ "Insert package keyword:"
+ finder-known-keywords
+ nil t nil nil
+ (lambda (item)
+ (format "%s\t%s" (car item) (cdr item))))))
+ (insert (format "\"%s\"" keyword)))
+
+(defvar erk--find-paths
+ '((ci-dco . ".github/workflows/dco.yml")
+ (ci-nix-flake . ".github/flake.nix")
+ (ci-run-shim . ".github/run-shim.el")
+ (ci-tests . ".github/workflows/ci.yml")
+ (docs-contributing . "docs/CONTRIBUTING.org")
+ (docs-manual . "docs/manual.org")
+ (docs-readme . "docs/README.org"))
+ "Paths that exist in an ERK style project.")
+
+;;;###autoload
+(defun erk-find (file)
+ "Find FILE within projects using erk's project structure."
+ (interactive (list (completing-read "Select file" erk--find-paths)))
+ (find-file (concat (erk--project-root) (cdr (assoc-string file erk--find-paths)))))
+
+;;;###autoload
+(defun erk-find-ci-dco ()
+ "Shortcut for `erk-find'."
+ (interactive)
+ (erk-find "ci-dco"))
+
+;;;###autoload
+(defun erk-find-ci-nix-flake ()
+ "Shortcut for `erk-find'."
+ (interactive)
+ (erk-find "ci-nix-flake"))
+
+;;;###autoload
+(defun erk-find-ci-run-shim ()
+ "Shortcut for `erk-find'."
+ (interactive)
+ (erk-find "ci-run-shim"))
+
+;;;###autoload
+(defun erk-find-ci-tests ()
+ "Shortcut for `erk-find'."
+ (interactive)
+ (erk-find "ci-tests"))
+
+;;;###autoload
+(defun erk-find-docs-contributing ()
+ "Shortcut for `erk-find'."
+ (interactive)
+ (erk-find "docs-contributing"))
+
+;;;###autoload
+(defun erk-find-docs-manual ()
+ "Shortcut for `erk-find'."
+ (interactive)
+ (erk-find "docs-manual"))
+
+;;;###autoload
+(defun erk-find-docs-readme ()
+ "Shortcut for `erk-find'."
+ (interactive)
+ (erk-find "docs-readme"))
+
+
+(defun erk--export (filename export-fun)
+ "Export FILENAME to markdown using EXPORT-FUN."
+ (let* ((buffer (find-buffer-visiting filename))
+ (buffer (or buffer (find-file-noselect filename))))
+ (set-buffer buffer)
+ (when (buffer-modified-p buffer)
+ (when (yes-or-no-p "Save buffer? ")
+ (save-buffer)))
+ (save-restriction
+ (widen)
+ (save-excursion
+ (when (region-active-p) (deactivate-mark))
+ (funcall export-fun)))))
+
+;;;###autoload
+(defun erk-export-contributing (&optional preview)
+ "Export the contributing doc to markdown.
+With prefix argument, PREVIEW the buffer."
+ (interactive "P")
+ (erk--export
+ (concat (erk--project-root)
+ (cdr (assoc 'docs-contributing erk--find-paths)))
+ #'org-md-export-to-markdown)
+ (when preview
+ (find-file-read-only-other-window
+ (concat (erk--project-root)
+ "CONTRIBUTING.md"))))
+
+;;;###autoload
+(defun erk-export-manual (&optional preview)
+ "Export the manual doc to markdown.
+With prefix argument, PREVIEW the buffer."
+ (interactive "P")
+ (erk--export
+ (concat (erk--project-root)
+ (cdr (assoc 'docs-manual erk--find-paths)))
+ #'org-texinfo-export-to-info)
+ (when preview
+ (let ((exported-path (concat (erk--project-root)
+ "docs/manual.info")))
+ (info-initialize)
+ (info-other-window (Info-find-file exported-path)
+ (generate-new-buffer-name "*info*")))))
+
+;;;###autoload
+(defun erk-export-readme (&optional preview)
+ "Export the readme doc to markdown.
+With prefix argument, PREVIEW the buffer."
+ (interactive "P")
+ (erk--export
+ (concat (erk--project-root)
+ (cdr (assoc 'docs-readme erk--find-paths)))
+ #'org-md-export-to-markdown)
+ (when preview
+ (find-file-read-only-other-window
+ (concat (erk--project-root)
+ "README.md"))))
+
+;;;###autoload
+(defun erk-preview-contributing ()
+ "Export and show the contributing."
+ (let ((prefix-arg t))) (call-interactively #'erk-export-contributing))
+
+;;;###autoload
+(defun erk-preview-manual ()
+ "Export and show the manual."
+ (let ((prefix-arg t))) (call-interactively #'erk-export-manual))
+
+;;;###autoload
+(defun erk-preview-readme ()
+ "Export and show the readme."
+ (let ((prefix-arg t))) (call-interactively #'erk-export-readme))
+
+;;;###autoload
+(defun erk-export-docs ()
+ "Shortcut to export all docs."
+ (interactive)
+ (erk-export-contributing)
+ (erk-export-readme)
+ (erk-export-manual))
+
(provide 'erk)
;;; erk.el ends here