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 | version = proc.communicate()[0] |
6 | return float(version) |
7 | |
8 | -def updatepackaging(changelog=None, no_changelog=False): |
9 | +def updatepackaging(changelog=None, no_changelog=False, installopt=False): |
10 | """create or update a package using python-mkdebian. |
11 | |
12 | Commit after the first packaging creation""" |
13 | @@ -172,8 +172,11 @@ |
14 | command = ['python-mkdebian', '--force-control'] |
15 | if get_python_mkdebian_version() > 2.22: |
16 | command.append("--force-copyright") |
17 | + command.append("--force-rules") |
18 | if no_changelog: |
19 | command.append("--no-changelog") |
20 | + if installopt: |
21 | + command.append("--prefix=/opt/extras.ubuntu.com/%s" % configurationhandler.project_config['project']) |
22 | for message in changelog: |
23 | command.extend(["--changelog", message]) |
24 | if not configurationhandler.project_config: |
25 | |
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 | PROJECT_ROOT_DIRECTORY = os.path.abspath( |
31 | os.path.dirname(os.path.dirname(os.path.realpath(sys.argv[0])))) |
32 | |
33 | +python_path = [] |
34 | +if os.path.abspath(__file__).startswith('/opt'): |
35 | + syspath = sys.path[:] # copy to avoid infinite loop in pending objects |
36 | + for path in syspath: |
37 | + opt_path = path.replace('/usr', '/opt/extras/python_name') |
38 | + python_path.insert(0, opt_path) |
39 | + sys.path.insert(0, opt_path) |
40 | if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY, 'python_name')) |
41 | and PROJECT_ROOT_DIRECTORY not in sys.path): |
42 | + python_path.insert(0, PROJECT_ROOT_DIRECTORY) |
43 | sys.path.insert(0, PROJECT_ROOT_DIRECTORY) |
44 | - os.putenv('PYTHONPATH', PROJECT_ROOT_DIRECTORY) # for subprocesses |
45 | +if python_path: |
46 | + os.putenv('PYTHONPATH', "%s:%s" % (os.getenv('PYTHONPATH', ''), ':'.join(python_path))) # for subprocesses |
47 | + |
48 | |
49 | from python_name import (Basecamel_case_nameWindow) |
50 | import python_name.helpers as helpers |
51 | |
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 | +#!/usr/bin/python |
57 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
58 | +# Copyright 2009 Didier Roche |
59 | +# |
60 | +# This file is part of Quickly ubuntu-application template |
61 | +# |
62 | +#This program is free software: you can redistribute it and/or modify it |
63 | +#under the terms of the GNU General Public License version 3, as published |
64 | +#by the Free Software Foundation. |
65 | + |
66 | +#This program is distributed in the hope that it will be useful, but |
67 | +#WITHOUT ANY WARRANTY; without even the implied warranties of |
68 | +#MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
69 | +#PURPOSE. See the GNU General Public License for more details. |
70 | + |
71 | +#You should have received a copy of the GNU General Public License along |
72 | +#with this program. If not, see <http://www.gnu.org/licenses/>. |
73 | + |
74 | +import os |
75 | +import sys |
76 | +import subprocess |
77 | +import webbrowser |
78 | + |
79 | +from internal import quicklyutils, packaging, launchpad_helper |
80 | +from internal import bzrutils |
81 | +from quickly import templatetools, configurationhandler, commands |
82 | +import license |
83 | + |
84 | +import logging |
85 | + |
86 | +from quickly import launchpadaccess |
87 | + |
88 | +import gettext |
89 | +from gettext import gettext as _ |
90 | +gettext.textdomain('quickly') |
91 | + |
92 | +options = ["--ppa",] |
93 | + |
94 | +def usage(): |
95 | + templatetools.print_usage(_('quickly submitubuntu [--ppa <ppa | group/ppa>] [release-version] [comments]')) |
96 | +def help(): |
97 | + print _("""Posts a release of your project and submit it the ubuntu |
98 | +application review board so that any users can see and install the |
99 | +application ont their system. |
100 | + |
101 | +Before running quickly submitubuntu, you should: create your account |
102 | +and a project page on http://launchpad.net. |
103 | +You also have to add a PPA to your launchpad account. |
104 | + |
105 | +Name, email, and version will be automatically changed in setup.py and |
106 | +bzr will tag the current source with the new version number. |
107 | + |
108 | +If not specified, the new version number will be 'YEAR.MONTH[.RELEASE]'. |
109 | + |
110 | +For example, the third release in July 2010 would be versioned 10.07.2. |
111 | + |
112 | +You may want to make sure that the description and long description in |
113 | +setup.py are up to date before releasing. |
114 | + |
115 | +You can optionally run 'quickly package' and test your package to make |
116 | +sure it installs as expected.""") |
117 | +def shell_completion(argv): |
118 | + ''' Complete --args ''' |
119 | + # option completion |
120 | + rv = [] |
121 | + if argv[-1].startswith("-"): |
122 | + rv = options |
123 | + elif len(argv) > 1 and argv[-2] == '--ppa': # if argument following --ppa, complete by ppa |
124 | + rv = packaging.shell_complete_ppa(argv[-1]) |
125 | + if rv: |
126 | + rv.sort() |
127 | + print ' '.join(rv) |
128 | + |
129 | +templatetools.handle_additional_parameters(sys.argv, help, shell_completion, usage=usage) |
130 | + |
131 | + |
132 | +launchpad = None |
133 | +project = None |
134 | +ppa_name = None |
135 | +i = 0 |
136 | +args = [] |
137 | +argv = sys.argv |
138 | + |
139 | +while i < len(argv): |
140 | + arg = argv[i] |
141 | + if arg.startswith('-'): |
142 | + if arg == '--ppa': |
143 | + if i + 1 < len(argv): |
144 | + ppa_name = argv[i + 1] |
145 | + i += 1 |
146 | + else: |
147 | + cmd = commands.get_command('submitubuntu', 'ubuntu-application') |
148 | + templatetools.usage_error(_("No PPA provided."), cmd=cmd) |
149 | + else: |
150 | + cmd = commands.get_command('submitubuntu', 'ubuntu-application') |
151 | + templatetools.usage_error(_("Unknown option: %s." % arg), cmd=cmd) |
152 | + else: |
153 | + args.append(arg) |
154 | + i += 1 |
155 | + |
156 | + commit_msg = None |
157 | +if len(args) == 1: |
158 | + proposed_version = None |
159 | +elif len(args) == 2: |
160 | + proposed_version = args[1] |
161 | +elif len(args) > 2: |
162 | + proposed_version = args[1] |
163 | + commit_msg = " ".join(args[2:]) |
164 | + |
165 | +# warning: project_name can be different from project.name (one local, one on launchpad) |
166 | +if not configurationhandler.project_config: |
167 | + configurationhandler.loadConfig() |
168 | +project_name = configurationhandler.project_config['project'] |
169 | + |
170 | +# connect to LP |
171 | +try: |
172 | + launchpad = launchpadaccess.initialize_lpi() |
173 | +except launchpadaccess.launchpad_connection_error, e: |
174 | + print(e) |
175 | + sys.exit(1) |
176 | + |
177 | +# push the gpg key and email to the env |
178 | +try: |
179 | + keyid = quicklyutils.get_right_gpg_key_id(launchpad) |
180 | +except quicklyutils.gpg_error, e: |
181 | + print(e) |
182 | + sys.exit(1) |
183 | + |
184 | +# get the project now and save the url into setup.py |
185 | +try: |
186 | + project = launchpadaccess.get_project(launchpad) |
187 | +except launchpadaccess.launchpad_project_error, e: |
188 | + print(e) |
189 | + sys.exit(1) |
190 | +project_url = launchpadaccess.launchpad_url + '/' + project.name |
191 | +quicklyutils.set_setup_value('url', project_url) |
192 | +about_dialog_file_name = quicklyutils.get_about_file_name() |
193 | +if about_dialog_file_name: |
194 | + quicklyutils.change_xml_elem(about_dialog_file_name, "object/property", |
195 | + "name", "website", project_url, {}) |
196 | + |
197 | +# choose right ppa parameter (users, etc.) ppa or staging if ppa_name is None |
198 | +try: |
199 | + (ppa_user, ppa_name, dput_ppa_name, ppa_url) = packaging.choose_ppa(launchpad, ppa_name) |
200 | +except packaging.user_team_not_found, e: |
201 | + print(_("User or Team %s not found on Launchpad") % e) |
202 | + sys.exit(1) |
203 | +except packaging.not_ppa_owner, e: |
204 | + print(_("You have to be a member of %s team to upload to its ppas") % e) |
205 | + sys.exit(1) |
206 | + |
207 | +try: |
208 | + 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 | +except packaging.ppa_not_found, e: |
210 | + 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 | + user_has_ppa = False |
212 | + for ppa_name, ppa_display_name in packaging.get_all_ppas(launchpad, ppa_user): |
213 | + print "%s - %s" % (ppa_name, ppa_display_name) |
214 | + user_has_ppa = True |
215 | + if user_has_ppa: |
216 | + print(_("You can temporary choose one of them with --ppa switch or definitely by executing quickly configure ppa <ppa_name>.")) |
217 | + sys.exit(1) |
218 | + |
219 | +# update license if needed. Don't change anything if not needed |
220 | +try: |
221 | + license.licensing() |
222 | +except license.LicenceError, error_message: |
223 | + print(error_message) |
224 | + sys.exit(1) |
225 | + |
226 | +try: |
227 | + release_version = packaging.updateversion(proposed_version) |
228 | +except (packaging.invalid_versionning_scheme, |
229 | + packaging.invalid_version_in_setup), error_message: |
230 | + print(error_message) |
231 | + sys.exit(1) |
232 | + |
233 | +if commit_msg is None: |
234 | + commit_msg = _('quickly released: %s' % release_version) |
235 | + |
236 | + |
237 | +# check if already released with this name |
238 | +bzr_instance = subprocess.Popen(["bzr", "tags"], stdout=subprocess.PIPE) |
239 | +bzr_tags, err = bzr_instance.communicate() |
240 | +if bzr_instance.returncode !=0: |
241 | + print(err) |
242 | + sys.exit(1) |
243 | +if release_version in bzr_tags: |
244 | + print _("ERROR: quickly can't release: %s seems to be already released. Choose another name.") % release_version |
245 | + sys.exit(1) |
246 | + |
247 | +# commit current changes |
248 | +packaging.filter_exec_command(["bzr", "add"]) |
249 | +return_code = packaging.filter_exec_command(["bzr", "commit", '--unchanged', '-m', |
250 | + _('commit before release')]) |
251 | +if return_code != 0 and return_code != 3: |
252 | + print _("ERROR: quickly can't release as it can't commit with bzr") |
253 | + sys.exit(return_code) |
254 | + |
255 | +# try to get last available version in bzr |
256 | +previous_version = None |
257 | +bzr_instance = subprocess.Popen(['bzr', 'tags', '--sort=time'], |
258 | + stdout=subprocess.PIPE) |
259 | +result, err = bzr_instance.communicate() |
260 | +if bzr_instance.returncode == 0 and result: |
261 | + output = result.split('\n') |
262 | + output.reverse() |
263 | + for tag_line in output: |
264 | + tag_elem = tag_line.split (' ') |
265 | + if not (tag_elem[-1] == '?' or tag_elem[-1] == ''): |
266 | + previous_version = tag_elem[0] |
267 | + break |
268 | + |
269 | +changelog = quicklyutils.collect_commit_messages(previous_version) |
270 | +# creation/update debian packaging |
271 | +return_code = packaging.updatepackaging(changelog, installopt=True) |
272 | +if return_code != 0: |
273 | + print _("ERROR: can't create or update ubuntu package") |
274 | + sys.exit(1) |
275 | + |
276 | +# add files, setup release version, commit and push ! |
277 | +#TODO: check or fix if we don't have an ssh key (don't tag otherwise to be able to release again) |
278 | +packaging.filter_exec_command(["bzr", "add"]) |
279 | +return_code = packaging.filter_exec_command(["bzr", "commit", '-m', commit_msg]) |
280 | +if return_code != 0 and return_code != 3: |
281 | + print _("ERROR: quickly can't release as it can't commit with bzr") |
282 | + sys.exit(return_code) |
283 | +packaging.filter_exec_command(["bzr", "tag", release_version]) # tag revision |
284 | + |
285 | +# check if pull branch is set |
286 | +bzr_instance = subprocess.Popen(["bzr", "info"], stdout=subprocess.PIPE) |
287 | +bzr_info, err = bzr_instance.communicate() |
288 | +if bzr_instance.returncode !=0: |
289 | + print(err) |
290 | + sys.exit(1) |
291 | + |
292 | + |
293 | +if (launchpadaccess.lp_server == "staging"): |
294 | + bzr_staging = "//staging/" |
295 | +else: |
296 | + bzr_staging = "" |
297 | + |
298 | +custom_location_in_info = None |
299 | +branch_location = [] |
300 | +custom_location = bzrutils.get_bzrbranch() |
301 | +if custom_location: |
302 | + branch_location = [custom_location] |
303 | + custom_location_in_info = custom_location.replace('lp:', '') |
304 | +# if no branch, create it in ~user_name/project_name/quickly_trunk |
305 | +# or switch from staging to production |
306 | +if ("parent branch" in bzr_info) and not ( |
307 | + (custom_location_in_info and custom_location_in_info not in bzr_info) or |
308 | + ((".staging." in bzr_info) and not bzr_staging) or |
309 | + (not (".staging." in bzr_info) and bzr_staging)): |
310 | + return_code = packaging.filter_exec_command(["bzr", "pull"]) |
311 | + if return_code != 0: |
312 | + print _("ERROR: quickly can't release: can't pull from launchpad.") |
313 | + sys.exit(return_code) |
314 | + |
315 | + return_code = packaging.filter_exec_command(["bzr", "push"]) |
316 | + if return_code != 0: |
317 | + print _("ERROR: quickly can't release: can't push to launchpad.") |
318 | + sys.exit(return_code) |
319 | +else: |
320 | + if not branch_location: |
321 | + branch_location = ['lp:', bzr_staging, '~', launchpad.me.name, '/', project.name, '/quickly_trunk'] |
322 | + return_code = packaging.filter_exec_command(["bzr", "push", "--remember", "--overwrite", "".join(branch_location)]) |
323 | + if return_code != 0: |
324 | + print _("ERROR: quickly can't release: can't push to launchpad.") |
325 | + sys.exit(return_code) |
326 | + |
327 | + # make first pull too |
328 | + return_code = packaging.filter_exec_command(["bzr", "pull", "--remember", "".join(branch_location)]) |
329 | + if return_code != 0: |
330 | + print _("ERROR: quickly can't release correctly: can't pull from launchpad.") |
331 | + sys.exit(return_code) |
332 | + |
333 | + |
334 | +# upload to launchpad |
335 | +print _("pushing to launchpad") |
336 | +return_code = packaging.push_to_ppa(dput_ppa_name, "../%s_%s_source.changes" % (project_name, release_version), keyid=keyid) != 0 |
337 | +if return_code != 0: |
338 | + sys.exit(return_code) |
339 | + |
340 | +#create new release_date |
341 | +launchpad_helper.push_tarball_to_launchpad(project, release_version, |
342 | + "../%s_%s.tar.gz" % (project_name, |
343 | + release_version), changelog) |
344 | + |
345 | +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 | +print _("Then your application will be reviewed by the application review board.") |
347 | + |
348 | +# as launchpad-open doesn't support staging server, put an url |
349 | +if launchpadaccess.lp_server == "staging": |
350 | + webbrowser.open(launchpadaccess.LAUNCHPAD_CODE_STAGING_URL + '/' + project.name) |
351 | +else: |
352 | + webbrowser.open(launchpadaccess.LAUNCHPAD_URL + '/' + project.name) |
353 | |
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 | os.system("find . -name '*.py' -exec %s {} \;" % sedline) |
359 | os.system("%s bin/%s" % (sedline, project_name)) |
360 | |
361 | +### 0.7 update |
362 | +if project_version < '0.7': |
363 | + # support /opt installation |
364 | + content_to_update = '''python_path = [] |
365 | +if os.path.abspath(__file__).startswith('/opt'): |
366 | + syspath = sys.path[:] # copy to avoid infinite loop in pending objects |
367 | + for path in syspath: |
368 | + opt_path = path.replace('/usr', '/opt/extras.ubuntu.com/%(python_name)s') |
369 | + python_path.insert(0, opt_path) |
370 | + sys.path.insert(0, opt_path) |
371 | +if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY, '%(python_name)s')) |
372 | + and PROJECT_ROOT_DIRECTORY not in sys.path): |
373 | + python_path.insert(0, PROJECT_ROOT_DIRECTORY) |
374 | + sys.path.insert(0, PROJECT_ROOT_DIRECTORY) |
375 | +if python_path: |
376 | + os.putenv('PYTHONPATH', "%%s:%%s" %% (os.getenv('PYTHONPATH', ''), ':'.join(python_path))) # for subprocesses''' % {'python_name' : python_name} |
377 | + |
378 | + try: |
379 | + templatetools.update_file_content("./bin/%s" % project_name, |
380 | + 'if (os.path.exists(os.path.join(PROJECT_ROOT_DIRECTORY', |
381 | + " os.putenv('PYTHONPATH', PROJECT_ROOT_DIRECTORY) # for subprocesses", |
382 | + content_to_update) |
383 | + except templatetools.CantUpdateFile, e: |
384 | + 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 | + |
386 | + |
387 | sys.exit(0) |
388 | |
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 | # you're warned :) |
394 | |
395 | # quickly version used for project format compatibility |
396 | -__version__ = '0.6.1' |
397 | +__version__ = '0.7' |
398 | |
399 | # where quickly will head for quickly data (for instance, templates) |
400 | # by default, this is ../data, relative to trunk layout |
401 | |
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 | |
407 | class bad_project_name(Exception): |
408 | pass |
409 | +class CantUpdateFile(Exception): |
410 | + def __init__(self, msg): |
411 | + self.msg = msg |
412 | + def __str__(self): |
413 | + return self.msg |
414 | |
415 | def handle_additional_parameters(args, help=None, shell_completion=None, usage=None): |
416 | """Enable handling additional parameter like help or shell_completion""" |
417 | @@ -88,6 +93,46 @@ |
418 | mode = stat.S_IMODE(st.st_mode) |
419 | os.chmod(dest_file_name, mode) |
420 | |
421 | +def update_file_content(filename, start_marker, end_marker, replacing_content): |
422 | + """Safely replace the content of a file""" |
423 | + |
424 | + skip_until_end_found = False |
425 | + marker_found = False |
426 | + try: |
427 | + filename = os.path.abspath(filename) |
428 | + ftarget_file_name = file(filename, 'r') |
429 | + ftarget_file_name_out = file(ftarget_file_name.name + '.new', 'w') |
430 | + for line in ftarget_file_name: |
431 | + # seek if we have to add something |
432 | + if start_marker in line: |
433 | + skip_until_end_found = True |
434 | + marker_found = True |
435 | + ftarget_file_name_out.write(replacing_content) |
436 | + |
437 | + if end_marker in line: |
438 | + skip_until_end_found = False |
439 | + |
440 | + if not skip_until_end_found: |
441 | + ftarget_file_name_out.write(line) |
442 | + |
443 | + ftarget_file_name.close() |
444 | + ftarget_file_name_out.close() |
445 | + |
446 | + if skip_until_end_found: # that means we didn't find the end_tag, don't copy the file |
447 | + os.remove(ftarget_file_name_out.name) |
448 | + raise CantUpdateFile(_("%s was not found in the file %s.") % (end_marker, ftarget_file_name.name)) |
449 | + |
450 | + if not marker_found: |
451 | + os.remove(ftarget_file_name_out.name) |
452 | + raise CantUpdateFile(_("%s was not found in the file %s.") % (start_marker, ftarget_file_name.name)) |
453 | + |
454 | + apply_file_rights(ftarget_file_name.name, ftarget_file_name_out.name) |
455 | + os.rename(ftarget_file_name_out.name, ftarget_file_name.name) |
456 | + |
457 | + except (OSError, IOError), e: |
458 | + msg = _("%s file was not found or can't update it") % ftarget_file_name |
459 | + raise CantUpdateFile(msg) |
460 | + |
461 | def in_verbose_mode(): |
462 | """Return true if verbose mode is on""" |
463 |
+# 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.