I'm cleaning build directories produced by GNOME build tool, JHBuild. This tool either downloads tarballs or clones git repositories, depending on set-up. After that, it proceeds to compilation (and then installation). Once in a while, something gets screwed up, and I need to clean the build directories so that I can start from scratch (because I don't know how to fix some of these problems).
Here's how I did it, and I'd like you to tell me if it can be improved:
import os
import subprocess
top_level = os.path.expanduser("~/src/gnome")
for filename in os.listdir(top_level):
full_path = "{}/{}".format(top_level, filename)
if os.path.isdir(full_path):
cmd = "cd ~/src/gnome/{} && git clean -dfx".format(filename)
if subprocess.call(cmd, shell=True) != 0:
cmd = "cd ~/src/gnome/{} && make distclean".format(filename)
if subprocess.call(cmd, shell=True) != 0:
cmd = "cd ~/src/gnome/{} && make clean".format(filename)
subprocess.call(cmd, shell=True)
1 Answer 1
full_path = "{}/{}".format(top_level, filename)
You can use os.path.join(top_level, filename)
for that. That way it will also work on any system which does not use /
as a directory separator (that's not really a realistic concern in this case, but using os.path.join
doesn't cost you anything and is a good practice to get used to).
cmd = "cd ~/src/gnome/{} && git clean -dfx".format(filename)
First of all spelling out ~/src/gnome
again is bad practice. This way if you want to change it to a different directory you have to change it in all 4 places. You already have it in the top_level
variable, so you should use that variable everywhere.
On second thought you should actually not use top_level
here, because what you're doing here is you're joining top_level
and filename
. However you already did that with full_path
. So you should just use full_path
here.
You should also consider using os.chdir
instead of cd
in the shell. This way you only have to change the directory once per iteration instead of on every call. I.e. you can just do:
if os.path.isdir(full_path):
os.chdir(full_path)
if subprocess.call("git clean -dfx", shell=True) != 0:
if subprocess.call("make distclean", shell=True) != 0:
subprocess.call("make clean", shell=True)
(Note that since full_path
is an absolute path, it doesn't matter that you don't chdir
back at the end of each iteration.)
Another good habit to get into is to not use shell=True
, but instead pass in a list with command and the arguments, e.g. subprocess.call(["make", "clean"])
. It doesn't make a difference in this case, but in cases where your parameters may contain spaces, it saves you the trouble of escaping them.
-
\$\begingroup\$ Regarding your very last comment, I'm tempted to change the subprocess to something like
subprocess.call("git clean -dfx".split())
. Is that kool? \$\endgroup\$tshepang– tshepang2011年03月26日 18:03:46 +00:00Commented Mar 26, 2011 at 18:03 -
\$\begingroup\$ @Tshepang: The point of passing in an array instead of
shell=True
is that it will handle arguments with spaces or shell-metacharacters automatically correctly without you having to worry about. Usingsplit
circumvents this again (as far as spaces are concerned anyway), so there's little point in that. Since in this case you know that your arguments don't contain any funny characters, you can just keep usingshell=True
if you don't want to pass in a spelled-out array. \$\endgroup\$sepp2k– sepp2k2011年03月26日 18:09:31 +00:00Commented Mar 26, 2011 at 18:09 -
\$\begingroup\$ In such cases, won't shlex.split() be useful? \$\endgroup\$tshepang– tshepang2011年03月26日 18:16:40 +00:00Commented Mar 26, 2011 at 18:16
-
1\$\begingroup\$ @Tshepang: I don't see how. If you already know the arguments,
subprocess.call(shlex.split('some_command "some filename"'))
buys you nothing oversubprocess.call(["some_command", "some filename"]
and IMHO has a higher chance that you might forget the quotes. However if the filename is inside a variable,subprocess.call(["some_comand", filename])
still works no matter which special charactersfilename
contains, while usingshlex.split
would require you to somehow escape the contents offilename
first, in which case you could have just usedshell=True
in the first place. \$\endgroup\$sepp2k– sepp2k2011年03月26日 18:31:29 +00:00Commented Mar 26, 2011 at 18:31