forked from cockpit-project/bots
-
Notifications
You must be signed in to change notification settings - Fork 0
/
npm-update
executable file
·146 lines (114 loc) · 4.6 KB
/
npm-update
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env python3
# 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",
"angular",
"angular-route",
]
import collections
import json
import os
import random
import sys
import subprocess
sys.dont_write_bytecode = True
import task
from machine.machine_core.directories import BASE_DIR
def package_json(data=None, package=None, version=None):
package_path = os.path.join(BASE_DIR, "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_DIR)
def output(*args):
if task.verbose:
sys.stderr.write("+ " + " ".join(args) + "\n")
return subprocess.check_output(args, cwd=BASE_DIR, 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)
if not kwargs["dry"]:
# 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
else:
# in dry mode, still only update one dep, so that updates can be tested one by one
break
# Undo our changes
if not kwargs["dry"]:
package_json(orig_package_json)
if __name__ == '__main__':
task.main(function=run, title="Upgrade a node dependency")