2015-11-17 08:18:42 +00:00
|
|
|
#!/usr/bin/env python3
|
2016-03-09 10:15:04 +00:00
|
|
|
"""Generate an updated requirements_all.txt."""
|
2015-11-17 08:18:42 +00:00
|
|
|
import importlib
|
|
|
|
import os
|
2019-04-13 20:17:01 +00:00
|
|
|
import pathlib
|
2015-11-17 08:18:42 +00:00
|
|
|
import pkgutil
|
|
|
|
import re
|
2015-12-18 07:51:34 +00:00
|
|
|
import sys
|
2015-11-17 08:18:42 +00:00
|
|
|
|
2019-04-13 20:17:01 +00:00
|
|
|
from script.hassfest.model import Integration
|
2019-04-05 04:29:29 +00:00
|
|
|
|
2016-07-02 18:22:51 +00:00
|
|
|
COMMENT_REQUIREMENTS = (
|
2019-07-31 19:25:30 +00:00
|
|
|
"Adafruit-DHT",
|
|
|
|
"Adafruit_BBIO",
|
|
|
|
"avion",
|
|
|
|
"beacontools",
|
|
|
|
"blinkt",
|
|
|
|
"bluepy",
|
|
|
|
"bme680",
|
|
|
|
"credstash",
|
|
|
|
"decora",
|
|
|
|
"envirophat",
|
|
|
|
"evdev",
|
|
|
|
"face_recognition",
|
|
|
|
"fritzconnection",
|
|
|
|
"i2csense",
|
|
|
|
"opencv-python-headless",
|
|
|
|
"py_noaa",
|
|
|
|
"VL53L1X2",
|
|
|
|
"pybluez",
|
|
|
|
"pycups",
|
|
|
|
"PySwitchbot",
|
|
|
|
"pySwitchmate",
|
|
|
|
"python-eq3bt",
|
|
|
|
"python-lirc",
|
|
|
|
"pyuserinput",
|
|
|
|
"raspihats",
|
|
|
|
"rpi-rf",
|
|
|
|
"RPi.GPIO",
|
|
|
|
"smbus-cffi",
|
2016-07-02 18:22:51 +00:00
|
|
|
)
|
|
|
|
|
2017-05-07 05:37:31 +00:00
|
|
|
TEST_REQUIREMENTS = (
|
2019-07-31 19:25:30 +00:00
|
|
|
"adguardhome",
|
|
|
|
"ambiclimate",
|
|
|
|
"aioambient",
|
|
|
|
"aioautomatic",
|
|
|
|
"aiobotocore",
|
|
|
|
"aioesphomeapi",
|
|
|
|
"aiohttp_cors",
|
|
|
|
"aiohue",
|
|
|
|
"aionotion",
|
|
|
|
"aiounifi",
|
|
|
|
"aioswitcher",
|
|
|
|
"aiowwlln",
|
|
|
|
"apns2",
|
|
|
|
"aprslib",
|
|
|
|
"av",
|
|
|
|
"axis",
|
|
|
|
"caldav",
|
|
|
|
"coinmarketcap",
|
|
|
|
"defusedxml",
|
|
|
|
"dsmr_parser",
|
|
|
|
"eebrightbox",
|
|
|
|
"emulated_roku",
|
|
|
|
"enocean",
|
|
|
|
"ephem",
|
|
|
|
"evohomeclient",
|
|
|
|
"feedparser-homeassistant",
|
|
|
|
"foobot_async",
|
|
|
|
"geojson_client",
|
|
|
|
"geopy",
|
|
|
|
"georss_generic_client",
|
|
|
|
"georss_ign_sismologia_client",
|
|
|
|
"georss_qld_bushfire_alert_client",
|
|
|
|
"google-api-python-client",
|
|
|
|
"gTTS-token",
|
|
|
|
"ha-ffmpeg",
|
|
|
|
"hangups",
|
|
|
|
"HAP-python",
|
|
|
|
"hass-nabucasa",
|
|
|
|
"haversine",
|
|
|
|
"hbmqtt",
|
|
|
|
"hdate",
|
|
|
|
"holidays",
|
|
|
|
"home-assistant-frontend",
|
|
|
|
"homekit[IP]",
|
|
|
|
"homematicip",
|
|
|
|
"httplib2",
|
|
|
|
"huawei-lte-api",
|
|
|
|
"influxdb",
|
|
|
|
"jsonpath",
|
|
|
|
"libpurecool",
|
|
|
|
"libsoundtouch",
|
|
|
|
"luftdaten",
|
|
|
|
"pyMetno",
|
|
|
|
"mbddns",
|
|
|
|
"mficlient",
|
|
|
|
"netdisco",
|
|
|
|
"numpy",
|
|
|
|
"oauth2client",
|
|
|
|
"paho-mqtt",
|
|
|
|
"pexpect",
|
|
|
|
"pilight",
|
|
|
|
"pmsensor",
|
|
|
|
"prometheus_client",
|
|
|
|
"ptvsd",
|
|
|
|
"pushbullet.py",
|
|
|
|
"py-canary",
|
|
|
|
"pyblackbird",
|
|
|
|
"pydeconz",
|
|
|
|
"pydispatcher",
|
|
|
|
"pyheos",
|
|
|
|
"pyhomematic",
|
|
|
|
"pyiqvia",
|
|
|
|
"pylitejet",
|
|
|
|
"pymfy",
|
|
|
|
"pymonoprice",
|
|
|
|
"pynx584",
|
|
|
|
"pyopenuv",
|
|
|
|
"pyotp",
|
|
|
|
"pyps4-homeassistant",
|
|
|
|
"pysmartapp",
|
|
|
|
"pysmartthings",
|
|
|
|
"pysonos",
|
|
|
|
"pyqwikswitch",
|
|
|
|
"PyRMVtransport",
|
|
|
|
"PyTransportNSW",
|
|
|
|
"pyspcwebgw",
|
|
|
|
"python-forecastio",
|
|
|
|
"python-nest",
|
|
|
|
"python_awair",
|
|
|
|
"python-velbus",
|
|
|
|
"pytradfri[async]",
|
|
|
|
"pyunifi",
|
|
|
|
"pyupnp-async",
|
|
|
|
"pyvesync",
|
|
|
|
"pywebpush",
|
|
|
|
"pyHS100",
|
|
|
|
"PyNaCl",
|
|
|
|
"regenmaschine",
|
|
|
|
"restrictedpython",
|
|
|
|
"rflink",
|
|
|
|
"ring_doorbell",
|
|
|
|
"rxv",
|
|
|
|
"simplisafe-python",
|
|
|
|
"sleepyq",
|
|
|
|
"smhi-pkg",
|
|
|
|
"somecomfort",
|
|
|
|
"sqlalchemy",
|
|
|
|
"srpenergy",
|
|
|
|
"statsd",
|
|
|
|
"toonapilib",
|
|
|
|
"twentemilieu",
|
|
|
|
"uvcclient",
|
|
|
|
"vsure",
|
|
|
|
"warrant",
|
|
|
|
"pythonwhois",
|
|
|
|
"wakeonlan",
|
|
|
|
"vultr",
|
|
|
|
"YesssSMS",
|
|
|
|
"ruamel.yaml",
|
|
|
|
"zeroconf",
|
|
|
|
"zigpy-homeassistant",
|
|
|
|
"bellows-homeassistant",
|
|
|
|
"py17track",
|
2017-05-07 05:37:31 +00:00
|
|
|
)
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
IGNORE_PIN = ("colorlog>2.1,<3", "keyring>=9.3,<10.0", "urllib3")
|
2017-01-21 23:31:10 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
IGNORE_REQ = ("colorama<=1",) # Windows only requirement in check_config
|
2017-03-12 19:08:49 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
URL_PIN = (
|
|
|
|
"https://developers.home-assistant.io/docs/"
|
|
|
|
"creating_platform_code_review.html#1-requirements"
|
|
|
|
)
|
2017-01-22 16:34:00 +00:00
|
|
|
|
2015-11-17 08:18:42 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
CONSTRAINT_PATH = os.path.join(
|
|
|
|
os.path.dirname(__file__), "../homeassistant/package_constraints.txt"
|
|
|
|
)
|
2017-08-05 06:06:10 +00:00
|
|
|
CONSTRAINT_BASE = """
|
2018-08-28 10:49:50 +00:00
|
|
|
pycryptodome>=3.6.6
|
|
|
|
|
2018-02-20 07:10:44 +00:00
|
|
|
# Breaks Python 3.6 and is not needed for our supported Python versions
|
2017-08-05 06:06:10 +00:00
|
|
|
enum34==1000000000.0.0
|
2018-02-27 09:58:45 +00:00
|
|
|
|
|
|
|
# This is a old unmaintained library and is replaced with pycryptodome
|
|
|
|
pycrypto==1000000000.0.0
|
2018-11-16 13:28:39 +00:00
|
|
|
|
|
|
|
# Contains code to modify Home Assistant to work around our rules
|
|
|
|
python-systemair-savecair==1000000000.0.0
|
2017-08-05 06:06:10 +00:00
|
|
|
"""
|
2017-03-22 15:50:54 +00:00
|
|
|
|
|
|
|
|
2015-11-17 08:18:42 +00:00
|
|
|
def explore_module(package, explore_children):
|
2016-03-09 10:15:04 +00:00
|
|
|
"""Explore the modules."""
|
2015-11-17 08:18:42 +00:00
|
|
|
module = importlib.import_module(package)
|
|
|
|
|
|
|
|
found = []
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
if not hasattr(module, "__path__"):
|
2015-11-17 08:18:42 +00:00
|
|
|
return found
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
for _, name, _ in pkgutil.iter_modules(module.__path__, package + "."):
|
2015-11-17 08:18:42 +00:00
|
|
|
found.append(name)
|
|
|
|
|
|
|
|
if explore_children:
|
|
|
|
found.extend(explore_module(name, False))
|
|
|
|
|
|
|
|
return found
|
|
|
|
|
|
|
|
|
|
|
|
def core_requirements():
|
2016-03-09 10:15:04 +00:00
|
|
|
"""Gather core requirements out of setup.py."""
|
2019-07-31 19:25:30 +00:00
|
|
|
with open("setup.py") as inp:
|
|
|
|
reqs_raw = re.search(r"REQUIRES = \[(.*?)\]", inp.read(), re.S).group(1)
|
2015-11-17 08:18:42 +00:00
|
|
|
return re.findall(r"'(.*?)'", reqs_raw)
|
|
|
|
|
|
|
|
|
2019-06-10 21:38:14 +00:00
|
|
|
def gather_recursive_requirements(domain, seen=None):
|
|
|
|
"""Recursively gather requirements from a module."""
|
|
|
|
if seen is None:
|
|
|
|
seen = set()
|
|
|
|
|
|
|
|
seen.add(domain)
|
2019-07-31 19:25:30 +00:00
|
|
|
integration = Integration(
|
|
|
|
pathlib.Path("homeassistant/components/{}".format(domain))
|
|
|
|
)
|
2019-06-10 21:38:14 +00:00
|
|
|
integration.load_manifest()
|
2019-07-31 19:25:30 +00:00
|
|
|
reqs = set(integration.manifest["requirements"])
|
|
|
|
for dep_domain in integration.manifest["dependencies"]:
|
2019-06-10 21:38:14 +00:00
|
|
|
reqs.update(gather_recursive_requirements(dep_domain, seen))
|
|
|
|
return reqs
|
|
|
|
|
|
|
|
|
2015-11-17 08:28:22 +00:00
|
|
|
def comment_requirement(req):
|
2018-08-24 08:28:43 +00:00
|
|
|
"""Comment out requirement. Some don't install on all systems."""
|
2015-11-17 08:28:22 +00:00
|
|
|
return any(ign in req for ign in COMMENT_REQUIREMENTS)
|
|
|
|
|
|
|
|
|
2015-11-25 22:31:04 +00:00
|
|
|
def gather_modules():
|
2017-05-07 05:37:31 +00:00
|
|
|
"""Collect the information."""
|
2016-02-01 07:52:42 +00:00
|
|
|
reqs = {}
|
2015-11-17 08:18:42 +00:00
|
|
|
|
|
|
|
errors = []
|
2015-11-25 22:31:04 +00:00
|
|
|
|
2019-04-13 20:17:01 +00:00
|
|
|
gather_requirements_from_manifests(errors, reqs)
|
2019-04-05 04:29:29 +00:00
|
|
|
gather_requirements_from_modules(errors, reqs)
|
|
|
|
|
|
|
|
for key in reqs:
|
2019-07-31 19:25:30 +00:00
|
|
|
reqs[key] = sorted(reqs[key], key=lambda name: (len(name.split(".")), name))
|
2019-04-05 04:29:29 +00:00
|
|
|
|
|
|
|
if errors:
|
|
|
|
print("******* ERROR")
|
2019-07-31 19:25:30 +00:00
|
|
|
print("Errors while importing: ", ", ".join(errors))
|
2019-04-05 04:29:29 +00:00
|
|
|
return None
|
|
|
|
|
|
|
|
return reqs
|
|
|
|
|
|
|
|
|
2019-04-13 20:17:01 +00:00
|
|
|
def gather_requirements_from_manifests(errors, reqs):
|
|
|
|
"""Gather all of the requirements from manifests."""
|
2019-07-31 19:25:30 +00:00
|
|
|
integrations = Integration.load_dir(pathlib.Path("homeassistant/components"))
|
2019-04-13 20:17:01 +00:00
|
|
|
for domain in sorted(integrations):
|
|
|
|
integration = integrations[domain]
|
|
|
|
|
|
|
|
if not integration.manifest:
|
2019-07-31 19:25:30 +00:00
|
|
|
errors.append("The manifest for integration {} is invalid.".format(domain))
|
2019-04-13 20:17:01 +00:00
|
|
|
continue
|
|
|
|
|
|
|
|
process_requirements(
|
|
|
|
errors,
|
2019-07-31 19:25:30 +00:00
|
|
|
integration.manifest["requirements"],
|
|
|
|
"homeassistant.components.{}".format(domain),
|
|
|
|
reqs,
|
2019-04-13 20:17:01 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-04-05 04:29:29 +00:00
|
|
|
def gather_requirements_from_modules(errors, reqs):
|
|
|
|
"""Collect the requirements from the modules directly."""
|
2018-08-22 07:52:34 +00:00
|
|
|
for package in sorted(
|
2019-07-31 19:25:30 +00:00
|
|
|
explore_module("homeassistant.scripts", True)
|
|
|
|
+ explore_module("homeassistant.auth", True)
|
|
|
|
):
|
2015-11-17 08:18:42 +00:00
|
|
|
try:
|
|
|
|
module = importlib.import_module(package)
|
2019-03-17 03:44:05 +00:00
|
|
|
except ImportError as err:
|
2019-07-31 19:25:30 +00:00
|
|
|
print("{}: {}".format(package.replace(".", "/") + ".py", err))
|
2019-06-10 21:38:14 +00:00
|
|
|
errors.append(package)
|
2015-11-17 08:18:42 +00:00
|
|
|
continue
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
if getattr(module, "REQUIREMENTS", None):
|
2019-04-05 04:29:29 +00:00
|
|
|
process_requirements(errors, module.REQUIREMENTS, package, reqs)
|
2016-02-01 07:52:42 +00:00
|
|
|
|
2015-11-17 08:18:42 +00:00
|
|
|
|
2019-04-05 04:29:29 +00:00
|
|
|
def process_requirements(errors, module_requirements, package, reqs):
|
|
|
|
"""Process all of the requirements."""
|
|
|
|
for req in module_requirements:
|
|
|
|
if req in IGNORE_REQ:
|
|
|
|
continue
|
2019-07-31 19:25:30 +00:00
|
|
|
if "://" in req:
|
2019-04-05 04:29:29 +00:00
|
|
|
errors.append(
|
2019-07-31 19:25:30 +00:00
|
|
|
"{}[Only pypi dependencies are allowed: {}]".format(package, req)
|
|
|
|
)
|
|
|
|
if req.partition("==")[1] == "" and req not in IGNORE_PIN:
|
2019-04-05 04:29:29 +00:00
|
|
|
errors.append(
|
2019-07-31 19:25:30 +00:00
|
|
|
"{}[Please pin requirement {}, see {}]".format(package, req, URL_PIN)
|
|
|
|
)
|
2019-04-05 04:29:29 +00:00
|
|
|
reqs.setdefault(req, []).append(package)
|
2017-05-07 05:37:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
def generate_requirements_list(reqs):
|
|
|
|
"""Generate a pip file based on requirements."""
|
|
|
|
output = []
|
2016-02-01 07:52:42 +00:00
|
|
|
for pkg, requirements in sorted(reqs.items(), key=lambda item: item[0]):
|
2019-04-05 04:29:29 +00:00
|
|
|
for req in sorted(requirements):
|
2019-07-31 19:25:30 +00:00
|
|
|
output.append("\n# {}".format(req))
|
2015-11-17 08:28:22 +00:00
|
|
|
|
|
|
|
if comment_requirement(pkg):
|
2019-07-31 19:25:30 +00:00
|
|
|
output.append("\n# {}\n".format(pkg))
|
2015-11-17 08:28:22 +00:00
|
|
|
else:
|
2019-07-31 19:25:30 +00:00
|
|
|
output.append("\n{}\n".format(pkg))
|
|
|
|
return "".join(output)
|
2017-05-07 05:37:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
def requirements_all_output(reqs):
|
|
|
|
"""Generate output for requirements_all."""
|
|
|
|
output = []
|
2019-07-31 19:25:30 +00:00
|
|
|
output.append("# Home Assistant core")
|
|
|
|
output.append("\n")
|
|
|
|
output.append("\n".join(core_requirements()))
|
|
|
|
output.append("\n")
|
2017-05-07 05:37:31 +00:00
|
|
|
output.append(generate_requirements_list(reqs))
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
return "".join(output)
|
2017-05-07 05:37:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
def requirements_test_output(reqs):
|
|
|
|
"""Generate output for test_requirements."""
|
|
|
|
output = []
|
2019-07-31 19:25:30 +00:00
|
|
|
output.append("# Home Assistant test")
|
|
|
|
output.append("\n")
|
|
|
|
with open("requirements_test.txt") as test_file:
|
2017-10-09 03:49:51 +00:00
|
|
|
output.append(test_file.read())
|
2019-07-31 19:25:30 +00:00
|
|
|
output.append("\n")
|
|
|
|
filtered = {
|
|
|
|
key: value
|
|
|
|
for key, value in reqs.items()
|
|
|
|
if any(
|
|
|
|
re.search(r"(^|#){}($|[=><])".format(re.escape(ign)), key) is not None
|
|
|
|
for ign in TEST_REQUIREMENTS
|
|
|
|
)
|
|
|
|
}
|
2017-05-07 05:37:31 +00:00
|
|
|
output.append(generate_requirements_list(filtered))
|
2015-11-25 22:31:04 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
return "".join(output)
|
2015-11-25 22:31:04 +00:00
|
|
|
|
|
|
|
|
2017-03-22 15:50:54 +00:00
|
|
|
def gather_constraints():
|
|
|
|
"""Construct output for constraint file."""
|
2019-07-31 19:25:30 +00:00
|
|
|
return "\n".join(
|
|
|
|
sorted(
|
|
|
|
core_requirements() + list(gather_recursive_requirements("default_config"))
|
|
|
|
)
|
|
|
|
+ [""]
|
|
|
|
)
|
2017-03-22 15:50:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
def write_requirements_file(data):
|
2016-03-09 10:15:04 +00:00
|
|
|
"""Write the modules to the requirements_all.txt."""
|
2019-07-31 19:25:30 +00:00
|
|
|
with open("requirements_all.txt", "w+", newline="\n") as req_file:
|
2015-11-25 22:31:04 +00:00
|
|
|
req_file.write(data)
|
|
|
|
|
|
|
|
|
2017-05-07 05:37:31 +00:00
|
|
|
def write_test_requirements_file(data):
|
2018-07-18 10:16:27 +00:00
|
|
|
"""Write the modules to the requirements_test_all.txt."""
|
2019-07-31 19:25:30 +00:00
|
|
|
with open("requirements_test_all.txt", "w+", newline="\n") as req_file:
|
2017-05-07 05:37:31 +00:00
|
|
|
req_file.write(data)
|
|
|
|
|
|
|
|
|
2017-03-22 15:50:54 +00:00
|
|
|
def write_constraints_file(data):
|
|
|
|
"""Write constraints to a file."""
|
2019-07-31 19:25:30 +00:00
|
|
|
with open(CONSTRAINT_PATH, "w+", newline="\n") as req_file:
|
2017-08-05 06:06:10 +00:00
|
|
|
req_file.write(data + CONSTRAINT_BASE)
|
2017-03-22 15:50:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
def validate_requirements_file(data):
|
2016-03-09 10:15:04 +00:00
|
|
|
"""Validate if requirements_all.txt is up to date."""
|
2019-07-31 19:25:30 +00:00
|
|
|
with open("requirements_all.txt", "r") as req_file:
|
2017-08-05 06:06:10 +00:00
|
|
|
return data == req_file.read()
|
2015-12-18 07:51:34 +00:00
|
|
|
|
|
|
|
|
2017-05-07 05:37:31 +00:00
|
|
|
def validate_requirements_test_file(data):
|
2018-07-18 10:16:27 +00:00
|
|
|
"""Validate if requirements_test_all.txt is up to date."""
|
2019-07-31 19:25:30 +00:00
|
|
|
with open("requirements_test_all.txt", "r") as req_file:
|
2017-08-05 06:06:10 +00:00
|
|
|
return data == req_file.read()
|
2017-05-07 05:37:31 +00:00
|
|
|
|
|
|
|
|
2017-03-22 15:50:54 +00:00
|
|
|
def validate_constraints_file(data):
|
|
|
|
"""Validate if constraints is up to date."""
|
2019-07-31 19:25:30 +00:00
|
|
|
with open(CONSTRAINT_PATH, "r") as req_file:
|
2017-08-05 06:06:10 +00:00
|
|
|
return data + CONSTRAINT_BASE == req_file.read()
|
2017-03-22 15:50:54 +00:00
|
|
|
|
|
|
|
|
2018-03-09 20:27:39 +00:00
|
|
|
def main(validate):
|
2018-08-24 08:28:43 +00:00
|
|
|
"""Run the script."""
|
2019-07-31 19:25:30 +00:00
|
|
|
if not os.path.isfile("requirements_all.txt"):
|
|
|
|
print("Run this from HA root dir")
|
2018-03-09 20:27:39 +00:00
|
|
|
return 1
|
2015-11-29 21:55:46 +00:00
|
|
|
|
2015-11-25 22:31:04 +00:00
|
|
|
data = gather_modules()
|
|
|
|
|
2015-11-29 21:55:46 +00:00
|
|
|
if data is None:
|
2018-03-09 20:27:39 +00:00
|
|
|
return 1
|
2015-12-18 07:51:34 +00:00
|
|
|
|
2017-03-22 15:50:54 +00:00
|
|
|
constraints = gather_constraints()
|
2015-11-29 21:55:46 +00:00
|
|
|
|
2017-05-07 05:37:31 +00:00
|
|
|
reqs_file = requirements_all_output(data)
|
|
|
|
reqs_test_file = requirements_test_output(data)
|
|
|
|
|
2018-03-09 20:27:39 +00:00
|
|
|
if validate:
|
2017-05-07 05:37:31 +00:00
|
|
|
errors = []
|
|
|
|
if not validate_requirements_file(reqs_file):
|
|
|
|
errors.append("requirements_all.txt is not up to date")
|
|
|
|
|
|
|
|
if not validate_requirements_test_file(reqs_test_file):
|
|
|
|
errors.append("requirements_test_all.txt is not up to date")
|
2017-03-22 15:50:54 +00:00
|
|
|
|
|
|
|
if not validate_constraints_file(constraints):
|
2019-07-31 19:25:30 +00:00
|
|
|
errors.append("home-assistant/package_constraints.txt is not up to date")
|
2017-05-07 05:37:31 +00:00
|
|
|
|
|
|
|
if errors:
|
2017-03-22 15:50:54 +00:00
|
|
|
print("******* ERROR")
|
2019-07-31 19:25:30 +00:00
|
|
|
print("\n".join(errors))
|
2017-03-22 15:50:54 +00:00
|
|
|
print("Please run script/gen_requirements_all.py")
|
2018-03-09 20:27:39 +00:00
|
|
|
return 1
|
2017-03-22 15:50:54 +00:00
|
|
|
|
2018-03-09 20:27:39 +00:00
|
|
|
return 0
|
2017-03-22 15:50:54 +00:00
|
|
|
|
2017-05-07 05:37:31 +00:00
|
|
|
write_requirements_file(reqs_file)
|
|
|
|
write_test_requirements_file(reqs_test_file)
|
2017-03-22 15:50:54 +00:00
|
|
|
write_constraints_file(constraints)
|
2018-03-09 20:27:39 +00:00
|
|
|
return 0
|
2015-11-17 08:18:42 +00:00
|
|
|
|
2016-11-19 05:47:59 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
if __name__ == "__main__":
|
|
|
|
_VAL = sys.argv[-1] == "validate"
|
2018-03-09 20:27:39 +00:00
|
|
|
sys.exit(main(_VAL))
|