People: |
|
---|
Initial version of what will become the best installer in the world - ever
Review Request #1696 — Created June 28, 2010 and discarded
Initial version of installer with example json file structure for ubuntu that shows working source, easy_install and apt type installs.
All manual - there might be a slight problem with lucene which needs a patch (one more command in source type install for it).
-
-
input.json (Diff revision 1) Hm - I still think it's weird to have an array of single entry dicts like this. Didn't we agree upon: "database": { "mysql": { ... } "pqsql": { ... } ...etc? }
-
install.py (Diff revision 1) From what I gather, we want these in alphabetical order, so: import os import platform ...
-
-
-
-
-
-
-
-
-
-
-
-
MA
-
-
install.py (Diff revision 1) Personally I put them in order of lowest level to highest level, so common stuff at the top, and more specialized stuff at the bottom .. old habit .. it also happily turns out to make it look nice line length wise :) import os import sys import shutil import platform import simplejson as json from types import ListType from subprocess import Popen, PIPE But really no-one cares .. it's just whatever you're comfortable with and whatever makes it easy to read later; alphabetical is good too.
-
install.py (Diff revision 1) According to good old guido's python style guide, class is preceded with two blank lines. That also goes for tabs characters, they should all be 4 spaces I reckon: http://www.python.org/dev/peps/pep-0008/
-
install.py (Diff revision 1) 'file' is a reserved keyword. I wouldn't use it for variable nor attribute names myself. Also I see that the file is actually a filename so probably I'd call it fileName :)
-
install.py (Diff revision 1) No need for the brackets there: self.arch, self.distro = self._get_osarch() is fine
-
install.py (Diff revision 1) No need for the i = 0 nor i = i + 1. Just use enumerate: for i, o in enumerate(options): ... does the same thing
-
-
-
install.py (Diff revision 1) Personally I don't like the redundant use of the valid variable .. it might be OK with some people, but I'd prefer something like: while 1: do stuff if done: break sort of style
-
install.py (Diff revision 1) I'd add a try..except around the 'int' conversion, and only need to convert it once .. maybe something like: try: choice = int(choice) except: continue # Basically the choice is not an int, just ignore it .. probably should print some insult or something :P if choice in range(0, len(options)): break return choice
-
-
-
install.py (Diff revision 1) You can just add lists together, no need for the second loop. Either: options += opt.keys() or: options.extend(opt.keys())
-
install.py (Diff revision 1) This is just another option, I like this style myself, but some may see it as a bit freaky: descr = { 'database': 'Choose database:', 'web_server': 'Choose web server:' }.get(key, 'Not set!')
-
-
install.py (Diff revision 1) You can use a list comprehension here: pkg_list = [pkg['pkg_name'] for pkg in self.pkgmgr_list]
-
install.py (Diff revision 1) self._source_install() already loops through self.source_list(), no need to call it once for every item.
-
-
install.py (Diff revision 1) I'd use a try: finally: block here oldDir = os.getcwd() os.mkdir('/tmp/reviewboard_installer') try: ... finally: os.chdir(oldDir) shutil.rmtree('/tmp/reviewboard_installer')
MA
Change Summary:
Removed trailing spaces from json file. Last revision addresses problems found in earlier review round.
Diff: |
Revision 3 (+258) |
---|
-
-
input.json (Diff revision 4) I'm not exactly sure what the semantics of "an array of dicts of a single element" are here. Is there a particular meaning? If not, I'd like to see it just be one dict: { "mysql" : { ... }, "pgsql" : { ... }, ... }
-
-
-
-
install.py (Diff revision 4) Since you're doing a numeric comparison, it'd be a lot easier to use >= 0 and < len(options). The way you've written this it's generating a list and then checking every element.
-
install.py (Diff revision 4) I wonder if instead of having 3 lists and checking the string for each one, if it might be cleaner to have a dict of method name : list { 'pkgmgr': [], 'easy_install': [], 'source': [] } and then you could just do self.pkgs[method].append(pkg)
-
-
install.py (Diff revision 4) After this, you should probably check p1.returncode to make sure that it returned 0 and not an error.
-
-
-
install.py (Diff revision 4) Can you explicitly pass in the mode as 0700? By default os.mkdir() uses 0777, which is a pretty big security risk when this is (presumably) running as a privileged user.
-
install.py (Diff revision 4) Hmm, so your installer has a dependency on wget? And it's assuming that everything's a .tar.gz?
MA
Change Summary:
Took into account a lot of comments from previous reviews and irc talks. Error handling is now much better. Versions stuff and description are only provisional, and will be implemented properly later in the process - we might switch to description being hard-coded later on, but as I designed json files it made sense to put them in there, at least temporarily.
Diff: |
Revision 5 (+488) |
---|
MA
-
-
-
install.py (Diff revision 5) I'd just add a function comment in here: """Loads our settings from the provided json config file"""
-
-
MA
-
-
install.py (Diff revision 5) It'd be nice to have a nice comment here explaining what the function does, perhaps with an example output too..
-
install.py (Diff revision 5) You can get rid of the extra 'i' variable by using enumerate: default_num = -1 for (k, v), i in self.depmap[cat]['options'].items(): opt_str += "[%d] %s: %s\n" % (i, v['name'], v['description']) if k == self.depmap[cat]['default']: default_num = i
-
install.py (Diff revision 5) I'd probably go with: choice = raw_input(opt_str).strip() Just to remove extra spaces
MA
-
-
install.py (Diff revision 5) In my code I make all top level classes children of object: class File2(object): This makes it a 'new style class' rather than an 'old style class' http://www.python.org/doc/newstyle/
-
install.py (Diff revision 5) Function comments should be in the form of a string. That way autodoc tools like Sphinx pick it up well. And they can compile all of your todos into a single page and cool stuff like that
-
-
install.py (Diff revision 5) dep = self.depmap[pkg] pkgver = dep['default'] pkgdata = dep[pkgver] method = pkgdata['method'] if method == 'pkgmgr': ... # Just less lookups .. nit picking .. sorry If you wanted to be really pythony, you could switch the if statements to: myList = {'pkgmgr': self.pkgmgr_list, 'easy_install', self.easy_list}.get(method, self.source_list) myList.append(pkg) in fact it might be a neat idea to init that dictionary of list names to actual lists in the __init__: self.name2list = {'pkgmgr': self.pkgmgr_list, 'easy_install', self.easy_list} then you could use it where ever with: myList = self.name2list.get(methodName, self.source_list)
-
install.py (Diff revision 5) I probably would move the file reading out to a 'process' or 'read' method .. just a personal preference, and keeps with how most python classes are .. you init a 'reader' object, then you fill with some file..
-
install.py (Diff revision 5) This whole block looks similar to above, I'm sure you could probably merge them into a single reusable func. Possibly a base class or utility class sort of thing
-
install.py (Diff revision 5) could be done with enumerate as above for (k, v), i in enumerate(self.depmap.items()): ...
-
install.py (Diff revision 5) either: deps = self.depmap[self.version]['dependencies']['requirements'][:] or: deps = [] deps.extend(self.depmap[self.version]['dependencies']['requirements'])
-
install.py (Diff revision 5) deps.extend(self.depmap[self.version]['dependencies']['optional']) or possibly: deps += self.depmap[self.version]['dependencies']['optional']