138 lines
4.4 KiB
Python
Executable File
138 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# This file is part of Cockpit.
|
|
#
|
|
# Copyright (C) 2017 Red Hat, Inc.
|
|
#
|
|
# Cockpit is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU Lesser General Public License as published by
|
|
# the Free Software Foundation; either version 2.1 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Cockpit is distributed in the hope that it will be useful, but
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# To use this example add a line to an issue with the "bot" label
|
|
#
|
|
# * [ ] npm-update patternfly
|
|
#
|
|
|
|
# Dependencies that are either fragile (minor updates break)
|
|
# or are part of our public Javascript API and need caution
|
|
FRAGILE = [
|
|
"jquery",
|
|
"patternfly",
|
|
"paternfly-bootstrap-combobox",
|
|
# version 0.32.2 switches to babel 7, which causes build failures with our babel 6 build system
|
|
"react-bootstrap",
|
|
]
|
|
|
|
import collections
|
|
import json
|
|
import os
|
|
import random
|
|
import sys
|
|
import subprocess
|
|
|
|
sys.dont_write_bytecode = True
|
|
|
|
import task
|
|
|
|
BOTS = os.path.abspath(os.path.dirname(__file__))
|
|
BASE = os.path.normpath(os.path.join(BOTS, ".."))
|
|
|
|
def package_json(data=None, package=None, version=None):
|
|
package_path = os.path.join(BASE, "package.json")
|
|
if data is None:
|
|
with open(package_path, "r") as f:
|
|
return json.load(f, object_pairs_hook=collections.OrderedDict)
|
|
else:
|
|
if package:
|
|
data = dict(data, dependencies=dict(data["dependencies"], **{ package: version }))
|
|
with open(package_path, "w") as f:
|
|
json.dump(data, f, indent=2, separators=(',', ': '))
|
|
f.write("\n")
|
|
|
|
def map_dict(dependencies, function):
|
|
items = [ ]
|
|
for (name, value) in dependencies.items():
|
|
items.append((name, function(name, value)))
|
|
return collections.OrderedDict(items)
|
|
|
|
def execute(*args):
|
|
if task.verbose:
|
|
sys.stderr.write("+ " + " ".join(args) + "\n")
|
|
subprocess.check_call(args, cwd=BASE)
|
|
|
|
def output(*args):
|
|
if task.verbose:
|
|
sys.stderr.write("+ " + " ".join(args) + "\n")
|
|
return subprocess.check_output(args, cwd=BASE, universal_newlines=True)
|
|
|
|
def run(specified_package, verbose=False, **kwargs):
|
|
# Force all current dependencies in place
|
|
execute("npm", "install")
|
|
|
|
orig_package_json = package_json()
|
|
|
|
if specified_package:
|
|
packages = [ specified_package ]
|
|
else:
|
|
packages = list(orig_package_json["dependencies"].keys())
|
|
random.shuffle(packages)
|
|
|
|
def prefix(name, version):
|
|
if not version[0].isdigit():
|
|
return version
|
|
if name == specified_package or name not in FRAGILE:
|
|
return "^" + version
|
|
return "~" + version
|
|
|
|
for package in packages:
|
|
|
|
orig_version = orig_package_json["dependencies"][package]
|
|
upgradeable_version = prefix(package, orig_version)
|
|
|
|
if orig_version == upgradeable_version:
|
|
continue
|
|
|
|
# Run npm upgrade for our package
|
|
#
|
|
package_json(orig_package_json, package, upgradeable_version)
|
|
execute("npm", "upgrade", "--save", package)
|
|
|
|
# Check if that did an upgrade
|
|
new_version = package_json()["dependencies"][package].lstrip("^~")
|
|
|
|
if new_version != orig_version:
|
|
|
|
# Write out the original package.json with the updated version
|
|
package_json(orig_package_json, package, new_version)
|
|
|
|
# Create a pull request from these changes
|
|
title = "package.json: Update {0} package dependency".format(package)
|
|
branch = task.branch(package, title, pathspec="package.json", **kwargs)
|
|
|
|
# List of files that probably touch this package
|
|
lines = output("git", "grep", "-w", package)
|
|
comment = "Please manually check features related to these files:\n\n```\n{0}```".format(lines)
|
|
|
|
if branch:
|
|
kwargs["title"] = title
|
|
pull = task.pull(branch, **kwargs)
|
|
|
|
task.comment(pull, comment)
|
|
break
|
|
|
|
# Undo our changes
|
|
package_json(orig_package_json)
|
|
|
|
if __name__ == '__main__':
|
|
task.main(function=run, title="Upgrade a node dependency")
|