Created
February 17, 2018 19:51
-
-
Save pkillnine/56dcb44f7c3a5c60c4cdf52854712703 to your computer and use it in GitHub Desktop.
guix package-description generator (WIP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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