Closed
Bug 802265
Opened 11 years ago
Closed 3 months ago
versionbump.py should have a --tag-only option
Categories
(Testing :: Mozbase, defect)
Testing
Mozbase
Tracking
(Not tracked)
RESOLVED
WORKSFORME
People
(Reporter: k0scist, Assigned: gbrown)
References
Details
Attachments
(2 files, 2 obsolete files)
28.75 KB,
patch
|
k0scist
:
feedback-
|
Details | Diff | Splinter Review |
17.35 KB,
text/plain
|
Details |
currently, versionbump.py is fairly monolithic. One consequence of this is that if one step fails, like for instance if i leave the interactive password prompt open too long and a git pull request times out, then it is hard to resume the step. We should have an e.g. --tag-only option to deal with this (and possibly an --upload-only switch for uploading to pypi).
Reporter | ||
Updated•11 years ago
|
Whiteboard: [good first bug][mentor=jhammel][lang=py]
Reporter | ||
Comment 1•11 years ago
|
||
As a long term plan, we should separate out the various components in actions with dependencies. In fact, a general purpose python implementation would be nice. For the immediate term, this could be done or we could just have if-else blocks based on --tag-only (much quicker)
Reporter | ||
Comment 2•11 years ago
|
||
So for the general purpose implementation we should have something like a list of actions that get run that correspond to various code blocks. These could be e.g. 'bump_setup_py_versions', 'git_tag', 'upload_to_pypi' etc. Each of these should be separated to their own functions. The main section can then call each of these in order. doing e.g. '--tag-only' or what not should remove the unneeded actions. I can provide example code if this makes sense or talk via IRC or other
Updated•10 years ago
|
Assignee: nobody → mihneadb
Comment 3•10 years ago
|
||
Here's a prototype of what was requested. I kept the globals()['var'] trick because it seems the easiest way in which we can have the actions as functions that get looked up by name and executed. Otherwise, we'd have to do something with the return values and the "do_action" function would get more complicated. Since the diff may be misleading, you can see the whole file here: http://www.pastebin.mozilla.org/1995889 Basically new parameters and new actions would be trivial to add this way.
Attachment #692443 -
Flags: feedback?(jhammel)
Reporter | ||
Comment 4•10 years ago
|
||
Comment on attachment 692443 [details] [diff] [review] refactor as requested If we're going to do a drastic rewrite, we probably shouldn't use global variables. Instead, we should probably use a class for this. + if options.dry_run: Should be an instance variable + # export the data + globals()['info'] = info + globals()['dependencies'] = dependencies + globals()['directories'] = directories Yeah...let's not do this anymore ++methods = { + 'pkg_info': pkg_info, + 'print_pkg_info': print_pkg_info, + 'print_pypi_versions': print_pypi_versions, + 'check_for_pypirc': check_for_pypirc, + 'check_for_master_branch': check_for_master_branch, + 'check_for_clean_dir': check_for_clean_dir, + 'parse_pkg_versions': parse_pkg_versions, + 'check_bumping_dependencies': check_bumping_dependencies, + 'check_for_latest_revision': check_for_latest_revision, + 'bump_desired_packages': bump_desired_packages, + 'bump_dependent_packages': bump_dependent_packages, + 'write_diff': write_diff, + 'check_for_msg': check_for_msg, + 'push_changes': push_changes, + 'tag_changes': tag_changes, + 'upload_to_pypi': upload_to_pypi, + } Again, let's not do this. A decorator would be more appropriate. +method_deps = {} +method_deps['info'] = ['pkg_info', 'print_pkg_info'] +method_deps['pypi_versions'] = ['pkg_info', 'print_pypi_versions'] +method_deps['bump'] = ['pkg_info', 'check_for_master_branch', 'check_for_clean_dir', + 'parse_pkg_versions', 'check_bumping_dependencies', + 'check_for_latest_revision', 'bump_desired_packages', + 'bump_dependent_packages'] +method_deps['diff'] = method_deps['bump'] + ['write_diff'] +method_deps['push'] = method_deps['bump'] + ['push_changes'] +method_deps['tag'] = method_deps['push'] + ['tag_changes'] +method_deps['tag_only'] = ['pkg_info', 'check_for_master_branch', + 'check_for_clean_dir', 'check_for_latest_revision', + 'parse_pkg_versions'] +method_deps['upload'] = method_deps['tag'] + ['check_for_pypirc', 'upload_to_pypi'] Again, let's not do this ;) Since we have e.g. +method_deps['diff'] = method_deps['bump'] + ['write_diff'] its probably better to build a system that will recursively descend through dependencies instead of trying to keep a flat list. + globals()['args'] = args + globals()['options'] = options + globals()['parser'] = parser Let's not do this + if options.info: + do_action('info') + parser.exit() + + if options.pypi_versions: + do_action('pypi_versions') + parser.exit() + + if options.diff and not options.dry_run: + do_action('diff') + sys.exit() + + if options.tag_only: + do_action('tag_only') + sys.exit() + + if options.tag: + do_action('tag') + sys.exit() + + do_action('upload') A few things here: * + if options.diff and not options.dry_run: Probably not the best pattern. Instead, it'd be easier to make the functions respond to options. * Similarly, if you do this, you can make a list of actions an iterate over them (or something similar, potentially relying on recursive dependencies). I generally avoid if-else trees unless they're really necessary and in this case they aren't. In this case, its not necessary except for the above bullet point: you have a table of things to do which are functions which take no arguments * Again, I'd rather off load most of this logic to a class ---- Backing off a bit, what problems are we solving here? * It would be nice to have a simple class that encapsulates the dependencies that actions need * This class should take configuration from the command line and "other" * [Recommended] there should be a decorator to label what "actions" are required for other actions. As I've often done, I've seriously underestimated the amount of work this bug requires ;) I'm happy to stub out an outline when I get a chance, but this will actually be a, ahem, "interesting" architecture. In short.... class Dependencies(object): """dependency decorator""" def __call__(self, *dependencies): """return a function that decorates a function and notes the dependencies""" def do(self, action): """perform the function `action`""" action = Dependencies() class VersionBump(self): defaults = {} def __init__(self, various, options, and, args): """setup VersionBump environment, configuration, etc""" @action('info', ...) def tag(self): """"something about tagging; it depends on info being run here""" def info(...): def main(args=sys.argv[1:]) parser = OptionParser() # TODO: add options, probably from the VersionBump class options, args = parser.parse_args(args) arguments = dict([(i, j) for i, j in options.__dict__.items() if i in VersionBump.defaults]) versionbump = VersionBump(**arguments) # and something about the versions actions = [] # some list of actions from the command line for a in actions: getattr(versionbump, action)() This is basically just a sketch, but similar to what I would do.
Attachment #692443 -
Flags: feedback?(jhammel) → feedback-
Reporter | ||
Updated•10 years ago
|
Whiteboard: [good first bug][mentor=jhammel][lang=py]
Comment 5•10 years ago
|
||
As discussed on IRC, work in progress: http://pastebin.mozilla.org/2009121
Comment 6•10 years ago
|
||
The file looks like this: http://pastebin.mozilla.org/2035641 So I'm not sure about the build_actions & run() part, suggestions are welcome. Otherwise, the core ideas are as discussed.
Attachment #692443 -
Attachment is obsolete: true
Attachment #697418 -
Flags: feedback?(jhammel)
Comment 7•10 years ago
|
||
Forgot to add --tag-only :). http://pastebin.mozilla.org/2035648
Attachment #697418 -
Attachment is obsolete: true
Attachment #697418 -
Flags: feedback?(jhammel)
Attachment #697422 -
Flags: feedback?(jhammel)
Reporter | ||
Comment 8•10 years ago
|
||
Sorry this has taken me so long to get to. :mihneadb, could you upload the rewritten version of the file? So much has changed that the diff is pretty hard to parse
Comment 9•10 years ago
|
||
I have, there's the URL in #c7. http://pastebin.mozilla.org/2035648
Reporter | ||
Comment 10•10 years ago
|
||
Reporter | ||
Comment 11•10 years ago
|
||
Comment on attachment 697422 [details] [diff] [review] rewrote vb.py So.... This is really complicated and hard to read. I imagine it would also be very hard to debug. While I'm not going to take the time to go through this verbosely, a few things: - build_actions_list seems pretty unnecessary. Really, 'run' should take an action (or list of actions) to run directly from the command line. - ... this also implies that casting the CLI options directly to a dict to use in the ctor doesn't really work. It implies that the class is usable other than via CLI invocation, which isn't effectively true - quit() should never be an action (or a function, for that matter) - actions should allow recursive dependencies. ABICT, they don't In any case, I somewhat regret calling for an action-dependency system now. While I do think it is, in the long term, the right path, it will be very hard to get right. I will try to take a stab at it sometime in the future, but for now it seems a lot of work for a tiny bit of benefit.
Attachment #697422 -
Flags: feedback?(jhammel) → feedback-
Comment 12•10 years ago
|
||
(In reply to Jeff Hammel [:jhammel] from comment #11) > Comment on attachment 697422 [details] [diff] [review] > rewrote vb.py > > So.... > > This is really complicated and hard to read. I imagine it would also be > very hard to debug. Except for the class/dependencies part, it is still the existing code from vb.py. Do you mean the dependency system is complicated? > While I'm not going to take the time to go through this > verbosely, a few things: > > - build_actions_list seems pretty unnecessary. Really, 'run' should take an > action (or list of actions) to run directly from the command line. > > - ... this also implies that casting the CLI options directly to a dict to > use in the ctor doesn't really work. It implies that the class is usable > other than via CLI invocation, which isn't effectively true Right, as I said, I don't know how to "correctly" do that part. Suggestions are welcome! :) > > - quit() should never be an action (or a function, for that matter) > > - actions should allow recursive dependencies. ABICT, they don't I'm not sure what you mean. if F depends on G and H depends on F, when you call H both G and F will get called. > > In any case, I somewhat regret calling for an action-dependency system now. > While I do think it is, in the long term, the right path, it will be very > hard to get right. I will try to take a stab at it sometime in the future, > but for now it seems a lot of work for a tiny bit of benefit. Sure, let me know if I can help. :)
Updated•10 years ago
|
Assignee: mihneadb → nobody
Comment 13•9 years ago
|
||
versionbump.py no longer exists after bug 949600.
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → WONTFIX
Comment 14•9 years ago
|
||
I don't think we should get this bug closed. Instead get it ported via bug 974184 for hg.m.o.
Status: RESOLVED → REOPENED
Resolution: WONTFIX → ---
Updated•5 months ago
|
Severity: normal → S3
![]() |
Assignee | |
Comment 15•3 months ago
|
||
There's only versioninfo.py now (via bug 974184); I don't think this bug is relevant any more.
Assignee: nobody → gbrown
Status: REOPENED → RESOLVED
Closed: 9 years ago → 3 months ago
Resolution: --- → WORKSFORME
You need to log in
before you can comment on or make changes to this bug.
Description
•