2. If you’re wondering why we’re building up paths manually with
%s
instead of the
os.path.join
command
we saw earlier, it’s because
path.join
will use backslashes if you run the script from Windows, but we
definitely want forward slashes on the server
3. There is a Fabric “cd” command, but I figured it was one thing too many to add in this chapter.
Hopefully each of those helper functions have fairly self-descriptive names. Because any
function in a fabfile can theoretically be invoked from the command line, I’ve used the
convention of a leading underscore to indicate that they’re not meant to be part of the
“public API” of the fabfile. Here they are in chronological order.
Here’s how we build our directory structure, in a way that doesn’t fall down if it already
exists:
deploy_tools/fabfile.py.
def
_create_directory_structure_if_necessary
(
site_folder
):
for
subfolder
in
(
'database'
,
'static'
,
'virtualenv'
,
'source'
):
run
(
'mkdir -p
%s
/
%s
'
%
(
site_folder
,
subfolder
))
#
run
is the most common Fabric command. It says “run this shell command on
the server”.
mkdir -p
is a useful flavor of
mkdir
, which is better in two ways: it can create
directories several levels deep, and it only creates them if necessary. So,
mkdir -
p /tmp/foo/bar
will create the directory
bar
but also its parent directory
foo
if
it needs to. It also won’t complain if
bar
already exists.
2
Next we want to pull down our source code:
deploy_tools/fabfile.py.
def
_get_latest_source
(
source_folder
):
if
exists
(
source_folder
+
'/.git'
):
#
run
(
'cd
%s
&& git fetch'
%
(
source_folder
,))
#
else
:
run
(
'git clone
%s
%s
'
%
(
REPO_URL
,
source_folder
))
#
current_commit
=
local
(
"git log -n 1 --format=%H"
,
capture
=
True
)
#
run
(
'cd
%s
&& git reset --hard
%s
'
%
(
source_folder
,
current_commit
))
#
exists
checks whether a directory or file already exists on the server. We look
for the
.git
hidden folder to check whether the repo has already been cloned in
that folder.
Many commands start with a
cd
in order to set the current working directory.
Fabric doesn’t have any state, so it doesn’t remember what directory you’re in
from one
run
to the next.
3
git fetch
inside an existing repository pulls down all the latest commits from
the Web.
Alternatively we use
git clone
with the repo URL to bring down a fresh source
tree.
Breakdown of a Fabric Script for Our Deployment
|
159