github actions: niv -> flakes

Use flake.nix/lock as a single source of truth for resolving
dependencies

NOTE: this patch implies a dependency update as well.
This commit is contained in:
László Vaskó
2020-12-26 18:24:14 +00:00
parent fbb213c531
commit 5ee8044b04
9 changed files with 723 additions and 355 deletions

View File

@ -1,17 +0,0 @@
name: Automated niv-managed dependency updates
on:
schedule:
# Every friday
- cron: '0 0 * * FRI'
jobs:
niv-updater:
name: 'Create PRs for niv-managed dependencies'
runs-on: ubuntu-latest
steps:
# notice there is no checkout step
- name: niv-updater-action
uses: knl/niv-updater-action@v7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
pull_request_base: 'develop'

View File

@ -0,0 +1,25 @@
name: "Update Dependencies"
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * FRI'
jobs:
update-deps:
name: Update dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
# Nix Flakes doesn't work on shallow clones
fetch-depth: 0
- uses: cachix/install-nix-action@v12
with:
install_url: https://github.com/numtide/nix-flakes-installer/releases/download/nix-2.4pre20201221_9fab14a/install
extra_nix_config: |
experimental-features = nix-command flakes
- name: Create PRs for dependencies
env:
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_BASE_BRANCH: develop
run: |
nix develop -c .github/workflows/update_flake_lock.py

173
.github/workflows/update_flake_lock.py vendored Executable file
View File

@ -0,0 +1,173 @@
#!/usr/bin/env python3
import json
import sys
import re
from tempfile import TemporaryDirectory
from subprocess import check_call
from difflib import unified_diff
from os import environ as env, path
from typing import NamedTuple, cast
from github import Github
from github.ContentFile import ContentFile
from github.GitCommit import GitCommit
from github.GithubException import GithubException
from github.Repository import Repository
API_TOKEN = env["GITHUB_API_TOKEN"]
REPOSITORY = env["GITHUB_REPOSITORY"]
BASE_BRANCH = env.get("GITHUB_BASE_BRANCH", "master")
DRY_RUN = bool(env.get("GITHUB_DRY_RUN", False))
LOCK = "flake.lock"
FLAKE = "flake.nix"
class Input(NamedTuple):
repo: str
branch: str
rev: str
class FlakeLock:
def __init__(self, github: Github, lock_contents) -> None:
self._github = github
self._lock = json.loads(lock_contents)
@property
def inputs(self):
return self._lock["nodes"]["root"]["inputs"]
def get_input(self, flake_input):
n = self._lock["nodes"][flake_input]
repo_id = f"{n['locked']['owner']}/{n['locked']['repo']}"
branch = n["original"].get("ref")
if not branch:
repo = self._github.get_repo(repo_id)
branch = repo.default_branch
return Input(repo_id, branch, n["locked"]["rev"])
def nix_flake_update(repo, flake_input):
check_call(["nix", "flake", "update", "--update-input", flake_input], cwd=repo)
def format_change(change: GitCommit, repo):
sha = change.sha[:8]
url = change.html_url
msg = re.sub(
r"#(?P<id>\d+)",
f"[{repo}\u2060#\\g<id>](http://r.duckduckgo.com/l/?uddg=https://github.com/{repo}/issues/\\g<id>)",
change.message.splitlines()[0],
)
return f"- [{sha}]({url}) {msg}"
def create_pr(
repo: Repository,
pr_branch_name: str,
head: str,
file: ContentFile,
updated_content: str,
pr_title: str,
pr_body: str,
):
try:
repo.get_branch(pr_branch_name)
print(f"Branch '{pr_branch_name}' already exist. Skipping update.")
return
except GithubException as ex:
if ex.status != 404:
raise
pr_branch = repo.create_git_ref(pr_branch_name, head)
repo.update_file(
file.path,
f"{pr_title}\n\n{pr_body}",
updated_content,
file.sha,
branch=pr_branch_name,
)
repo.create_pull(title=pr_title, body=pr_body, head=pr_branch.ref, base=BASE_BRANCH)
def main():
if API_TOKEN:
github = Github(API_TOKEN)
else:
print("GITHUB_API_TOKEN is required")
sys.exit(1)
repo = github.get_repo(REPOSITORY)
head = repo.get_branch(BASE_BRANCH).commit.sha
flake_contents = cast(ContentFile, repo.get_contents(FLAKE, ref=BASE_BRANCH))
lock_contents = cast(ContentFile, repo.get_contents(LOCK, ref=BASE_BRANCH))
lock_lines = lock_contents.decoded_content.decode().splitlines(keepends=True)
lock = FlakeLock(github, lock_contents.decoded_content)
for flake_input in lock.inputs:
with TemporaryDirectory(prefix="nix-flake-update.") as root:
with open(path.join(root, LOCK), "wb") as f:
f.write(lock_contents.decoded_content)
with open(path.join(root, FLAKE), "wb") as f:
f.write(flake_contents.decoded_content)
print(f"[{flake_input}] Checking for updates")
nix_flake_update(root, flake_input)
with open(path.join(root, LOCK), "r") as f:
updated_lock_lines = f.readlines()
diff = list(unified_diff(lock_lines, updated_lock_lines))
if not diff:
print(f"[{flake_input}] No update available")
continue
print(f"[{flake_input}] Updated")
updated_lock_contents = "".join(updated_lock_lines)
for l in diff:
print(l, end="")
old = lock.get_input(flake_input)
new = FlakeLock(github, updated_lock_contents).get_input(flake_input)
title = f"flake.lock: Updating '{flake_input} ({old.repo})' - {old.rev[:8]} -> {new.rev[:8]}"
dep_repo = github.get_repo(new.repo)
changes = dep_repo.compare(old.rev, new.rev)
commit_messages = "\n".join(
format_change(c.commit, new.repo)
for c in changes.commits
if len(c.parents) == 1
)
body = f"""\
### Changes for {flake_input}
On branch: {new.branch}
Commits: {changes.html_url}
{commit_messages}
"""
print(f"[{flake_input}] - Creating PR\nTitle: {title}\nBody:\n{body}")
if DRY_RUN:
print(f"DRY-RUN: NOT creating PR...")
continue
pr_branch_name = f"refs/heads/update/{flake_input}-{new.rev}"
create_pr(
repo,
pr_branch_name,
head,
lock_contents,
updated_lock_contents,
title,
body,
)
if __name__ == "__main__":
main()

View File

@ -66,10 +66,10 @@
, writeTextDir }:
let
sources = import ./nix/sources.nix;
flake = import ./flake-compat-helper.nix { src=./.; };
lock = p: if dependencyOverrides ? ${p}
then dependencyOverrides.${p}
else sources.${p};
else flake.inputs.${p};
# Packages we need to get the default doom configuration run
overrides = self: super:
(pkgs.callPackage ./overrides.nix { inherit lock; } self super) // (emacsPackagesOverlay self super);

183
flake-compat-helper.nix Normal file
View File

@ -0,0 +1,183 @@
# Based on flake-compat as of:
# Based on flake-compat as of: https://github.com/edolstra/flake-compat/blob/99f1c2157fba4bfe6211a321fd0ee43199025dbf/default.nix
# Instead of generating a shim for `default.nix` it exposes the `allNodes` method
#Compatibility function to allow flakes to be used by
# non-flake-enabled Nix versions. Given a source tree containing a
# 'flake.nix' and 'flake.lock' file, it fetches the flake inputs and
# calls the flake's 'outputs' function. It then returns an attrset
# containing 'defaultNix' (to be used in 'default.nix'), 'shellNix'
# (to be used in 'shell.nix').
{ src, system ? builtins.currentSystem or "unknown-system" }:
let
lockFilePath = src + "/flake.lock";
lockFile = builtins.fromJSON (builtins.readFile lockFilePath);
fetchTree =
info:
if info.type == "github" then
{ outPath = fetchTarball "https://api.${info.host or "github.com"}/repos/${info.owner}/${info.repo}/tarball/${info.rev}";
rev = info.rev;
shortRev = builtins.substring 0 7 info.rev;
lastModified = info.lastModified;
lastModifiedDate = formatSecondsSinceEpoch info.lastModified;
narHash = info.narHash;
}
else if info.type == "git" then
{ outPath =
builtins.fetchGit
({ url = info.url; }
// (if info ? rev then { inherit (info) rev; } else {})
// (if info ? ref then { inherit (info) ref; } else {})
);
lastModified = info.lastModified;
lastModifiedDate = formatSecondsSinceEpoch info.lastModified;
narHash = info.narHash;
} // (if info ? rev then {
rev = info.rev;
shortRev = builtins.substring 0 7 info.rev;
} else {
})
else if info.type == "path" then
{ outPath = builtins.path { path = info.path; };
narHash = info.narHash;
}
else if info.type == "tarball" then
{ outPath = fetchTarball info.url;
narHash = info.narHash;
}
else if info.type == "gitlab" then
{ inherit (info) rev narHash lastModified;
outPath = fetchTarball "https://${info.host or "gitlab.com"}/api/v4/projects/${info.owner}%2F${info.repo}/repository/archive.tar.gz?sha=${info.rev}";
shortRev = builtins.substring 0 7 info.rev;
}
else
# FIXME: add Mercurial, tarball inputs.
throw "flake input has unsupported input type '${info.type}'";
callFlake4 = flakeSrc: locks:
let
flake = import (flakeSrc + "/flake.nix");
inputs = builtins.mapAttrs (n: v:
if v.flake or true
then callFlake4 (fetchTree (v.locked // v.info)) v.inputs
else fetchTree (v.locked // v.info)) locks;
outputs = flakeSrc // (flake.outputs (inputs // {self = outputs;}));
in
assert flake.edition == 201909;
outputs;
callLocklessFlake = flakeSrc:
let
flake = import (flakeSrc + "/flake.nix");
outputs = flakeSrc // (flake.outputs ({ self = outputs; }));
in outputs;
rootSrc = let
# Try to clean the source tree by using fetchGit, if this source
# tree is a valid git repository.
tryFetchGit = src:
if isGit && !isShallow
then
let res = builtins.fetchGit src;
in if res.rev == "0000000000000000000000000000000000000000" then removeAttrs res ["rev" "shortRev"] else res
else { outPath = src; };
# NB git worktrees have a file for .git, so we don't check the type of .git
isGit = builtins.pathExists (src + "/.git");
isShallow = builtins.pathExists (src + "/.git/shallow");
in
{ lastModified = 0; lastModifiedDate = formatSecondsSinceEpoch 0; }
// (if src ? outPath then src else tryFetchGit src);
# Format number of seconds in the Unix epoch as %Y%m%d%H%M%S.
formatSecondsSinceEpoch = t:
let
rem = x: y: x - x / y * y;
days = t / 86400;
secondsInDay = rem t 86400;
hours = secondsInDay / 3600;
minutes = (rem secondsInDay 3600) / 60;
seconds = rem t 60;
# Courtesy of https://stackoverflow.com/a/32158604.
z = days + 719468;
era = (if z >= 0 then z else z - 146096) / 146097;
doe = z - era * 146097;
yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
y = yoe + era * 400;
doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
mp = (5 * doy + 2) / 153;
d = doy - (153 * mp + 2) / 5 + 1;
m = mp + (if mp < 10 then 3 else -9);
y' = y + (if m <= 2 then 1 else 0);
pad = s: if builtins.stringLength s < 2 then "0" + s else s;
in "${toString y'}${pad (toString m)}${pad (toString d)}${pad (toString hours)}${pad (toString minutes)}${pad (toString seconds)}";
allNodes =
builtins.mapAttrs
(key: node:
let
sourceInfo =
if key == lockFile.root
then rootSrc
else fetchTree (node.info or {} // removeAttrs node.locked ["dir"]);
subdir = if key == lockFile.root then "" else node.locked.dir or "";
flake = import (sourceInfo + (if subdir != "" then "/" else "") + subdir + "/flake.nix");
inputs = builtins.mapAttrs
(inputName: inputSpec: allNodes.${resolveInput inputSpec})
(node.inputs or {});
# Resolve a input spec into a node name. An input spec is
# either a node name, or a 'follows' path from the root
# node.
resolveInput = inputSpec:
if builtins.isList inputSpec
then getInputByPath lockFile.root inputSpec
else inputSpec;
# Follow an input path (e.g. ["dwarffs" "nixpkgs"]) from the
# root node, returning the final node.
getInputByPath = nodeName: path:
if path == []
then nodeName
else
getInputByPath
# Since this could be a 'follows' input, call resolveInput.
(resolveInput lockFile.nodes.${nodeName}.inputs.${builtins.head path})
(builtins.tail path);
outputs = flake.outputs (inputs // { self = result; });
result = outputs // sourceInfo // { inherit inputs; inherit outputs; inherit sourceInfo; };
in
if node.flake or true then
assert builtins.isFunction flake.outputs;
result
else
sourceInfo
)
lockFile.nodes;
result =
if !(builtins.pathExists lockFilePath)
then callLocklessFlake rootSrc
else if lockFile.version == 4
then callFlake4 rootSrc (lockFile.inputs)
else if lockFile.version >= 5 && lockFile.version <= 7
then allNodes.${lockFile.root}
else throw "lock file '${lockFilePath}' has unsupported version ${toString lockFile.version}";
in
result

316
flake.lock generated Normal file
View File

@ -0,0 +1,316 @@
{
"nodes": {
"doom-emacs": {
"flake": false,
"locked": {
"lastModified": 1611017958,
"narHash": "sha256-7UYJHbU4C+aV3x1xV+9gsyga4SNz+G8m2VFUVnetWMg=",
"owner": "hlissner",
"repo": "doom-emacs",
"rev": "2ad1eab6eebbae554ebcd931c03b7f906a77f3ec",
"type": "github"
},
"original": {
"owner": "hlissner",
"ref": "develop",
"repo": "doom-emacs",
"type": "github"
}
},
"doom-snippets": {
"flake": false,
"locked": {
"lastModified": 1609713949,
"narHash": "sha256-mthIKcR7l9Du32eoBj7PkcW/nKceNMAASjDVEmWsgNY=",
"owner": "hlissner",
"repo": "doom-snippets",
"rev": "aa5587b8c9863fcbb34e21d518ce1947ba4aeb22",
"type": "github"
},
"original": {
"owner": "hlissner",
"repo": "doom-snippets",
"type": "github"
}
},
"emacs-overlay": {
"flake": false,
"locked": {
"lastModified": 1611403984,
"narHash": "sha256-o7IGG+txGwLCAB4os1YW2FvAAIZWPYDCa5CxC6tkVaA=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "9e77787f9160d37ba4b07717442dc3ce12e8f7e8",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "emacs-overlay",
"type": "github"
}
},
"emacs-so-long": {
"flake": false,
"locked": {
"lastModified": 1575031854,
"narHash": "sha256-xIa5zO0ZaToDrec1OFjBK6l39AbA4l/CE4LInVu2hi0=",
"owner": "hlissner",
"repo": "emacs-so-long",
"rev": "ed666b0716f60e8988c455804de24b55919e71ca",
"type": "github"
},
"original": {
"owner": "hlissner",
"repo": "emacs-so-long",
"type": "github"
}
},
"evil-markdown": {
"flake": false,
"locked": {
"lastModified": 1591038520,
"narHash": "sha256-Kt2wxG1XCFowavVWtj0urM/yURKegonpZcxTy/+CrJY=",
"owner": "Somelauw",
"repo": "evil-markdown",
"rev": "064fe9b4767470472356d20bdd08e2f30ebbc9ac",
"type": "github"
},
"original": {
"owner": "Somelauw",
"repo": "evil-markdown",
"type": "github"
}
},
"evil-org-mode": {
"flake": false,
"locked": {
"lastModified": 1607203864,
"narHash": "sha256-JxwqVYDN6OIJEH15MVI6XOZAPtUWUhJQWHyzcrUvrFg=",
"owner": "hlissner",
"repo": "evil-org-mode",
"rev": "a9706da260c45b98601bcd72b1d2c0a24a017700",
"type": "github"
},
"original": {
"owner": "hlissner",
"repo": "evil-org-mode",
"type": "github"
}
},
"evil-quick-diff": {
"flake": false,
"locked": {
"lastModified": 1575189609,
"narHash": "sha256-oGzl1ayW9rIuq0haoiFS7RZsS8NFMdEA7K1BSozgnJU=",
"owner": "rgrinberg",
"repo": "evil-quick-diff",
"rev": "69c883720b30a892c63bc89f49d4f0e8b8028908",
"type": "github"
},
"original": {
"owner": "rgrinberg",
"repo": "evil-quick-diff",
"type": "github"
}
},
"explain-pause-mode": {
"flake": false,
"locked": {
"lastModified": 1595842060,
"narHash": "sha256-++znrjiDSx+cy4okFBBXUBkRFdtnE2x+trkmqjB3Njs=",
"owner": "lastquestion",
"repo": "explain-pause-mode",
"rev": "2356c8c3639cbeeb9751744dbe737267849b4b51",
"type": "github"
},
"original": {
"owner": "lastquestion",
"repo": "explain-pause-mode",
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1610051610,
"narHash": "sha256-U9rPz/usA1/Aohhk7Cmc2gBrEEKRzcW4nwPWMPwja4Y=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "3982c9903e93927c2164caa727cd3f6a0e6d14cc",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nix-straight": {
"flake": false,
"locked": {
"lastModified": 1592852066,
"narHash": "sha256-IwmBDtGv7GamiwCG+awZN6VgtHqJElkv/ic0VrVXAkI=",
"owner": "vlaci",
"repo": "nix-straight.el",
"rev": "9e6f7d71760b997b09d9bd3046257bc9ec17265b",
"type": "github"
},
"original": {
"owner": "vlaci",
"ref": "v2.1.0",
"repo": "nix-straight.el",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1611396451,
"narHash": "sha256-ZQDpSOA8NAu4Gzoen0lNtjxHB0GY1VJAC/cByOAvpb8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f6a583eeece936a1d917de67194fec4b6c74cf1f",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixpkgs-unstable",
"type": "indirect"
}
},
"nose": {
"flake": false,
"locked": {
"lastModified": 1400604510,
"narHash": "sha256-daEi8Kta1oGaDEmUUDDQMahTTPOpvNpDKk22rlr7cB0=",
"owner": "emacsattic",
"repo": "nose",
"rev": "f8528297519eba911696c4e68fa88892de9a7b72",
"type": "github"
},
"original": {
"owner": "emacsattic",
"repo": "nose",
"type": "github"
}
},
"ob-racket": {
"flake": false,
"locked": {
"lastModified": 1584656173,
"narHash": "sha256-rBUYDDCXb+3D4xTPQo9UocbTPZ32kWV1Uya/1DmZknU=",
"owner": "xchrishawk",
"repo": "ob-racket",
"rev": "83457ec9e1e96a29fd2086ed19432b9d75787673",
"type": "github"
},
"original": {
"owner": "xchrishawk",
"repo": "ob-racket",
"type": "github"
}
},
"org-mode": {
"flake": false,
"locked": {
"lastModified": 1611291947,
"narHash": "sha256-wa0Z+y+T/AJEmdQYQX1rZADHhGU4mDqWBiC0j3JRPzY=",
"owner": "emacs-straight",
"repo": "org-mode",
"rev": "3916a574063887f145af2e42667fb6478a065440",
"type": "github"
},
"original": {
"owner": "emacs-straight",
"repo": "org-mode",
"type": "github"
}
},
"org-yt": {
"flake": false,
"locked": {
"lastModified": 1527381913,
"narHash": "sha256-dzQ6B7ryzatHCTLyEnRSbWO0VUiX/FHYnpHTs74aVUs=",
"owner": "TobiasZawada",
"repo": "org-yt",
"rev": "40cc1ac76d741055cbefa13860d9f070a7ade001",
"type": "github"
},
"original": {
"owner": "TobiasZawada",
"repo": "org-yt",
"type": "github"
}
},
"php-extras": {
"flake": false,
"locked": {
"lastModified": 1573312690,
"narHash": "sha256-r4WyVbzvT0ra4Z6JywNBOw5RxOEYd6Qe2IpebHXkj1U=",
"owner": "arnested",
"repo": "php-extras",
"rev": "d410c5af663c30c01d461ac476d1cbfbacb49367",
"type": "github"
},
"original": {
"owner": "arnested",
"repo": "php-extras",
"type": "github"
}
},
"revealjs": {
"flake": false,
"locked": {
"lastModified": 1602496264,
"narHash": "sha256-oN77CUmmvrzObhQbORXAujjb+4IkiYbKVLsi7hddsIM=",
"owner": "hakimel",
"repo": "reveal.js",
"rev": "0582f57517c97a4c7bfeb58762138c78883f94c5",
"type": "github"
},
"original": {
"owner": "hakimel",
"repo": "reveal.js",
"type": "github"
}
},
"root": {
"inputs": {
"doom-emacs": "doom-emacs",
"doom-snippets": "doom-snippets",
"emacs-overlay": "emacs-overlay",
"emacs-so-long": "emacs-so-long",
"evil-markdown": "evil-markdown",
"evil-org-mode": "evil-org-mode",
"evil-quick-diff": "evil-quick-diff",
"explain-pause-mode": "explain-pause-mode",
"flake-utils": "flake-utils",
"nix-straight": "nix-straight",
"nixpkgs": "nixpkgs",
"nose": "nose",
"ob-racket": "ob-racket",
"org-mode": "org-mode",
"org-yt": "org-yt",
"php-extras": "php-extras",
"revealjs": "revealjs",
"rotate-text": "rotate-text"
}
},
"rotate-text": {
"flake": false,
"locked": {
"lastModified": 1322962747,
"narHash": "sha256-SOeOgSlcEIsKhUiYDJv0p+mLUb420s9E2BmvZQvZ0wk=",
"owner": "debug-ito",
"repo": "rotate-text.el",
"rev": "48f193697db996855aee1ad2bc99b38c6646fe76",
"type": "github"
},
"original": {
"owner": "debug-ito",
"repo": "rotate-text.el",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View File

@ -68,14 +68,30 @@
revealjs.flake = false;
rotate-text.url = "github:debug-ito/rotate-text.el";
rotate-text.flake = false;
nixpkgs.url = "nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { nixpkgs, ... }@inputs: {
hmModule = import ./modules/home-manager.nix inputs;
checks."x86_64-linux".init-example-el =
outputs = { nixpkgs, flake-utils, ... }@inputs:
let
pkgs = nixpkgs.legacyPackages."x86_64-linux";
inherit (flake-utils.lib) eachDefaultSystem eachSystem;
in
pkgs.callPackage ./. { doomPrivateDir = ./test/doom.d; dependencyOverrides = inputs; };
eachDefaultSystem
(system:
let
pkgs = import nixpkgs { inherit system; };
in
{
devShell = pkgs.mkShell { buildInputs = [ (pkgs.python3.withPackages (ps: with ps; [ PyGithub ])) ]; };
}) //
eachSystem [ "x86_64-linux" ]
(system: {
checks = {
init-example-el = nixpkgs.legacyPackages.${system}.callPackage ./. { doomPrivateDir = ./test/doom.d; dependencyOverrides = inputs; };
};
}) //
{
hmModule = import ./modules/home-manager.nix inputs;
};
}

View File

@ -1,194 +0,0 @@
{
"doom-emacs": {
"branch": "develop",
"description": "An Emacs configuration for the stubborn martian vimmer",
"homepage": "",
"owner": "hlissner",
"repo": "doom-emacs",
"rev": "2ad1eab6eebbae554ebcd931c03b7f906a77f3ec",
"sha256": "1j2qmmvmcm2iv4k6zy3k4ghila5kc3pmfw8xvyayc2rqnlfhjipd",
"type": "tarball",
"url": "https://github.com/hlissner/doom-emacs/archive/2ad1eab6eebbae554ebcd931c03b7f906a77f3ec.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"doom-snippets": {
"branch": "master",
"description": "The Doom Emacs snippets library",
"homepage": "",
"owner": "hlissner",
"repo": "doom-snippets",
"rev": "aa5587b8c9863fcbb34e21d518ce1947ba4aeb22",
"sha256": "1ml0miji5m9h980c0d0ylyfbzicirwz0da37vzpd15vvqhllin4s",
"type": "tarball",
"url": "https://github.com/hlissner/doom-snippets/archive/aa5587b8c9863fcbb34e21d518ce1947ba4aeb22.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"emacs-overlay": {
"branch": "master",
"description": "Bleeding edge emacs overlay [maintainer=@adisbladis] ",
"homepage": "",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "29267ea1a9fd54f01e80f64a10de9242677718cf",
"sha256": "187ivv1kab9x923gmdx5zdqis5z5krswmjkwbvvi241qdy6rg4fz",
"type": "tarball",
"url": "https://github.com/nix-community/emacs-overlay/archive/29267ea1a9fd54f01e80f64a10de9242677718cf.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"emacs-so-long": {
"branch": "master",
"description": "A mirror of the so-long package (until it's on ELPA)",
"homepage": "https://git.savannah.gnu.org/git/so-long.git/",
"owner": "hlissner",
"repo": "emacs-so-long",
"rev": "ed666b0716f60e8988c455804de24b55919e71ca",
"sha256": "0bc6nrdrvj422g15zqn00vs7ga9bq5c3hdg7ml1kls8rxp6bk1n4",
"type": "tarball",
"url": "https://github.com/hlissner/emacs-so-long/archive/ed666b0716f60e8988c455804de24b55919e71ca.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"evil-markdown": {
"branch": "master",
"description": "Integrates emacs evil and markdown",
"homepage": null,
"owner": "Somelauw",
"repo": "evil-markdown",
"rev": "064fe9b4767470472356d20bdd08e2f30ebbc9ac",
"sha256": "15mchbzwnlyccplqk0ly298z5kxc5qyvcmpmd8q5l22pdp2b1p9a",
"type": "tarball",
"url": "https://github.com/Somelauw/evil-markdown/archive/064fe9b4767470472356d20bdd08e2f30ebbc9ac.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"evil-org-mode": {
"branch": "master",
"description": "Supplemental evil-mode keybindings to emacs org-mode",
"homepage": null,
"owner": "hlissner",
"repo": "evil-org-mode",
"rev": "a9706da260c45b98601bcd72b1d2c0a24a017700",
"sha256": "0n5c5ysp5cvwb1814lhnslz41rjw79932ybx204y5s6dh1ajl717",
"type": "tarball",
"url": "https://github.com/hlissner/evil-org-mode/archive/a9706da260c45b98601bcd72b1d2c0a24a017700.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"evil-quick-diff": {
"branch": "master",
"description": "linediff.vim for evil",
"homepage": null,
"owner": "rgrinberg",
"repo": "evil-quick-diff",
"rev": "69c883720b30a892c63bc89f49d4f0e8b8028908",
"sha256": "15cww264lhddxh0d2ca5qd5nq5pda8hs4nj8mcpb5xlnmkayav50",
"type": "tarball",
"url": "https://github.com/rgrinberg/evil-quick-diff/archive/69c883720b30a892c63bc89f49d4f0e8b8028908.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"explain-pause-mode": {
"branch": "master",
"description": "top, but for Emacs.",
"homepage": "",
"owner": "lastquestion",
"repo": "explain-pause-mode",
"rev": "2356c8c3639cbeeb9751744dbe737267849b4b51",
"sha256": "0frnfwqal9mrnrz6q4v7vcai26ahaw81894arff1yjw372pfgv7v",
"type": "tarball",
"url": "https://github.com/lastquestion/explain-pause-mode/archive/2356c8c3639cbeeb9751744dbe737267849b4b51.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nix-straight.el": {
"branch": "v2.1.0",
"description": null,
"homepage": null,
"owner": "vlaci",
"repo": "nix-straight.el",
"rev": "9e6f7d71760b997b09d9bd3046257bc9ec17265b",
"sha256": "0hh2aysmcd17zqpmj4l9gas6199p36ngk1h0ifk6dv5gs4782293",
"type": "tarball",
"url": "https://github.com/vlaci/nix-straight.el/archive/9e6f7d71760b997b09d9bd3046257bc9ec17265b.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nose": {
"branch": "master",
"description": null,
"homepage": null,
"owner": "emacsattic",
"repo": "nose",
"rev": "f8528297519eba911696c4e68fa88892de9a7b72",
"sha256": "07bhzddaxdjd591xmg59yd657a1is0q515291jd83mjsmgq258bm",
"type": "tarball",
"url": "https://github.com/emacsattic/nose/archive/f8528297519eba911696c4e68fa88892de9a7b72.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"ob-racket": {
"branch": "master",
"description": "Org babel support for racket",
"homepage": "https://github.com/xchrishawk/ob-racket",
"owner": "xchrishawk",
"repo": "ob-racket",
"rev": "83457ec9e1e96a29fd2086ed19432b9d75787673",
"sha256": "0xcjk4wx9gr6adsnb4gnklyx7im1aj7l5kqlwg1ysvwp6061h5dc",
"type": "tarball",
"url": "https://github.com/xchrishawk/ob-racket/archive/83457ec9e1e96a29fd2086ed19432b9d75787673.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"org-mode": {
"branch": "master",
"description": "Mirror of org-mode from orgmode.org",
"homepage": "https://code.orgmode.org/bzg/org-mode",
"owner": "emacs-straight",
"repo": "org-mode",
"rev": "a8df7670c8f7d52d779e1d8e922d519b0aec3afb",
"sha256": "01rcp3kp41zrm43qg7c5v0422mpdi1kciqq2nnbhhns91p3hgv35",
"type": "tarball",
"url": "https://github.com/emacs-straight/org-mode/archive/a8df7670c8f7d52d779e1d8e922d519b0aec3afb.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"org-yt": {
"branch": "master",
"description": "Youtube links in org-mode, see https://emacs.stackexchange.com/questions/38098/org-mode-custom-youtube-link-syntax",
"homepage": null,
"owner": "TobiasZawada",
"repo": "org-yt",
"rev": "40cc1ac76d741055cbefa13860d9f070a7ade001",
"sha256": "0jsm3azb7lwikvc53z4p91av8qvda9s15wij153spkgjp83kld3p",
"type": "tarball",
"url": "https://github.com/TobiasZawada/org-yt/archive/40cc1ac76d741055cbefa13860d9f070a7ade001.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"php-extras": {
"branch": "develop",
"description": "Extra features for Emacs `php-mode'.",
"homepage": "http://marmalade-repo.org/packages/php-extras",
"owner": "arnested",
"repo": "php-extras",
"rev": "d410c5af663c30c01d461ac476d1cbfbacb49367",
"sha256": "0mcgwisnqplav0ga8xqqw72523iv841wp2cyw7d4lkzgpiav51dg",
"type": "tarball",
"url": "https://github.com/arnested/php-extras/archive/d410c5af663c30c01d461ac476d1cbfbacb49367.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"reveal.js": {
"branch": "master",
"description": "The HTML Presentation Framework",
"homepage": "https://revealjs.com",
"owner": "hakimel",
"repo": "reveal.js",
"rev": "0582f57517c97a4c7bfeb58762138c78883f94c5",
"sha256": "10xhblbyw8mvak58d294hbxxnf5sq0akj6qldv7brgm6944zppm0",
"type": "tarball",
"url": "https://github.com/hakimel/reveal.js/archive/0582f57517c97a4c7bfeb58762138c78883f94c5.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"rotate-text.el": {
"branch": "master",
"description": "Emacs: cycle through words, symbols and patterns",
"homepage": "http://nschum.de/src/emacs/rotate-text/",
"owner": "debug-ito",
"repo": "rotate-text.el",
"rev": "48f193697db996855aee1ad2bc99b38c6646fe76",
"sha256": "02fkv45nbbqrv12czlinpr8qpsd7yjdhr628hl58n42w560qxrs8",
"type": "tarball",
"url": "https://github.com/debug-ito/rotate-text.el/archive/48f193697db996855aee1ad2bc99b38c6646fe76.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}
}

View File

@ -1,134 +0,0 @@
# This file has been generated by Niv.
let
#
# The fetchers. fetch_<type> fetches specs of type <type>.
#
fetch_file = pkgs: spec:
if spec.builtin or true then
builtins_fetchurl { inherit (spec) url sha256; }
else
pkgs.fetchurl { inherit (spec) url sha256; };
fetch_tarball = pkgs: spec:
if spec.builtin or true then
builtins_fetchTarball { inherit (spec) url sha256; }
else
pkgs.fetchzip { inherit (spec) url sha256; };
fetch_git = spec:
builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; };
fetch_builtin-tarball = spec:
builtins.trace
''
WARNING:
The niv type "builtin-tarball" will soon be deprecated. You should
instead use `builtin = true`.
$ niv modify <package> -a type=tarball -a builtin=true
''
builtins_fetchTarball { inherit (spec) url sha256; };
fetch_builtin-url = spec:
builtins.trace
''
WARNING:
The niv type "builtin-url" will soon be deprecated. You should
instead use `builtin = true`.
$ niv modify <package> -a type=file -a builtin=true
''
(builtins_fetchurl { inherit (spec) url sha256; });
#
# Various helpers
#
# The set of packages used when specs are fetched using non-builtins.
mkPkgs = sources:
let
sourcesNixpkgs =
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {};
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
hasThisAsNixpkgsPath = <nixpkgs> == ./.;
in
if builtins.hasAttr "nixpkgs" sources
then sourcesNixpkgs
else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
import <nixpkgs> {}
else
abort
''
Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
add a package called "nixpkgs" to your sources.json.
'';
# The actual fetching function.
fetch = pkgs: name: spec:
if ! builtins.hasAttr "type" spec then
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
else if spec.type == "file" then fetch_file pkgs spec
else if spec.type == "tarball" then fetch_tarball pkgs spec
else if spec.type == "git" then fetch_git spec
else if spec.type == "builtin-tarball" then fetch_builtin-tarball spec
else if spec.type == "builtin-url" then fetch_builtin-url spec
else
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
# Ports of functions for older nix versions
# a Nix version of mapAttrs if the built-in doesn't exist
mapAttrs = builtins.mapAttrs or (
f: set: with builtins;
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
);
# fetchTarball version that is compatible between all the versions of Nix
builtins_fetchTarball = { url, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchTarball;
in
if lessThan nixVersion "1.12" then
fetchTarball { inherit url; }
else
fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix
builtins_fetchurl = { url, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchurl;
in
if lessThan nixVersion "1.12" then
fetchurl { inherit url; }
else
fetchurl attrs;
# Create the final "sources" from the config
mkSources = config:
mapAttrs (
name: spec:
if builtins.hasAttr "outPath" spec
then abort
"The values in sources.json should not have an 'outPath' attribute"
else
spec // { outPath = fetch config.pkgs name spec; }
) config.sources;
# The "config" used by the fetchers
mkConfig =
{ sourcesFile ? ./sources.json
, sources ? builtins.fromJSON (builtins.readFile sourcesFile)
, pkgs ? mkPkgs sources
}: rec {
# The sources, i.e. the attribute set of spec name to spec
inherit sources;
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
inherit pkgs;
};
in
mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }