-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathlpmptox.py
165 lines (135 loc) · 6.1 KB
/
lpmptox.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
#!/usr/bin/env python
"""
lpmptox script will run tox on changes in a selected MP
lpmptox depends on ``launchpadlib``, which isn't
necessarily up-to-date in PyPI, so we install it from the archive::
`sudo apt-get install python-launchpadlib` OR
`sudo apt-get install python3-launchpadlib` OR
As we're using ``launchpadlib`` from the archive (which is therefore
installed in the system), you'll need to create your virtualenvs
with the ``--system-site-packages`` option.
Activate your virtualenv and install the requirements::
`pip install -r requirements.txt`
"""
import click
import git
import os
import subprocess
from tempfile import TemporaryDirectory
import urwid
from lpshipit import (
_get_launchpad_client,
_set_urwid_widget,
summarize_git_mps,
)
from lxc import lxc_container
# Global var to store the chosen MP
CHOSEN_MP = None
def _write_debug(output_file, message):
output_file.write('{}\n'.format(message))
output_file.flush()
print(message)
def runtox(source_repo, source_branch,
tox_command='tox --recreate --parallel auto',
output_filepath=os.devnull,
environment=None):
with open(output_filepath, "a") as output_file, TemporaryDirectory() as local_repo:
_write_debug(output_file, 'Cloning {} (branch {}) in to tmp directory {} ...'.format(
source_repo,
source_branch,
local_repo))
repo = git.Repo.clone_from(
source_repo,
local_repo,
depth=1,
single_branch=True,
branch=source_branch
)
_write_debug(output_file, '{} {}'.format(
repo.head.object.hexsha,
repo.head.object.summary
))
if environment is not None:
_write_debug(output_file,
'Running `{}` in {} lxc environment ...'.format(
tox_command, environment))
return _run_tox_in_lxc(environment, local_repo, tox_command,
output_file)
else:
_write_debug(output_file,
'Running `{}` in {} ...'.format(tox_command,
local_repo))
return _run_tox_locally(local_repo, tox_command, output_file)
def _run_tox_in_lxc(environment, local_repo, tox_command, output_file):
with lxc_container(environment, local_repo) as container:
# If a proxy has been configured on the host using environment
# variables http_proxy or https_proxy then the container will inherit
# this proxy config for the default user. However then calling sudo
# this proxy config is no longer configured. To fix this and so sudo
# calls use the same proxy we can use `--preserve-env`
# http://manpages.ubuntu.com/manpages/focal/man8/sudo.8.html to pass
# in a list of environment variables we want set for sudo user too.
sudo_preserve_proxy = '--preserve-env="http_proxy,https_proxy"'
container.run_command('sudo {} apt-get update'.format(sudo_preserve_proxy))
container.run_command('sudo {} apt-get install -y python3-pip'.format(sudo_preserve_proxy))
container.run_command('sudo {} pip3 install tox'.format(sudo_preserve_proxy))
# local_repo is same path in the container
tox_returncode, tox_output = container.run_command(
tox_command + ' -c ' + local_repo)
_write_debug(output_file, tox_output)
return tox_returncode
def _run_tox_locally(local_repo, tox_command, output_file):
process = subprocess.Popen(tox_command,
stdout=subprocess.PIPE,
shell=True,
cwd=local_repo)
while process.poll() is None:
_write_debug(output_file, process.stdout.readline().decode('utf-8').rstrip())
return process.returncode
@click.command()
@click.option('--mp-owner', help='LP username of the owner of the MP '
'(Defaults to system configured user)',
default=None)
@click.option('--source-repo', help='Repository to test', default=None)
@click.option('--source-branch', help='Branch to test', default=None)
@click.option('--debug/--no-debug', default=False)
@click.option('--environment', default=None, help='release (16.04, 18.04, etc) to run tox in')
def lpmptox(mp_owner, source_repo, source_branch, debug, environment):
"""Invokes the commit building with proper user inputs."""
if not source_repo and not source_branch:
lp = _get_launchpad_client()
lp_user = lp.me
print('Retrieving Merge Proposals from Launchpad...')
person = lp.people[lp_user.name if mp_owner is None else mp_owner]
mps = person.getMergeProposals(status=['Needs review', 'Approved'])
if debug:
print('Debug: Launchad returned {} merge proposals'.format(len(mps)))
mp_summaries = summarize_git_mps(mps)
if mp_summaries:
def urwid_exit_on_q(key):
if key in ('q', 'Q'):
raise urwid.ExitMainLoop()
def mp_chosen(button, chosen_mp):
global CHOSEN_MP
CHOSEN_MP = chosen_mp
raise urwid.ExitMainLoop()
listwalker = urwid.SimpleFocusListWalker(list())
listwalker.append(urwid.Text(u'Merge Proposal to Merge'))
listwalker.append(urwid.Divider())
for mp in mp_summaries:
button = urwid.Button(mp['summary'])
urwid.connect_signal(button, 'click', mp_chosen, mp)
listwalker.append(button)
mp_box = urwid.ListBox(listwalker)
try:
_set_urwid_widget(mp_box, urwid_exit_on_q)
finally:
if CHOSEN_MP:
source_repo = CHOSEN_MP['source_repo']
source_branch = CHOSEN_MP['source_branch']
else:
print("You have no Merge Proposals in either "
"'Needs review' or 'Approved' state")
runtox(source_repo, source_branch, environment=environment)
if __name__ == "__main__":
lpmptox()