Skip to content

Instantly share code, notes, and snippets.

@pkillnine
Created February 17, 2018 19:51
Show Gist options
  • Save pkillnine/56dcb44f7c3a5c60c4cdf52854712703 to your computer and use it in GitHub Desktop.
Save pkillnine/56dcb44f7c3a5c60c4cdf52854712703 to your computer and use it in GitHub Desktop.
guix package-description generator (WIP)
#!/usr/bin/env python3
#https://www.gnu.org/software/guix/manual/guix.html#Invoking-guix-import
#https://docs.python.org/3/library/argparse.html#argparse.Action
import json, argparse, re, subprocess, tempfile, os
CACHEFILE = os.path.expanduser("~/.cache/guix-module-creator-file-hashes.log")
def add_hash(metadata: dict):
"""Read from cache file which stores url hashes as '<url> <hash>'."""
with open(CACHEFILE, "r") as f:
hashes = f.read()
if len(hashes) > 0:
hashes = {source : source_hash for source, source_hash in [line.split() for line in hashes.split('\n')]}
else:
hashes = []
if metadata["source"] in hashes:
source_hash = hashes[metadata["source"]]
source = {
"method": "url-fetch",
"uri": metadata["source"],
"sha256": {
"base32": source_hash
}
}
metadata["source"] = source
return metadata
elif metadata["source"] not in hashes:
subprocess_call = subprocess.run(["guix", "download", metadata["source"]], stdout=subprocess.PIPE)
if subprocess_call.returncode != 0:
raise Exception("`Guix download` failed with code {}".format(subprocess_call.returncode))
else:
source_hash = subprocess_call.stdout.decode().split('\n')[1]
source = {
"method": "url-fetch",
"uri": metadata["source"],
"sha256": {
"base32": source_hash
}
}
metadata["source"] = source
with open(CACHEFILE, "a") as f:
f.write("{} {}".format(metadata["source"]["uri"], source_hash))
return metadata
def manufacture_pkgdef(metadata: dict):
with tempfile.NamedTemporaryFile(mode="w", delete=False) as f:
tempfile_name = f.name
json.dump(metadata, f)
subprocess_call = subprocess.run(["guix", "import", "json", f.name], stdout=subprocess.PIPE)
os.remove(tempfile_name)
if subprocess_call.returncode != 0:
raise Exception("`Guix import` failed with code {}".format(subprocess_call.returncode))
return header + subprocess_call.stdout.decode()
parser = argparse.ArgumentParser(description='Generate a Guix module.')
parser.add_argument('--source', type=str, required=True,
help="(Required) URL of package source")
parser.add_argument('--build-system', type=str, required=True, metavar="BUILD-SYSTEM", choices=["gnu", "ant", "asdf", "cargo", "cmake", "go", "glib-or-gtk", "minify", "ocaml", "python", "perl", "r", "texlive", "ruby", "waf", "scons", "haskell", "dub", "emacs", "font", "meson", "trivial"],
help="gnu/python/etc")
parser.add_argument('--native-inputs', metavar='INPUT', type=str, nargs='*',
help='Additional build inputs')
parser.add_argument('--inputs', metavar='INPUT', type=str, nargs='*',
help='Additional build and runtime inputs')
parser.add_argument('--propagated-inputs', metavar='INPUT', type=str, nargs='*',
help='Additional runtime inputs')
parser.add_argument('--name', metavar='PACKAGE-NAME', type=str,
help='Will attempt to parse from URL if not specified')
parser.add_argument('--version', metavar='PACKAGE-VERSION', type=str,
help='Will attempt to parse from URL if not specified')
parser.add_argument('--home-page', metavar='URL', type=str, default="")
parser.add_argument('--synopsis', metavar='SYNOPSIS', type=str, default="")
parser.add_argument('--description', metavar='DESCRIPTION', type=str, default="")
parser.add_argument('--license', metavar='LICENSE', type=str, choices=["GPL-3.0+"], default="GPL-3.0+")
#parser.add_argument('--debug')
metadata = vars(parser.parse_args())
for key in metadata:
metadata[key.replace('_', '-')] = metadata.pop(key) # change underscores to dashes
match = re.match(r"^.+\/([\w-]+)-([\d\.]+)\.[\w\.]+", metadata["source"])
if not metadata["name"]:
if match:
metadata["name"] = match.group(1)
else:
raise Exception("Couldn't extract name and/or version.")
if not metadata["version"]:
if match:
metadata["version"] = match.group(2)
else:
raise Exception("Couldn't extract version and/or version.")
header = """(define-module (gnu packages {})
#:use-module (gnu packages)
#:use-module (guix packages)
#:use-module (guix download)
#:use-module (guix build-system {})
#:use-module (guix licenses)
)
; Example arguments to use:
; (arguments
; `(#:tests? #f
; #:make-flags '("CC=gcc" "RM=rm" "SHELL=sh" "all")
; #:phases (modify-phases %standard-phases (delete 'configure))
; ))
""".format(metadata["name"], metadata["build-system"])
print(manufacture_pkgdef(add_hash(metadata)))
#print(manufacture_pkgdef(metadata))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment