Merge lp:~mikemc/dirspec/add-exefind into lp:dirspec
| Status: | Merged |
|---|---|
| Merged at revision: | 8 |
| Proposed branch: | lp:~mikemc/dirspec/add-exefind |
| Merge into: | lp:dirspec |
| Diff against target: |
257 lines (+215/-1) 2 files modified
dirspec/tests/test_utils.py (+141/-1) dirspec/utils.py (+74/-0) |
| To merge this branch: | bzr merge lp:~mikemc/dirspec/add-exefind |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| dobey (community) | 2012-07-06 | Needs Fixing on 2012-07-06 | |
|
Review via email:
|
|||
Commit Message
- Add function for getting executable command lines across projects and platforms and packagings (LP: #1021833)
Description of the Change
- Add function for getting executable command lines across projects and platforms and packagings (LP: #1021833)
- 9. By Mike McCracken on 2012-07-09
-
Add support for installed linux using generated-
at-install module.constants to find BIN_DIR
Avoid using 'python ' + exe on non-mac/win
Refactor tests.
| Mike McCracken (mikemc) wrote : | # |
rev 9 addresses the __all__ attr, and the issue of a linux fallback.
On linux, the difference between installed and not installed is not the sys.frozen attribute.
I've adapted the approach from ubuntu_
On linux, if we are running from source, we find the path relative to the module, eg. srctree/bin next to srctree/ubuntu_sso. If there's something there, we use it, otherwise we look at the generated constants.py that is generated when setup.py is run.
Clients of this code other than ubuntu-sso-client would need to add a constants.py with a BIN_DIR attribute to work the same way. However, only sso-client currently launches any processes using Popen on linux - the other projects use DBus.
I am still open to suggestions about what to do wrt. the python exe name - I don't completely understand when & why that'll change.
| Mike McCracken (mikemc) wrote : | # |
Also, please elaborate on your naming concerns. I'm open to suggestions!
- 10. By Mike McCracken on 2012-07-09
-
Remove an unused line
| dobey (dobey) wrote : | # |
I don't like the name, because it's platform-specific, as there are no .exes on OSX or Linux generally (C# and things under WINE, notwithstanding). Also, dirspec already has a utils.py module, and this is but a utility function, albeit with a few additional private helper functions.
Also, I'm really not liking the API, now that I've thought about it more. The idea of having a special module in one's code that gets passed in, and must have specific platform-dependent constants in it, is rather nasty. I think all these things the code is poking at a module for, would be better passed in as kwargs on the entry point method.
As for the python prefix issue, we can't just prepend it anyway. It won't work very well for things which aren't written in Python. If someone else wanted to use the library in their code to launch a non-python application, for whatever reason, prefixing python here would break that. So I'd rather avoid us having that here if possible. It would be nice if we could find some other way to solve this problem for running programs from tree, on Windows/OS X. Maybe I don't understand that problem fully enough yet, and need to have it explained better to me, but it seems like a separate problem from the need to avoid duplicating the code to find the files on disk to run.
| Mike McCracken (mikemc) wrote : | # |
naming - no prob moving it to utils. call it utils.get_cmdline
originally wanted an API as smart as possible, otherwise we're not removing much complexity from the callsites.
But I don't disagree with the comments about the module pokery. It's
not a very intuitive API.
So, here's what it'd look like if we avoided module pokery:
We need to tell it the name of the executable we're looking for, and
three extra things:
- what directory to look in , or near (best we can do is pass in
__file__ from something)
-- Unless we give it more info, like I was by passing the module, all
it can do is look for a bin/ in cwd, then cwd/.. , etc...
- only for darwin: what the name of the sub-app will be if packaged.
- only for linux: we need to give it a way to get the compiled-in
BIN_DIR constant for SSO, which is at ubuntu_
Giving all this explicitly (and we always need to give all the args,
because the same code should work on all platforms) makes a kind of
messy call site:
cmdline = get_cmdline(
ubuntuone.
"Ubuntu One Syncdaemon.app") # no constants module
cmdline = get_cmdline(
ubuntu_
"Ubuntu SSO.app", # or, probably DARWIN_
dir_constants
# here's what the function's signature would look like, with some overly descriptive names that I didn't think about too hard:
def get_cmdline(
| Mike McCracken (mikemc) wrote : | # |
Regarding prepending 'python ', the issue is that the scripts now have
an absolute path to /usr/bin/python, but on windows and darwin we have
a buildout-generated python wrapper that sets up PYTHONPATH to point
to the eggs in the buildout directory, etc, so we need to use that.
One option would be to avoid using the buildout python, and either
just set PYTHONPATH to include all the eggs while developing, or use
virtualenv, or something. However, that's a rather big change.
If we want to stick with the buildout python, we need to just prepend
'python' to the cmdline and use Popen(shell=True).
All that said, I think it'd be fine to move that out of this general
library function. There'd just be a bit of extra code after we call it
each time:
cmdline = get_cmdline(blah)
if getattr(sys, "frozen", None) is None and
sys.platform in ('win32','darwin'):
# then we are in a source tree, using the buildout python wrapper,
# and we need to make sure we run it using that, so that its path
# makes sense.
cmdline = 'python ' + cmdline
for ease of writing tests, we might also want to wrap that in a
function on the client end (ie, not in dirspec)
- 11. By Mike McCracken on 2012-07-09
-
- Move get_cmdline into utils.py
- Don't prepend 'python ' to cmdline, this is too specific to buildout
python and should be done by clients of this code.
| dobey (dobey) wrote : | # |
So, for the case where all the arguments are passed in, the API doesn't have to be overly complex to allow for it. We can simply require them to be passed in **kwargs, and document what they are called. This can keep the basic API nice and simple, and we can have additional things for the cases where we need them.
| dobey (dobey) wrote : | # |
This is more what I was thinking, in terms of having a 'smarter' API, that we could just use via kwargs, and simply state in the docstring what kwargs are available for use, though they aren't required: http://
I haven't updated the docstring in that revision, but there are the fallback_dirs= and app_names= kwargs, to specify a list of fallback directories, and a dict of app names for darwin.

First thing I notice this will need is an __all__ to only export the public method.
Also, I don't like the naming, and I think we should probably have a better fallback for Linux/BSD/etc… We'll also need to deal with varying python executable name, such as python3 instead of python.