Skip to content

Instantly share code, notes, and snippets.

@dotlambda
Last active January 30, 2018 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dotlambda/83e72cd47d797f6c25c442d6d61bdee7 to your computer and use it in GitHub Desktop.
Save dotlambda/83e72cd47d797f6c25c442d6d61bdee7 to your computer and use it in GitHub Desktop.
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p "python3.withPackages (ps: with ps; [ setuptools ])"
from urllib.request import urlopen
import subprocess
import json
import re
from pkg_resources import Requirement, RequirementParseError
PREFIX = '# homeassistant.components.'
PKG_SET = 'python3Packages'
def fetch_reqs(version='master'):
requirements = {}
with urlopen('https://github.com/home-assistant/home-assistant/raw/{}/requirements_all.txt'.format(version)) as response:
components = []
for line in response.read().decode().splitlines():
if line == '':
components = []
elif line[:len(PREFIX)] == PREFIX:
component = line[len(PREFIX):]
components.append(component)
if component not in requirements:
requirements[component] = []
elif line[0] != '#':
for component in components:
requirements[component].append(line)
return requirements
output = subprocess.check_output(['nix-env', '-f', '../../..', '-qa', '-A', PKG_SET, '--json'])
packages = json.loads(output)
def name_to_attr_path(req):
attr_paths = []
m = re.compile('python3\\.6-{}-\\d'.format(req))
for attr_path, package in packages.items():
if m.match(package['name']):
attr_paths.append(attr_path)
assert(len(attr_paths) <= 1)
if attr_paths:
return attr_paths[0]
else:
return None
requirements = fetch_reqs()
build_inputs = {}
for component, reqs in requirements.items():
attr_paths = []
for req in reqs:
try:
name = Requirement.parse(req).project_name
attr_path = name_to_attr_path(name)
if attr_path is not None:
# Add attribute path without "python3Packages." prefix
attr_paths.append(attr_path[len(PKG_SET + '.'):])
except RequirementParseError:
continue
else:
build_inputs[component] = attr_paths
# Only select components which have any dependency
build_inputs = {k: v for k, v in build_inputs.items() if len(v) > 0}
with open('component-packages.nix', 'w') as f:
f.write('[\n')
for component, attr_paths in build_inputs.items():
f.write(' {\n')
f.write(' attrPath = [ "')
f.write('" "'.join(component.split('.')))
f.write('" ];\n')
f.write(' extraPackages = ps: with ps; [ ')
f.write(' '.join(attr_paths))
f.write(' ];\n')
f.write(' }\n')
f.write(']')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment