Merge lp:~didrocks/quickly/install-in-opt into lp:quickly
- install-in-opt
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Michael Terry |
Approved revision: | 568 |
Merged at revision: | 568 |
Proposed branch: | lp:~didrocks/quickly/install-in-opt |
Merge into: | lp:quickly |
Diff against target: |
462 lines (+384/-3) 6 files modified
data/templates/ubuntu-application/internal/packaging.py (+4/-1) data/templates/ubuntu-application/project_root/bin/project_name (+11/-1) data/templates/ubuntu-application/submitubuntu.py (+297/-0) data/templates/ubuntu-application/upgrade.py (+26/-0) quickly/quicklyconfig.py (+1/-1) quickly/templatetools.py (+45/-0) |
To merge this branch: | bzr merge lp:~didrocks/quickly/install-in-opt |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Terry (community) | Approve | ||
Review via email: mp+40628@code.launchpad.net |
Commit message
Description of the change
The branch which makes the application review board happy :)
see my comment at
https:/
Still some work to do, like create a symlink for the .desktop file and such, but anything should now be installed in /opt/<appname> with "quickly submitubuntu".
Michael Terry (mterry) wrote : | # |
Didier Roche-Tolomelli (didrocks) wrote : | # |
+# Copyright 2009 Didier Roche
Should that be 2010 Canonical?
No, Quickly doesn't have copyright assignment and I didn't work on that part on my Canonical time (I just added an option to it)? So keeping original file copyright make sense.
17 + command = ['python-mkdebian', '--force-control', '--force-rules']
I'll update that, and also add linking the right file.
Could we not reduce the duplicated logic between 'submitubuntu' and 'release' more?
Is there a reason we don't just default installopt to True? Seems bad for developers to be testing one thing and submitting a different one. Especially since any hard-coded paths they used will want to be different.
Did you read my comment as pointed from the original message?
https:/
I agree with that, but that's wont be an alpha1 target given the time I have. All the testing issue is also discussed in the comment linked above and I want that we discuss that during alpha1 and alpha2 to make submitubuntu a more useful command.
- 563. By Didier Roche-Tolomelli
-
add support in project_name for running application in /opt/appname
- 564. By Didier Roche-Tolomelli
-
force rules under conditions
- 565. By Didier Roche-Tolomelli
-
support upgrade for /opt support and add a function to make the safe add easy
Didier Roche-Tolomelli (didrocks) wrote : | # |
pushed the previous remark fixes. Handle now upgrades as well.
I've created a convenient function for replacing some text in files between a start and end marker. Maybe some of our function (like licence) should starts using it.
- 566. By Didier Roche-Tolomelli
-
install in /opt/extras
Michael Terry (mterry) wrote : | # |
/opt/extras should be /opt/extras.
15 if get_python_
16 command.
17 + if get_python_
18 + command.
Should just be:
if get_python_
command.
command.
as --force-rules was added in 2.23.
+print _("Then your application will be reviewed by the application review board.")
I didn't see anything that would notify the ARB. I assume that's a TODO item?
+def update_
Nice function. :) Though ideally, it would use set_file_contents() from quicklyutils.py (after moving it to templatetools).
Didier Roche-Tolomelli (didrocks) wrote : | # |
/opt/extras should be /opt/extras.
15 if get_python_
16 command.
17 + if get_python_
18 + command.
Should just be:
if get_python_
command.
command.
as --force-rules was added in 2.23.
oopss, fixing
+print _("Then your application will be reviewed by the application review board.")
I didn't see anything that would notify the ARB. I assume that's a TODO item?
Right, as mentionned and pending email on the ARB about "what to do with the submitubuntu command, should we always install in /opt?"
+def update_
Nice function. :) Though ideally, it would use set_file_contents() from quicklyutils.py (after moving it to templatetools).
Not really the same the same, set_files_contents exchanges some values, here this one is to add/remove content between tags. the licence command should use it.
- 567. By Didier Roche-Tolomelli
-
force versionning
- 568. By Didier Roche-Tolomelli
-
use extras.ubuntu.com
Didier Roche-Tolomelli (didrocks) wrote : | # |
pushed the new version, I mixed the update_file_content function. Well free to merge it with my function :)
Michael Terry (mterry) wrote : | # |
> Not really the same the same, set_files_contents exchanges some values, here this one is to add/remove content between tags. the licence command should use it.
I know they aren't the same. I was proposing that your new function use the existing set_file_contents() function instead of duplicating the whole .new/os.rename stuff again.
Didier Roche-Tolomelli (didrocks) wrote : | # |
it can't really use it, it should rather deprecate it as there are some operations done while going through the loop) or wrapping it, like set_file_contents call update_
Allison Randal (allison) wrote : | # |
> /opt/extras should be /opt/extras.
> the mailing list, I believe. But you mention that you are waiting for final,
> final approval.
Rick asked me to comment here. It's 98% sure the Tech Board will approve /opt/extras.
Didier Roche-Tolomelli (didrocks) wrote : | # |
Thanks Allison, there is still the question sent to the ARB and the "do we install always in /opt or just in the submitubuntu command and what to do with that command (and rename it to "submit"), but I think we can get to that later…
Michael: ok to merge? We will merge all the with: for writing in a file function later if you don't mind (like license, renaming and replace… and so on…)
Michael Terry (mterry) wrote : | # |
Approved, if you fix
37 + opt_path = path.replace(
To use extras.ubuntu.com
Didier Roche-Tolomelli (didrocks) wrote : | # |
argh, a one leftover :)
doing and done!
Preview Diff
1 | === modified file 'data/templates/ubuntu-application/internal/packaging.py' | |||
2 | --- data/templates/ubuntu-application/internal/packaging.py 2010-11-22 16:01:03 +0000 | |||
3 | +++ data/templates/ubuntu-application/internal/packaging.py 2010-11-22 16:47:10 +0000 | |||
4 | @@ -162,7 +162,7 @@ | |||
5 | 162 | version = proc.communicate()[0] | 162 | version = proc.communicate()[0] |
6 | 163 | return float(version) | 163 | return float(version) |
7 | 164 | 164 | ||
9 | 165 | def updatepackaging(changelog=None, no_changelog=False): | 165 | def updatepackaging(changelog=None, no_changelog=False, installopt=False): |
10 | 166 | """create or update a package using python-mkdebian. | 166 | """create or update a package using python-mkdebian. |
11 | 167 | 167 | ||
12 | 168 | Commit after the first packaging creation""" | 168 | Commit after the first packaging creation""" |
13 | @@ -172,8 +172,11 @@ | |||
14 | 172 | command = ['python-mkdebian', '--force-control'] | 172 | command = ['python-mkdebian', '--force-control'] |
15 | 173 | if get_python_mkdebian_version() > 2.22: | 173 | if get_python_mkdebian_version() > 2.22: |
16 | 174 | command.append("--force-copyright") | 174 | command.append("--force-copyright") |
17 | 175 | command.append("--force-rules") | ||
18 | 175 | if no_changelog: | 176 | if no_changelog: |
19 | 176 | command.append("--no-changelog") | 177 | command.append("--no-changelog") |
20 | 178 | if installopt: | ||
21 | 179 | command.append("--prefix=/opt/extras.ubuntu.com/%s" % configurationhandler.project_config['project']) | ||
22 | 177 | for message in changelog: | 180 | for message in changelog: |
23 | 178 | command.extend(["--changelog", message]) | 181 | command.extend(["--changelog", message]) |
24 | 179 | if not configurationhandler.project_config: | 182 | if not configurationhandler.project_config: |
25 | 180 | 183 | ||
26 | === modified file 'data/templates/ubuntu-application/project_root/bin/project_name' | |||
27 | --- data/templates/ubuntu-application/project_root/bin/project_name 2010-11-17 18:44:18 +0000 | |||
28 | +++ data/templates/ubuntu-application/project_root/bin/project_name 2010-11-22 16:47:10 +0000 | |||
29 | @@ -16,10 +16,20 @@ | |||
30 | 16 | PROJECT_ROOT_DIRECTORY = os.path.abspath( | 16 | PROJECT_ROOT_DIRECTORY = os.path.abspath( |
31 | 17 | os.path.dirname(os.path.dirname(os.path.realpath(sys.argv[0])))) | 17 | os.path.dirname(os.path.dirname(os.path.realpath(sys.argv[0])))) |
32 | 18 | 18 | ||
33 | 19 | python_path = [] | ||
34 | 20 | if os.path.abspath(__file__).startswith('/opt'): | ||
35 | 21 | syspath = sys.path[:] # copy to avoid infinite loop in pending objects | ||
36 | 22 | for path in syspath: | ||
37 | 23 | opt_path = path.replace('/usr', '/opt/extras/python_name') | ||
38 | 24 | python_path.insert(0, opt_path) | ||
39 | 25 | sys.path.insert(0, opt_path) | ||
40 | 19 | if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY, 'python_name')) | 26 | if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY, 'python_name')) |
41 | 20 | and PROJECT_ROOT_DIRECTORY not in sys.path): | 27 | and PROJECT_ROOT_DIRECTORY not in sys.path): |
42 | 28 | python_path.insert(0, PROJECT_ROOT_DIRECTORY) | ||
43 | 21 | sys.path.insert(0, PROJECT_ROOT_DIRECTORY) | 29 | sys.path.insert(0, PROJECT_ROOT_DIRECTORY) |
45 | 22 | os.putenv('PYTHONPATH', PROJECT_ROOT_DIRECTORY) # for subprocesses | 30 | if python_path: |
46 | 31 | os.putenv('PYTHONPATH', "%s:%s" % (os.getenv('PYTHONPATH', ''), ':'.join(python_path))) # for subprocesses | ||
47 | 32 | |||
48 | 23 | 33 | ||
49 | 24 | from python_name import (Basecamel_case_nameWindow) | 34 | from python_name import (Basecamel_case_nameWindow) |
50 | 25 | import python_name.helpers as helpers | 35 | import python_name.helpers as helpers |
51 | 26 | 36 | ||
52 | === added file 'data/templates/ubuntu-application/submitubuntu.py' | |||
53 | --- data/templates/ubuntu-application/submitubuntu.py 1970-01-01 00:00:00 +0000 | |||
54 | +++ data/templates/ubuntu-application/submitubuntu.py 2010-11-22 16:47:10 +0000 | |||
55 | @@ -0,0 +1,297 @@ | |||
56 | 1 | #!/usr/bin/python | ||
57 | 2 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | ||
58 | 3 | # Copyright 2009 Didier Roche | ||
59 | 4 | # | ||
60 | 5 | # This file is part of Quickly ubuntu-application template | ||
61 | 6 | # | ||
62 | 7 | #This program is free software: you can redistribute it and/or modify it | ||
63 | 8 | #under the terms of the GNU General Public License version 3, as published | ||
64 | 9 | #by the Free Software Foundation. | ||
65 | 10 | |||
66 | 11 | #This program is distributed in the hope that it will be useful, but | ||
67 | 12 | #WITHOUT ANY WARRANTY; without even the implied warranties of | ||
68 | 13 | #MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
69 | 14 | #PURPOSE. See the GNU General Public License for more details. | ||
70 | 15 | |||
71 | 16 | #You should have received a copy of the GNU General Public License along | ||
72 | 17 | #with this program. If not, see <http://www.gnu.org/licenses/>. | ||
73 | 18 | |||
74 | 19 | import os | ||
75 | 20 | import sys | ||
76 | 21 | import subprocess | ||
77 | 22 | import webbrowser | ||
78 | 23 | |||
79 | 24 | from internal import quicklyutils, packaging, launchpad_helper | ||
80 | 25 | from internal import bzrutils | ||
81 | 26 | from quickly import templatetools, configurationhandler, commands | ||
82 | 27 | import license | ||
83 | 28 | |||
84 | 29 | import logging | ||
85 | 30 | |||
86 | 31 | from quickly import launchpadaccess | ||
87 | 32 | |||
88 | 33 | import gettext | ||
89 | 34 | from gettext import gettext as _ | ||
90 | 35 | gettext.textdomain('quickly') | ||
91 | 36 | |||
92 | 37 | options = ["--ppa",] | ||
93 | 38 | |||
94 | 39 | def usage(): | ||
95 | 40 | templatetools.print_usage(_('quickly submitubuntu [--ppa <ppa | group/ppa>] [release-version] [comments]')) | ||
96 | 41 | def help(): | ||
97 | 42 | print _("""Posts a release of your project and submit it the ubuntu | ||
98 | 43 | application review board so that any users can see and install the | ||
99 | 44 | application ont their system. | ||
100 | 45 | |||
101 | 46 | Before running quickly submitubuntu, you should: create your account | ||
102 | 47 | and a project page on http://launchpad.net. | ||
103 | 48 | You also have to add a PPA to your launchpad account. | ||
104 | 49 | |||
105 | 50 | Name, email, and version will be automatically changed in setup.py and | ||
106 | 51 | bzr will tag the current source with the new version number. | ||
107 | 52 | |||
108 | 53 | If not specified, the new version number will be 'YEAR.MONTH[.RELEASE]'. | ||
109 | 54 | |||
110 | 55 | For example, the third release in July 2010 would be versioned 10.07.2. | ||
111 | 56 | |||
112 | 57 | You may want to make sure that the description and long description in | ||
113 | 58 | setup.py are up to date before releasing. | ||
114 | 59 | |||
115 | 60 | You can optionally run 'quickly package' and test your package to make | ||
116 | 61 | sure it installs as expected.""") | ||
117 | 62 | def shell_completion(argv): | ||
118 | 63 | ''' Complete --args ''' | ||
119 | 64 | # option completion | ||
120 | 65 | rv = [] | ||
121 | 66 | if argv[-1].startswith("-"): | ||
122 | 67 | rv = options | ||
123 | 68 | elif len(argv) > 1 and argv[-2] == '--ppa': # if argument following --ppa, complete by ppa | ||
124 | 69 | rv = packaging.shell_complete_ppa(argv[-1]) | ||
125 | 70 | if rv: | ||
126 | 71 | rv.sort() | ||
127 | 72 | print ' '.join(rv) | ||
128 | 73 | |||
129 | 74 | templatetools.handle_additional_parameters(sys.argv, help, shell_completion, usage=usage) | ||
130 | 75 | |||
131 | 76 | |||
132 | 77 | launchpad = None | ||
133 | 78 | project = None | ||
134 | 79 | ppa_name = None | ||
135 | 80 | i = 0 | ||
136 | 81 | args = [] | ||
137 | 82 | argv = sys.argv | ||
138 | 83 | |||
139 | 84 | while i < len(argv): | ||
140 | 85 | arg = argv[i] | ||
141 | 86 | if arg.startswith('-'): | ||
142 | 87 | if arg == '--ppa': | ||
143 | 88 | if i + 1 < len(argv): | ||
144 | 89 | ppa_name = argv[i + 1] | ||
145 | 90 | i += 1 | ||
146 | 91 | else: | ||
147 | 92 | cmd = commands.get_command('submitubuntu', 'ubuntu-application') | ||
148 | 93 | templatetools.usage_error(_("No PPA provided."), cmd=cmd) | ||
149 | 94 | else: | ||
150 | 95 | cmd = commands.get_command('submitubuntu', 'ubuntu-application') | ||
151 | 96 | templatetools.usage_error(_("Unknown option: %s." % arg), cmd=cmd) | ||
152 | 97 | else: | ||
153 | 98 | args.append(arg) | ||
154 | 99 | i += 1 | ||
155 | 100 | |||
156 | 101 | commit_msg = None | ||
157 | 102 | if len(args) == 1: | ||
158 | 103 | proposed_version = None | ||
159 | 104 | elif len(args) == 2: | ||
160 | 105 | proposed_version = args[1] | ||
161 | 106 | elif len(args) > 2: | ||
162 | 107 | proposed_version = args[1] | ||
163 | 108 | commit_msg = " ".join(args[2:]) | ||
164 | 109 | |||
165 | 110 | # warning: project_name can be different from project.name (one local, one on launchpad) | ||
166 | 111 | if not configurationhandler.project_config: | ||
167 | 112 | configurationhandler.loadConfig() | ||
168 | 113 | project_name = configurationhandler.project_config['project'] | ||
169 | 114 | |||
170 | 115 | # connect to LP | ||
171 | 116 | try: | ||
172 | 117 | launchpad = launchpadaccess.initialize_lpi() | ||
173 | 118 | except launchpadaccess.launchpad_connection_error, e: | ||
174 | 119 | print(e) | ||
175 | 120 | sys.exit(1) | ||
176 | 121 | |||
177 | 122 | # push the gpg key and email to the env | ||
178 | 123 | try: | ||
179 | 124 | keyid = quicklyutils.get_right_gpg_key_id(launchpad) | ||
180 | 125 | except quicklyutils.gpg_error, e: | ||
181 | 126 | print(e) | ||
182 | 127 | sys.exit(1) | ||
183 | 128 | |||
184 | 129 | # get the project now and save the url into setup.py | ||
185 | 130 | try: | ||
186 | 131 | project = launchpadaccess.get_project(launchpad) | ||
187 | 132 | except launchpadaccess.launchpad_project_error, e: | ||
188 | 133 | print(e) | ||
189 | 134 | sys.exit(1) | ||
190 | 135 | project_url = launchpadaccess.launchpad_url + '/' + project.name | ||
191 | 136 | quicklyutils.set_setup_value('url', project_url) | ||
192 | 137 | about_dialog_file_name = quicklyutils.get_about_file_name() | ||
193 | 138 | if about_dialog_file_name: | ||
194 | 139 | quicklyutils.change_xml_elem(about_dialog_file_name, "object/property", | ||
195 | 140 | "name", "website", project_url, {}) | ||
196 | 141 | |||
197 | 142 | # choose right ppa parameter (users, etc.) ppa or staging if ppa_name is None | ||
198 | 143 | try: | ||
199 | 144 | (ppa_user, ppa_name, dput_ppa_name, ppa_url) = packaging.choose_ppa(launchpad, ppa_name) | ||
200 | 145 | except packaging.user_team_not_found, e: | ||
201 | 146 | print(_("User or Team %s not found on Launchpad") % e) | ||
202 | 147 | sys.exit(1) | ||
203 | 148 | except packaging.not_ppa_owner, e: | ||
204 | 149 | print(_("You have to be a member of %s team to upload to its ppas") % e) | ||
205 | 150 | sys.exit(1) | ||
206 | 151 | |||
207 | 152 | try: | ||
208 | 153 | ppa_name = packaging.check_and_return_ppaname(launchpad, ppa_user, ppa_name) # ppa_name can be ppa name or ppa display name. Find the right one if exists | ||
209 | 154 | except packaging.ppa_not_found, e: | ||
210 | 155 | print(_("%s does not exist. Please create it on launchpad if you want to push a package to it. %s has the following ppas available:") % (e, ppa_user.name)) | ||
211 | 156 | user_has_ppa = False | ||
212 | 157 | for ppa_name, ppa_display_name in packaging.get_all_ppas(launchpad, ppa_user): | ||
213 | 158 | print "%s - %s" % (ppa_name, ppa_display_name) | ||
214 | 159 | user_has_ppa = True | ||
215 | 160 | if user_has_ppa: | ||
216 | 161 | print(_("You can temporary choose one of them with --ppa switch or definitely by executing quickly configure ppa <ppa_name>.")) | ||
217 | 162 | sys.exit(1) | ||
218 | 163 | |||
219 | 164 | # update license if needed. Don't change anything if not needed | ||
220 | 165 | try: | ||
221 | 166 | license.licensing() | ||
222 | 167 | except license.LicenceError, error_message: | ||
223 | 168 | print(error_message) | ||
224 | 169 | sys.exit(1) | ||
225 | 170 | |||
226 | 171 | try: | ||
227 | 172 | release_version = packaging.updateversion(proposed_version) | ||
228 | 173 | except (packaging.invalid_versionning_scheme, | ||
229 | 174 | packaging.invalid_version_in_setup), error_message: | ||
230 | 175 | print(error_message) | ||
231 | 176 | sys.exit(1) | ||
232 | 177 | |||
233 | 178 | if commit_msg is None: | ||
234 | 179 | commit_msg = _('quickly released: %s' % release_version) | ||
235 | 180 | |||
236 | 181 | |||
237 | 182 | # check if already released with this name | ||
238 | 183 | bzr_instance = subprocess.Popen(["bzr", "tags"], stdout=subprocess.PIPE) | ||
239 | 184 | bzr_tags, err = bzr_instance.communicate() | ||
240 | 185 | if bzr_instance.returncode !=0: | ||
241 | 186 | print(err) | ||
242 | 187 | sys.exit(1) | ||
243 | 188 | if release_version in bzr_tags: | ||
244 | 189 | print _("ERROR: quickly can't release: %s seems to be already released. Choose another name.") % release_version | ||
245 | 190 | sys.exit(1) | ||
246 | 191 | |||
247 | 192 | # commit current changes | ||
248 | 193 | packaging.filter_exec_command(["bzr", "add"]) | ||
249 | 194 | return_code = packaging.filter_exec_command(["bzr", "commit", '--unchanged', '-m', | ||
250 | 195 | _('commit before release')]) | ||
251 | 196 | if return_code != 0 and return_code != 3: | ||
252 | 197 | print _("ERROR: quickly can't release as it can't commit with bzr") | ||
253 | 198 | sys.exit(return_code) | ||
254 | 199 | |||
255 | 200 | # try to get last available version in bzr | ||
256 | 201 | previous_version = None | ||
257 | 202 | bzr_instance = subprocess.Popen(['bzr', 'tags', '--sort=time'], | ||
258 | 203 | stdout=subprocess.PIPE) | ||
259 | 204 | result, err = bzr_instance.communicate() | ||
260 | 205 | if bzr_instance.returncode == 0 and result: | ||
261 | 206 | output = result.split('\n') | ||
262 | 207 | output.reverse() | ||
263 | 208 | for tag_line in output: | ||
264 | 209 | tag_elem = tag_line.split (' ') | ||
265 | 210 | if not (tag_elem[-1] == '?' or tag_elem[-1] == ''): | ||
266 | 211 | previous_version = tag_elem[0] | ||
267 | 212 | break | ||
268 | 213 | |||
269 | 214 | changelog = quicklyutils.collect_commit_messages(previous_version) | ||
270 | 215 | # creation/update debian packaging | ||
271 | 216 | return_code = packaging.updatepackaging(changelog, installopt=True) | ||
272 | 217 | if return_code != 0: | ||
273 | 218 | print _("ERROR: can't create or update ubuntu package") | ||
274 | 219 | sys.exit(1) | ||
275 | 220 | |||
276 | 221 | # add files, setup release version, commit and push ! | ||
277 | 222 | #TODO: check or fix if we don't have an ssh key (don't tag otherwise to be able to release again) | ||
278 | 223 | packaging.filter_exec_command(["bzr", "add"]) | ||
279 | 224 | return_code = packaging.filter_exec_command(["bzr", "commit", '-m', commit_msg]) | ||
280 | 225 | if return_code != 0 and return_code != 3: | ||
281 | 226 | print _("ERROR: quickly can't release as it can't commit with bzr") | ||
282 | 227 | sys.exit(return_code) | ||
283 | 228 | packaging.filter_exec_command(["bzr", "tag", release_version]) # tag revision | ||
284 | 229 | |||
285 | 230 | # check if pull branch is set | ||
286 | 231 | bzr_instance = subprocess.Popen(["bzr", "info"], stdout=subprocess.PIPE) | ||
287 | 232 | bzr_info, err = bzr_instance.communicate() | ||
288 | 233 | if bzr_instance.returncode !=0: | ||
289 | 234 | print(err) | ||
290 | 235 | sys.exit(1) | ||
291 | 236 | |||
292 | 237 | |||
293 | 238 | if (launchpadaccess.lp_server == "staging"): | ||
294 | 239 | bzr_staging = "//staging/" | ||
295 | 240 | else: | ||
296 | 241 | bzr_staging = "" | ||
297 | 242 | |||
298 | 243 | custom_location_in_info = None | ||
299 | 244 | branch_location = [] | ||
300 | 245 | custom_location = bzrutils.get_bzrbranch() | ||
301 | 246 | if custom_location: | ||
302 | 247 | branch_location = [custom_location] | ||
303 | 248 | custom_location_in_info = custom_location.replace('lp:', '') | ||
304 | 249 | # if no branch, create it in ~user_name/project_name/quickly_trunk | ||
305 | 250 | # or switch from staging to production | ||
306 | 251 | if ("parent branch" in bzr_info) and not ( | ||
307 | 252 | (custom_location_in_info and custom_location_in_info not in bzr_info) or | ||
308 | 253 | ((".staging." in bzr_info) and not bzr_staging) or | ||
309 | 254 | (not (".staging." in bzr_info) and bzr_staging)): | ||
310 | 255 | return_code = packaging.filter_exec_command(["bzr", "pull"]) | ||
311 | 256 | if return_code != 0: | ||
312 | 257 | print _("ERROR: quickly can't release: can't pull from launchpad.") | ||
313 | 258 | sys.exit(return_code) | ||
314 | 259 | |||
315 | 260 | return_code = packaging.filter_exec_command(["bzr", "push"]) | ||
316 | 261 | if return_code != 0: | ||
317 | 262 | print _("ERROR: quickly can't release: can't push to launchpad.") | ||
318 | 263 | sys.exit(return_code) | ||
319 | 264 | else: | ||
320 | 265 | if not branch_location: | ||
321 | 266 | branch_location = ['lp:', bzr_staging, '~', launchpad.me.name, '/', project.name, '/quickly_trunk'] | ||
322 | 267 | return_code = packaging.filter_exec_command(["bzr", "push", "--remember", "--overwrite", "".join(branch_location)]) | ||
323 | 268 | if return_code != 0: | ||
324 | 269 | print _("ERROR: quickly can't release: can't push to launchpad.") | ||
325 | 270 | sys.exit(return_code) | ||
326 | 271 | |||
327 | 272 | # make first pull too | ||
328 | 273 | return_code = packaging.filter_exec_command(["bzr", "pull", "--remember", "".join(branch_location)]) | ||
329 | 274 | if return_code != 0: | ||
330 | 275 | print _("ERROR: quickly can't release correctly: can't pull from launchpad.") | ||
331 | 276 | sys.exit(return_code) | ||
332 | 277 | |||
333 | 278 | |||
334 | 279 | # upload to launchpad | ||
335 | 280 | print _("pushing to launchpad") | ||
336 | 281 | return_code = packaging.push_to_ppa(dput_ppa_name, "../%s_%s_source.changes" % (project_name, release_version), keyid=keyid) != 0 | ||
337 | 282 | if return_code != 0: | ||
338 | 283 | sys.exit(return_code) | ||
339 | 284 | |||
340 | 285 | #create new release_date | ||
341 | 286 | launchpad_helper.push_tarball_to_launchpad(project, release_version, | ||
342 | 287 | "../%s_%s.tar.gz" % (project_name, | ||
343 | 288 | release_version), changelog) | ||
344 | 289 | |||
345 | 290 | print _("%s %s released and submitted to ubuntu. Wait for half an hour and have look at %s.") % (project_name, release_version, ppa_url) | ||
346 | 291 | print _("Then your application will be reviewed by the application review board.") | ||
347 | 292 | |||
348 | 293 | # as launchpad-open doesn't support staging server, put an url | ||
349 | 294 | if launchpadaccess.lp_server == "staging": | ||
350 | 295 | webbrowser.open(launchpadaccess.LAUNCHPAD_CODE_STAGING_URL + '/' + project.name) | ||
351 | 296 | else: | ||
352 | 297 | webbrowser.open(launchpadaccess.LAUNCHPAD_URL + '/' + project.name) | ||
353 | 0 | 298 | ||
354 | === modified file 'data/templates/ubuntu-application/upgrade.py' | |||
355 | --- data/templates/ubuntu-application/upgrade.py 2010-09-28 12:53:04 +0000 | |||
356 | +++ data/templates/ubuntu-application/upgrade.py 2010-11-22 16:47:10 +0000 | |||
357 | @@ -171,4 +171,30 @@ | |||
358 | 171 | os.system("find . -name '*.py' -exec %s {} \;" % sedline) | 171 | os.system("find . -name '*.py' -exec %s {} \;" % sedline) |
359 | 172 | os.system("%s bin/%s" % (sedline, project_name)) | 172 | os.system("%s bin/%s" % (sedline, project_name)) |
360 | 173 | 173 | ||
361 | 174 | ### 0.7 update | ||
362 | 175 | if project_version < '0.7': | ||
363 | 176 | # support /opt installation | ||
364 | 177 | content_to_update = '''python_path = [] | ||
365 | 178 | if os.path.abspath(__file__).startswith('/opt'): | ||
366 | 179 | syspath = sys.path[:] # copy to avoid infinite loop in pending objects | ||
367 | 180 | for path in syspath: | ||
368 | 181 | opt_path = path.replace('/usr', '/opt/extras.ubuntu.com/%(python_name)s') | ||
369 | 182 | python_path.insert(0, opt_path) | ||
370 | 183 | sys.path.insert(0, opt_path) | ||
371 | 184 | if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY, '%(python_name)s')) | ||
372 | 185 | and PROJECT_ROOT_DIRECTORY not in sys.path): | ||
373 | 186 | python_path.insert(0, PROJECT_ROOT_DIRECTORY) | ||
374 | 187 | sys.path.insert(0, PROJECT_ROOT_DIRECTORY) | ||
375 | 188 | if python_path: | ||
376 | 189 | os.putenv('PYTHONPATH', "%%s:%%s" %% (os.getenv('PYTHONPATH', ''), ':'.join(python_path))) # for subprocesses''' % {'python_name' : python_name} | ||
377 | 190 | |||
378 | 191 | try: | ||
379 | 192 | templatetools.update_file_content("./bin/%s" % project_name, | ||
380 | 193 | 'if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY', | ||
381 | 194 | " os.putenv('PYTHONPATH', PROJECT_ROOT_DIRECTORY) # for subprocesses", | ||
382 | 195 | content_to_update) | ||
383 | 196 | except templatetools.CantUpdateFile, e: | ||
384 | 197 | print _("WARNING: can't update your project to support /opt. This doesn't mind if you don't plan to submit your project to the application review board. Cause is: %s" % e) | ||
385 | 198 | |||
386 | 199 | |||
387 | 174 | sys.exit(0) | 200 | sys.exit(0) |
388 | 175 | 201 | ||
389 | === modified file 'quickly/quicklyconfig.py' | |||
390 | --- quickly/quicklyconfig.py 2010-10-06 09:52:51 +0000 | |||
391 | +++ quickly/quicklyconfig.py 2010-11-22 16:47:10 +0000 | |||
392 | @@ -20,7 +20,7 @@ | |||
393 | 20 | # you're warned :) | 20 | # you're warned :) |
394 | 21 | 21 | ||
395 | 22 | # quickly version used for project format compatibility | 22 | # quickly version used for project format compatibility |
397 | 23 | __version__ = '0.6.1' | 23 | __version__ = '0.7' |
398 | 24 | 24 | ||
399 | 25 | # where quickly will head for quickly data (for instance, templates) | 25 | # where quickly will head for quickly data (for instance, templates) |
400 | 26 | # by default, this is ../data, relative to trunk layout | 26 | # by default, this is ../data, relative to trunk layout |
401 | 27 | 27 | ||
402 | === modified file 'quickly/templatetools.py' | |||
403 | --- quickly/templatetools.py 2010-10-15 20:26:19 +0000 | |||
404 | +++ quickly/templatetools.py 2010-11-22 16:47:10 +0000 | |||
405 | @@ -31,6 +31,11 @@ | |||
406 | 31 | 31 | ||
407 | 32 | class bad_project_name(Exception): | 32 | class bad_project_name(Exception): |
408 | 33 | pass | 33 | pass |
409 | 34 | class CantUpdateFile(Exception): | ||
410 | 35 | def __init__(self, msg): | ||
411 | 36 | self.msg = msg | ||
412 | 37 | def __str__(self): | ||
413 | 38 | return self.msg | ||
414 | 34 | 39 | ||
415 | 35 | def handle_additional_parameters(args, help=None, shell_completion=None, usage=None): | 40 | def handle_additional_parameters(args, help=None, shell_completion=None, usage=None): |
416 | 36 | """Enable handling additional parameter like help or shell_completion""" | 41 | """Enable handling additional parameter like help or shell_completion""" |
417 | @@ -88,6 +93,46 @@ | |||
418 | 88 | mode = stat.S_IMODE(st.st_mode) | 93 | mode = stat.S_IMODE(st.st_mode) |
419 | 89 | os.chmod(dest_file_name, mode) | 94 | os.chmod(dest_file_name, mode) |
420 | 90 | 95 | ||
421 | 96 | def update_file_content(filename, start_marker, end_marker, replacing_content): | ||
422 | 97 | """Safely replace the content of a file""" | ||
423 | 98 | |||
424 | 99 | skip_until_end_found = False | ||
425 | 100 | marker_found = False | ||
426 | 101 | try: | ||
427 | 102 | filename = os.path.abspath(filename) | ||
428 | 103 | ftarget_file_name = file(filename, 'r') | ||
429 | 104 | ftarget_file_name_out = file(ftarget_file_name.name + '.new', 'w') | ||
430 | 105 | for line in ftarget_file_name: | ||
431 | 106 | # seek if we have to add something | ||
432 | 107 | if start_marker in line: | ||
433 | 108 | skip_until_end_found = True | ||
434 | 109 | marker_found = True | ||
435 | 110 | ftarget_file_name_out.write(replacing_content) | ||
436 | 111 | |||
437 | 112 | if end_marker in line: | ||
438 | 113 | skip_until_end_found = False | ||
439 | 114 | |||
440 | 115 | if not skip_until_end_found: | ||
441 | 116 | ftarget_file_name_out.write(line) | ||
442 | 117 | |||
443 | 118 | ftarget_file_name.close() | ||
444 | 119 | ftarget_file_name_out.close() | ||
445 | 120 | |||
446 | 121 | if skip_until_end_found: # that means we didn't find the end_tag, don't copy the file | ||
447 | 122 | os.remove(ftarget_file_name_out.name) | ||
448 | 123 | raise CantUpdateFile(_("%s was not found in the file %s.") % (end_marker, ftarget_file_name.name)) | ||
449 | 124 | |||
450 | 125 | if not marker_found: | ||
451 | 126 | os.remove(ftarget_file_name_out.name) | ||
452 | 127 | raise CantUpdateFile(_("%s was not found in the file %s.") % (start_marker, ftarget_file_name.name)) | ||
453 | 128 | |||
454 | 129 | apply_file_rights(ftarget_file_name.name, ftarget_file_name_out.name) | ||
455 | 130 | os.rename(ftarget_file_name_out.name, ftarget_file_name.name) | ||
456 | 131 | |||
457 | 132 | except (OSError, IOError), e: | ||
458 | 133 | msg = _("%s file was not found or can't update it") % ftarget_file_name | ||
459 | 134 | raise CantUpdateFile(msg) | ||
460 | 135 | |||
461 | 91 | def in_verbose_mode(): | 136 | def in_verbose_mode(): |
462 | 92 | """Return true if verbose mode is on""" | 137 | """Return true if verbose mode is on""" |
463 | 93 | 138 |
+# Copyright 2009 Didier Roche
Should that be 2010 Canonical?
17 + command = ['python-mkdebian', '--force-control', '--force-rules']
You probably want to version-guard --force-rules like we did for --force-copyright.
Could we call it 'submit' rather than 'submitubuntu'?
Could we not reduce the duplicated logic between 'submitubuntu' and 'release' more?
Is there a reason we don't just default installopt to True? Seems bad for developers to be testing one thing and submitting a different one. Especially since any hard-coded paths they used will want to be different.