Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add version-listing tool #1

Merged
merged 4 commits into from
Apr 20, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
109 changes: 109 additions & 0 deletions impactlab_tools/os/versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import subprocess as sp

def check_version(input_list, check_git=False):
"""
Returns version information given a list of module dependencies

Parameters
----------

input_list: list
list of strings, all module names

check_git: bool
True if the caller also wants to check the git hash of a repo
(input_list contains its name) that's under the user's home dir.

Returns
-------

dict:
A dictionary of the modules: keys are the module names, each
key has value of another dictionary, containing:
- "source": how is the module installed ("pip", "local",
"git", or None):
- source is "pip" if it's an open-sourced python
package installed through pip.
- source is "pip-local" if it's a self-made tool
installed through pip.
- source is "git" if it's a git managed repo of
scripts, not installed through pip.
- source is None if the module cannot be found.
- "version": If it's an open source module (source: pip),
this is the version numbers of it.
- "git_hash": If it's a local module (source: local, or
git).

Example
-------

>>> input_list = [
... "scipy", "numpy", "Cheetah", "computer",
... "impact-calculations", "metacsv"]
...
>>> check_version(input_list, check_git=True) # doctest: +SKIP
{
"scipy": {"source": "pip", "version": "0.19"},
"numpy": {"source": "pip", "version": "1.12.1"},
"Cheetah": {"source": "pip", "version": "2.4.4"},
"computer": {
"source": "git",
"git_hash": "662870e0fa914b4fa958e78ebe02b858c31fe41d"},
"impact-calculations": {
"source": "git",
"git_hash": "e7c1b53b1d9e6571c0555a560c919f9645693b45"},
"metacsv": {"source": "pip", "version": "0.0.9"}
}

"""
# Read in all packages in pips
pips = sp.check_output("pip freeze", shell=True).split("\n")[:-1]
modules = {}
for mod in pips:
if ".git@" in mod:
# Assume the format of a local repo in pip freeze looks
# like this:
#
# "-e git+https://github.com/<UserName>/
# <RepoName>.git@<Git_Hash>#egg=computer-master"
#
# We are interested in the <Git_Hash> part, saving in
# the modules dictionary with <RepoName> as the key.
ind = mod.index(".git@")
end = mod.index("#")
modules[mod[:ind].split("/")[-1]] = mod[ind+5:end]
else:
ind = mod.index("=")
modules[mod[:ind]] = mod[ind:].rstrip("\n").lstrip("=")

# Read in all repos under my home directory
repos = sp.check_output(
"find ~/ -name '.git'", shell=True).split(".git\n")[:-1]

git = {}
for repo in repos:
name = repo.split("/")[-2]
git[name] = sp.check_output(
"cd " + repo + " && git log --format='%H' -n 1",
shell=True).rstrip("\n")

# Iterate through the input_list and find if the target is in
# either the modules or the git dictionary, or not at all.
rtDict = {}
for tgt in input_list:
info = {}
if tgt in modules:
if "." in modules[tgt]:
info["source"] = "pip"
info["version"] = modules[tgt]
else:
info["source"] = "pip-local"
info["git_hash"] = modules[tgt]
elif tgt in git:
info["source"] = "git"
info["git_hash"] = git[tgt]
else:
info["source"] = None
rtDict[tgt] = info

return rtDict