Skip to content

Commit

Permalink
sha parsing in place
Browse files Browse the repository at this point in the history
  • Loading branch information
dham committed Feb 17, 2016
1 parent eea91ac commit 06085f5
Showing 1 changed file with 131 additions and 0 deletions.
131 changes: 131 additions & 0 deletions scripts/firedrake-zenodo
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#! /usr/bin/env python
import logging
import sys
import os
import subprocess
from argparse import ArgumentParser, RawDescriptionHelpFormatter
from collections import OrderedDict
import json

descriptions = OrderedDict(
firedrake="Firedrake: an automated finite element system",
PyOP2="PyOP2: Framework for performance-portable parallel computations on unstructured meshes",
tsfc="TSFC: The Two Stage Form Compiler",
COFFEE="COFFEE: A Compiler for Fast Expression Evaluation",
ufl="UFL: The Unified Form Language",
fiat="FIAT: The Finite Element Automated Tabulator",
petsc="PETSc: Portable, Extensible Toolkit for Scientific Computation",
petsc4py="PETSc4py: The Python interface to PETSc")

components = descriptions.keys()

parser = ArgumentParser(description="""Create Zenodo DOIs for specific versions of Firedrake components.
If you are a Firedrake user, this script creates a JSON file encoding
the precise versions of all the Firedrake components you are using,
and a documentation string. You should create an issue on the
Firedrake github page and attach this file. The Firedrake core
developers will generate DOIs for your packages and report them back
to you.
If you are a Firedrake core developer, this script enables you to
create DOIs directly, or to create them from a user-supplied JSON file.""",
epilog="""""",
formatter_class=RawDescriptionHelpFormatter)
group = parser.add_mutually_exclusive_group()
group.add_argument("--output", "-o", action="store", nargs=1, default=["firedrake.json"],
help="Output to the named file instead of firedrake.json.")
group.add_argument("--input", "-i", action="store", nargs=1,
help="Release based on the named input file")
group.add_argument("--release", action="store_true",
help="Release based on the current checked out versions.")

for component in components:
parser.add_argument("--%s" % component, action="store", nargs=1,
help="Use this git hash for %s instead of that in the file or the checked out version."
% component)

parser.add_argument("--log", action='store_true',
help="Produce a verbose log of the installation process in firedrake-zenodo.log. If you have problem running this script, please include this log in any bug report you file.")


args = parser.parse_args()

cwd = os.getcwd()
src = os.path.dirname(__file__) + "/../src"

# Set up logging
if args.log:
# Log to file at DEBUG level
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(levelname)-6s %(message)s',
filename='firedrake-zenodo.log',
filemode='w')
# Log to console at INFO level
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(message)s')
console.setFormatter(formatter)
logging.getLogger().addHandler(console)
else:
# Log to console at INFO level
logging.basicConfig(level=logging.INFO,
format='%(message)s')
log = logging.getLogger()


def check_call(arguments):
if args.log:
try:
log.debug(subprocess.check_output(arguments, stderr=subprocess.STDOUT))
except subprocess.CalledProcessError as e:
log.debug(e.output)
raise
else:
subprocess.check_call(arguments)


def check_output(args):
try:
return subprocess.check_output(args, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
log.debug(e.output)
raise


def collect_repo_shas():
shas = {}

for component in components:
try:
os.chdir(src + "/" + component)
shas[component] = check_output(["git", "rev-parse", "HEAD"]).strip()

This comment has been minimized.

Copy link
@wence-

wence- Feb 18, 2016

Contributor

I would add, before this line:

try:
    check_call(["git", "diff-index", "--quiet", "HEAD"])
except subprocess.CalledProcessError:
    log.error("Component %s has uncommitted changes, cannot create release" % component)
    sys.exit(0)

To stop people from attempting to create releases from dirty trees.

This comment has been minimized.

Copy link
@dham

dham Feb 18, 2016

Author Member

Nice. Yes. Is there also a way to prevent them specifying a sha which does not exist on origin?

This comment has been minimized.

Copy link
@wence-

wence- Feb 18, 2016

Contributor

I can check if they don't exist on any remote, but I don't want to do the parsing to check if those remotes are actually upstream. That would look something like:

contains = check_output(["git", "for-each-ref", "--contains", "HEAD", "refs/remotes", "--format=%(objectname)"]).strip()
if len(contains) == 0:
    log.error("Component %s has changes that are not upstream, cannot create release" % component)
    sys.exit(0)
except:
log.error("Failed to retrieve git hash for %s" % component)
raise
return shas

if args.release or not args.input:
# Collect hashes from the current repo.
shas = collect_repo_shas()
else:
# Read hashes from file.
infile = file(cwd+"/"+args.input[0], "r")
shas = json.loads(infile.read())

# Override hashes with any read from the command line.
for component in components:
new_sha = getattr(args, component)
if new_sha:
shas[component] = new_sha[0]

if not (args.release or args.input):
# Dump json and exit.
out = file(cwd+"/"+args.output[0], "w")
out.write(json.dumps(shas) + "\n")

log.info("Wrote release information to %s" % args.output[0])
sys.exit(0)

# Now create releases.
print shas

0 comments on commit 06085f5

Please sign in to comment.