Skip to content

Commit

Permalink
nix: add flake
Browse files Browse the repository at this point in the history
  • Loading branch information
abathur committed Sep 16, 2023
1 parent 56c8ad6 commit 53fc735
Show file tree
Hide file tree
Showing 26 changed files with 851 additions and 422 deletions.
10 changes: 6 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ jobs:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v23
with:
nix_path: nixpkgs=channel:nixos-unstable
- run: touch .local && nix-build ci.nix
- name: ensure demo doesn't rot
run: nix-shell --run "./demo"
nix_path: nixpkgs=channel:nixpkgs-unstable
- run: nix build .#ci
- name: validate core CLI demo
run: nix-shell --run ./demo
- name: validate new CLI demo
run: nix develop --command ./demo
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# resholve specific
.local.nix
*.resolved
*.todo
flarf/

# nix
result
result-ci
nix-result-ci
nixpkgs_source
nixpkgs_source.touch

# subl
*.sublime-*
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## September 14, 2023
Refactor Nix expressions and convert to flake.

## v0.9.0 (Jan 29 2023)
Update oil/osh parser from 0.8.12 -> 0.14.0. In the process of updating the parser, I also cut out some extensions and dependencies that resholve shouldn't need to depend on.

Expand Down
24 changes: 13 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#! /usr/bin/env make
#export PATH := $(shell nix-shell -p nix coreutils gnused groff util-linux --run 'echo $$PATH')
export PATH := $(shell nix-shell make.nix --run 'echo $$PATH')
export PATH := $(shell nix develop .#make --command sh -c 'echo $$makeInputs')

.PHONY: apologeez ci clean update # lint

Expand All @@ -12,20 +11,17 @@ all: apologeez
install: apologeez
uninstall: apologeez

.local : *.nix setup.cfg setup.py test.sh demo tests/* resholve.1 resholve _resholve/*
touch .local


result-ci: .local
@echo Building ci.nix
@nix-build --out-link nix-result-ci ci.nix
result-ci: *.nix setup.cfg setup.py test.sh demo tests/* resholve.1 resholve _resholve/*
@echo Running Nix CI tests
@nix build .#ci --out-link nix-result-ci --print-build-logs
@mkdir -p result-ci
@install -m 644 nix-result-ci/* result-ci/

ci: result-ci

clean:
rm .local nix-result-ci result-ci/* docs/README.nixpkgs.md
rm nix-result-ci result-ci/* nixpkgs/README.md

result-ci/test.txt result-ci/demo.txt result-ci/nix-demo.txt: result-ci

Expand All @@ -49,7 +45,13 @@ resholve.1: docs/manpage.wwst docs/manpage.css docs/content.wwst
@echo Building manpage
@wordswurst $< > $@

docs/README.nixpkgs.md: docs/markdown.wwst docs/markdown.css docs/content.wwst docs/examples/*.nix
# use a touchfile; store will have old timestamps
nixpkgs_source.touch: flake.lock
@echo linking nixpkgs source into $@
@nix build --out-link nixpkgs_source "$$(nix eval .#nixpkgs_source --raw)"
@touch nixpkgs_source.touch

nixpkgs/README.md: docs/markdown.wwst docs/markdown.css docs/content.wwst docs/examples/*.nix nixpkgs_source.touch
@echo "Building Nixpkgs README (markdown)"
@wordswurst $< > $@

Expand All @@ -66,7 +68,7 @@ _resholve/strings.py: docs/strings.wwst docs/strings.css docs/content.wwst
@echo Wursting $@ from $<
@wordswurst $< > $@

update: timings.md demos.md docs/resholve.1.txt docs/README.nixpkgs.md
update: timings.md demos.md docs/resholve.1.txt nixpkgs/README.md

# lint: lint-sass # lint-nix

Expand Down
88 changes: 68 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,60 +33,108 @@ In the Nix ecosystem, resholve helps us:

## Quickstart

If you're looking to use resholve for packaging shell projects with Nix, you'll want to start with resholve's Nix API.

> **Note**: resholve is only packaged with Nix for now, so you'll need to have Nix installed.
### Nix API

If you use Nix, you'll want to use resholve's Nix API/builders included in nixpkgs. Two good places to start:
Since resholve's Nix API/builders are included in nixpkgs, most Nix users can jump straight to using it. A few good places to start:
- API reference: [NixOS/nixpkgs: pkgs/development/misc/resholve/README.md](https://github.com/nixos/nixpkgs/blob/master/pkgs/development/misc/resholve/README.md).

- [Examples via GitHub code search](https://github.com/search?q=language%3Anix+%2Fresholve%5C.%28mkDerivation%7CwriteScript%7CwriteScriptBin%7CphraseSolution%29%2F+-path%3A**%2Faliases.nix&type=code)

> **Tip**: Most users won't need the capabilities it illustrates, but you might also want to read through [resholve's Nix demo](demos.md#Nix demo). It's a little terse, but it ~proves that Nix + resholve enable us to compose shell projects that normally have clashing dependencies. (This is most useful for composing multiple shell libraries.)
### CLI

If you'd like to look at scripting resholve or integrating it with other toolchains, you can also use the resholve CLI directly. resholve is only packaged with Nix for now, so you'll need to have it installed.
Most resholve users won't need to directly invoke resholve's CLI, but it's available if you're looking at scripting resholve, integrating it with other toolchains, packaging it, or contributing to resholve itself.

#### Latest stable version
If you're new to resholve, start with the [demo shell](#Demo-shell).

You can get the latest stable version of resholve from Nixpkgs:
If you want to use resholve itself (without the preconfigured demo environment)

> **Note**: However you obtain the resholve CLI, check `man resholve` for CLI usage.
#### Demo shell

The demo shell pulls in some prerequisites for running resholve's command-line demo. This demo illustrates resholve's basic features, invocation patterns, output, and how this process changes scripts.

The easy way to run the demo is with Nix installed and the experimental `nix-command` and `flakes` features enabled. The following command will load the demo shell environment and print more information on how to proceed:

```shell
NIXPKGS_ALLOW_INSECURE=1 nix-shell -p resholve
nix develop github:abathur/resholve
```

Or, you can get it from this Git repo:
> **Note**: If you don't have Nix available, you can see an unhighlighted copy of the demo output in the [Demos](demos.md) document.
<details>
<summary>Traditional `nix-shell` instructions</summary>

You can also use the demo via `nix-shell` if you clone the repository:

```shell
git clone https://github.com/abathur/resholve.git
cd resholve
nix-shell
```

In both cases, check `man resholve` for CLI usage.
</details>

> **Note:** resholve uses python2 because the high-quality shell parser it's built on does. Setting the `NIXPKGS_ALLOW_INSECURE` env is necessary to try resholve out in a shell because `nixpkgs` has taken steps to root out run-time usage of python2. resholve *will* still work at build-time for use in Nix packages. To be safe, don't run resholve on untrusted input.
>
> (This isn't permanent. resholve should eventually be able to move to python3.)
#### Development versions

#### Latest unstable version
resholve's `master` branch is fairly stable. If you have Nix's experimental nix-command and flakes features enabled, you should generally be able to use it with any of the below:

```shell
# without cloning
nix build github:abathur/resholve
nix shell github:abathur/resholve

# from the root of a resholve checkout
nix build
nix shell
```

<details>
<summary>Traditional `nix-build` instructions</summary>

You can build resholve from a checkout with the traditional CLI:

```shell
git clone https://github.com/abathur/resholve.git
cd resholve
mkdir .local
nix-shell
nix-build
```

`mkdir .local` makes `nix-shell` use whatever code is in the resholve folder. Without a folder named `.local`, `nix-shell` will download a copy of a stable version of resholve.
> **Caution**: The same isn't quite true of `nix-shell`, which will load the _demo_ shell. This may be fine for some purposes, but keep in mind that it pre-populates some environment variables just for the demo.
## Contributing
If you're looking to improve resholve or the broader ecosystem (resholve + binlore), feel free to open issue or reach out to me on Matrix or by email.
</details>

#### Latest stable version

You can get the latest stable version of resholve from Nixpkgs:

There's much to do. Some of it is simple and straightforward. Some of it's creative and green-field. Some of it's difficult. I've focused on primary work at the expense of building an onramp for other contributors, but I'm happy to help you get started and use the opportunity to build the ramp as we go.
```shell
# new CLI/flakes
NIXPKGS_ALLOW_INSECURE=1 nix shell nixpkgs#resholve
NIXPKGS_ALLOW_INSECURE=1 nix shell github:nixos/nixpkgs#resholve

# traditional CLI
NIXPKGS_ALLOW_INSECURE=1 nix-shell -p resholve
```

> **Note:** the high-quality shell parser resholve is built on uses python2. `nixpkgs` has taken steps to protect users from accidental _run-time_ use of python2. resholve *will* still work at build-time for use in Nix packages. Setting the `NIXPKGS_ALLOW_INSECURE` env is only needed to use resholve from nixpkgs in a shell. To be safe, don't run resholve on untrusted input.
>
> (This isn't permanent. resholve should eventually be able to move to python3.)
## Contributing
If you're looking to improve resholve or the broader ecosystem (resholve + binlore), feel free to open an issue, reach out to me on Matrix, or send an email.

If you do make code changes, then you can test your changes by following [the instructions for installing an unstable version of resholve](#latest-unstable-version). You can also validate the codebase locally by running `make ci`.
There's much to do. Some of it is simple and straightforward. Some of it's creative and green-field. Some of it's difficult. I've focused on primary work at the expense of documenting an onramp for other contributors, but I'm happy to help you get started and use the opportunity to build the ramp as we go.

Some documentation updates entail updating generated files that currently require an adjacent checkout of nixpkgs--it's easiest to just bug me to do this for now.
If you make code changes, you can rebuild resholve by following [the instructions for building a development version](#development-versions). resholve's tests aren't run during the build, so you should also validate the codebase locally by running `make ci`.

> Caution: from a dev perspective, `default.nix` is a lie. It’s in the form required by callPackage for syncing with nixpkgs.
> **Note**: Some documentation updates entail updating generated files. I use `make update` for this, but this will also usually cause some churn in `timings.md` and `demos.md`. It's generally fine to skip committing those changes if they aren't meaningful (feel free to bug me if you aren't comfortable doing this or need feedback).
## Acknowledgements
- resholve leverages the [Oil](https://github.com/oilshell/oil) shell's OSH parser) and wouldn't be feasible without Andy Chu's excellent work on that project.
Expand Down
11 changes: 5 additions & 6 deletions bits/demos.md.mid
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

## Nix demo

This demo illustrates how to use resholve in Nix to compose a set of modules together. You can see the Nix code for the modules in [ci.nix](ci.nix), and their shell scripts in [tests/nix](tests/nix/). The modules are:
This demo illustrates how to use resholve in Nix to compose a set of modules together. You can see the Nix code for the modules in [nixpkgs/test.nix](nixpkgs/test.nix), and their shell scripts in [tests/nix](tests/nix/). The modules are:

- `shunit2` - This re-builds [Nixpkgs existing shunit2 package](https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/misc/shunit2/default.nix) in a resolved form. This module demonstrates the Nix API for telling resholve that some violations are okay.
- `test_module1` - Depends on the jq and libressl executables, and on test_module2.
- `test_module2` - Depends on the openssl executable, and the shunit2 module/shell library.
- `test_module3` - Depends on test_module1.
Expand All @@ -15,15 +14,15 @@ This demo (which is just a shell script executing with `set -x` enabled around p
- Before any output begins, `conjure.sh` (test_module3) sources `libressl.sh` (test_module1), which sources `openssl.sh` (test_module2), which sources `shunit2`. *Everything is in one shell namespace when the test begins.*
- When `shunit2` is sourced, it automatically collects and runs functions named test_*.
- `type jq openssl` demonstrates that the jq and openssl executables aren't on the PATH. *Dependencies declared for one module/script aren't leaking into others!*
- Both `openssl.sh` and `libressl.sh` invoke `openssl`, but *because the scripts were separately resolved by Nix and resholve, `openssl.sh` correctly invokes `OpenSSL 1.1.1d 10 Sep 2019`, while `libressl.sh` correctly invokes `LibreSSL 2.9.2`!*
- Both `openssl.sh` and `libressl.sh` invoke `openssl`, but *because the scripts were separately resolved by Nix and resholve, `openssl.sh` correctly invokes `OpenSSL x.y.z`, while `libressl.sh` correctly invokes `LibreSSL x.y.z`!*

It is currently tied into the CI run, so for now you'll have to run the whole thing if you want to see it locally (sorry!):

```shell
nix-build ci.nix
nix build .#ci
```

I'll try to keep these up-to-date, but if you suspect this file is outdated you can also find the output at the end of the main phase of resholve's latest successful [weekly scheduled CI run](https://github.com/abathur/resholve/actions?query=branch%3Amaster+event%3Aschedule+is%3Asuccess).
The result will be something like:

```shell
$ nix-build ci.nix
$ nix build .#ci
16 changes: 12 additions & 4 deletions bits/demos.md.pre
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,21 @@ This demo runs a handful of commands on a set of test `.sh` scripts (you can see
- A status > 0 indicates the script couldn't be resolved. The body of the case report quotes the original file, and any feedback the command gives about why it can't resolve the script.
- A status == 0 indicates the script was resolved. The body of the case report shows a diff of the input script, and the resolved output.

To run this demo yourself:
To run this demo yourself, first open the demo shell:

```shell
nix-shell --run "./demo"
# without cloning, w/ experimental nix-command flakes
nix develop github:abathur/resholve

# with a clone
# w/ experimental nix-command flakes
nix develop

# or traditional
nix-shell
```

The demo output is colored for easier reading, but I've included an example of the output below as well:
Once the shell loads, run `demo` to begin. The demo output uses color for easier reading, but I've included a plaintext copy of the output below as well:

```shell
$ nix-shell --run "./demo"
$ demo
27 changes: 0 additions & 27 deletions ci.nix

This file was deleted.

61 changes: 10 additions & 51 deletions default.nix
Original file line number Diff line number Diff line change
@@ -1,51 +1,10 @@
{ lib
, pkgs
, pkgsBuildHost
, ...
}:

let
removeKnownVulnerabilities = pkg: pkg.overrideAttrs (old: {
meta = (old.meta or { }) // { knownVulnerabilities = [ ]; };
});
# We are removing `meta.knownVulnerabilities` from `python27`,
# and setting it in `resholve` itself.
python27' = (removeKnownVulnerabilities pkgsBuildHost.python27).override {
self = python27';
pkgsBuildHost = pkgsBuildHost // { python27 = python27'; };
# strip down that python version as much as possible
openssl = null;
bzip2 = null;
readline = null;
ncurses = null;
gdbm = null;
sqlite = null;
rebuildBytecode = false;
stripBytecode = true;
strip2to3 = true;
stripConfig = true;
stripIdlelib = true;
stripTests = true;
enableOptimizations = false;
};
callPackage = lib.callPackageWith (pkgs // { python27 = python27'; });
source = callPackage ./source.nix { };
deps = callPackage ./deps.nix { };
in rec
{
# resholve itself
resholve = removeKnownVulnerabilities (callPackage ./resholve.nix {
inherit (source) rSrc version;
inherit (deps) binlore;
inherit (deps.oil) oildev;
inherit (deps) configargparse;
inherit resholve-utils;
});
# funcs to validate and phrase invocations of resholve
# and use those invocations to build packages
resholve-utils = callPackage ./resholve-utils.nix {
inherit resholve;
inherit (deps) binlore;
};
python27 = python27';
}
(import
(
let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
)
{ src = ./.; }
).defaultNix
Loading

0 comments on commit 53fc735

Please sign in to comment.