-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcommon.py
205 lines (141 loc) · 5.59 KB
/
common.py
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# -*- coding: utf-8 -*-"
"""Common functions and variables used by rebase scripts"""
import os
import sys
import re
import sqlite3
import subprocess
from config import datadir, rebasedb_name
from config import rebase_baseline_branch, rebase_target
from config import next_repo, stable_repo, android_repo
if datadir is None:
datadir = os.path.join(sys.path[0], 'data')
if rebasedb_name is None:
rebasedb_name = 'rebase-%s.db' % rebase_target
repodir = 'repositories'
chromeos_path = os.path.join(datadir, repodir, 'linux-chrome')
upstream_path = os.path.join(datadir, repodir, 'linux-upstream')
stable_path = os.path.join(datadir, repodir, 'linux-stable') if stable_repo else None
android_path = os.path.join(datadir, repodir, 'linux-android') if android_repo else None
next_path = os.path.join(datadir, repodir, 'linux-next') if next_repo else None
dbdir = os.path.join(datadir, 'database')
rebasedb = os.path.join(dbdir, rebasedb_name)
upstreamdb = os.path.join(dbdir, 'upstream.db')
nextdb = os.path.join(dbdir, 'next.db') if next_repo else None
def do_check_output(cmd):
"""Python version independent implementation of 'subprocess.check_output'"""
return subprocess.check_output(cmd, stderr=subprocess.DEVNULL, # pylint: disable=no-member
encoding='utf-8', errors='ignore')
def stable_baseline():
"""Return most recent label in to-be-rebased branch"""
cmd = ['git', '-C', chromeos_path, 'describe', rebase_baseline_branch]
tag = do_check_output(cmd)
return tag.split('-')[0]
def rebase_baseline():
"""Return most recent tag in to-be-rebased branch"""
baseline = stable_baseline()
if baseline:
return baseline.split('.')[0] + '.' + baseline.split('.')[1]
return None
version_re = re.compile(r'(v[0-9]+(\.[0-9]+)(-rc[0-9]+(-dontuse)?)?)\s*')
def rebase_target_tag():
"""Return most recent label in upstream kernel"""
if not os.path.exists(upstream_path):
return 'HEAD'
if rebase_target == 'latest':
cmd = ['git', '-C', upstream_path, 'describe']
tag = do_check_output(cmd)
v = version_re.match(tag)
if v:
tag = v.group(0).strip('\n')
else:
tag = 'HEAD'
else:
tag = rebase_target
return tag
def rebase_target_version():
"""Return target version for rebase"""
return rebase_target_tag().strip('v')
def stable_branch(version):
"""Return stable branch name in upstream stable kernel"""
return 'linux-%s.y' % version
def chromeos_branch(version):
"""Return chromeos branch name"""
return 'chromeos-%s' % version
def doremove(filename):
"""remove file if it exists"""
try:
os.remove(filename)
except OSError:
pass
def createdb(db, op):
"""remove and recreate database"""
dbdirname = os.path.dirname(db)
if not os.path.exists(dbdirname):
os.mkdir(dbdirname)
doremove(db)
conn = sqlite3.connect(db)
c = conn.cursor()
op(c)
# Convention: table 'tip' ref 1 contains the most recently processed SHA.
# Use this to avoid re-processing SHAs already in the database.
c.execute('CREATE TABLE tip (ref integer, sha text)')
c.execute('INSERT INTO tip (ref, sha) VALUES (?, ?)', (1, ''))
# Save (commit) the changes
conn.commit()
conn.close()
# match "vX.Y[.Z][.rcN]"
_version_re = re.compile(r'(v[0-9]+(?:\.[0-9]+)+(?:-rc[0-9]+(-dontuse)?)?)\s*')
def get_integrated_tag(sha):
"""For a given SHA, find the first tag that includes it."""
try:
cmd = [
'git', '-C', upstream_path, 'describe', '--match', 'v*',
'--contains', sha
]
tag = do_check_output(cmd)
return _version_re.match(tag).group()
except AttributeError:
return None
except subprocess.CalledProcessError:
return None
# extract_numerics matches numeric parts of a Linux version as separate elements
# For example, "v5.4" matches "5" and "4", and "v5.4.12" matches "5", "4", and "12"
extract_numerics = re.compile(
r'(?:v)?([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:-rc([0-9]+))?\s*')
def version_to_number(version):
"""Convert Linux version to numeric value usable for comparisons.
A branch with higher version number will return a larger number.
Supports version numbers up to 999, and release candidates up to 99.
Returns 0 if the kernel version can not be extracted.
"""
m = extract_numerics.match(version)
if m:
major = int(m.group(1))
minor1 = int(m.group(2))
minor2 = int(m.group(3)) if m.group(3) else 0
minor3 = int(m.group(4)) if m.group(4) else 0
total = major * 1000000000 + minor1 * 1000000 + minor2 * 1000
if minor3 != 0:
total -= (100 - minor3)
return total
return 0
def version_compare(v1, v2):
"""Convert linux version into numberic string for comparison"""
return version_to_number(v2) >= version_to_number(v1)
def is_in_baseline(version, baseline=rebase_baseline()):
"""Return true if 1st version is included in the current baseline.
If no baseline is provided, use default.
"""
if version and baseline:
return version_compare(version, baseline)
# If there is no version tag, it can not be included in any baseline.
return False
def is_in_target(version, target=rebase_target_tag()):
"""Return true if 1st version is included in the current baseline.
If no baseline is provided, use default.
"""
if version and target:
return version_compare(version, target)
# If there is no version tag, it can not be included in any target.
return False