22
22
import sys, os, re, getopt, shutil, subprocess
23
import the, deployment
24
from subprocess import Popen
23
from .command import Command
24
import stdhome.the as the
25
from stdhome.deployment import Deployment
28
class InitCommand( Command ):
30
31
def __init__( self ):
33
self.vcs = the.config.default_vcs
34
36
def print_help( self ):
35
print "Usage: " + the.program.name + " init [URL] [--repo=REPO]"
37
print("Usage: " + the.program.name + " init [URL] [--repo=REPO]")
37
39
# 01234567890123456789012345678901234567890123456789012345678901234567890123456789
38
print "Initialise a local repository."
40
print "If an URL is given, the local reposity is a checkout of it (i.e., you can"
41
print "receive updates from it and changes you commit will be sent to it). The URL"
42
print "can take the form of a simple hostname, such as \"example.com\", or it can be a"
43
print "fully-qualified bazaar URL. (Actually, in the first case, where it is a simple"
44
print "hostname, it is internally expanded to scp://HOSTNAME/~/.stdhome/REPO)."
47
print " -r, --repo=REPO select the repo to check-out or create (defaults to 'home')"
48
print " --help display help and exit"
40
print("Initialise a local repository.")
42
print("If an URL is given, the local reposity is a checkout of it (i.e., you can")
43
print("receive updates from it and changes you commit will be sent to it). The URL")
44
print("can take the form of a simple hostname, such as \"example.com\", or it can be a")
45
print("fully-qualified bazaar URL. (Actually, in the first case, where it is a simple")
46
print("hostname, it is internally expanded to scp://HOSTNAME/~/.stdhome/REPO).")
49
print(" --quiet do not report changes to the home directory")
50
print(" -r, --repo=REPO select the repo to check-out or create (defaults to 'home')")
51
print(" -v, --verbose display information about what is being done")
52
print(" --vcs=VCS select the version control system")
53
print(" --help display help and exit")
52
57
def parse_command_line( self ):
53
58
opts, args = getopt.gnu_getopt(
54
59
sys.argv[ 1: ], "r:v",
55
[ "repo=", "verbose", "help" ] )
60
[ "quiet", "repo=", "vcs=", "verbose", "help" ] )
56
61
for opt, optarg in opts:
57
if [ '--repo', '-r' ].count( opt ):
58
if not re.match( '^[-a-zA-z0-9.]+$', optarg ):
64
elif opt in [ '--repo', '-r' ]:
65
if not re.search( '^[-a-zA-z0-9.]+$', optarg ):
66
raise the.program.FatalError(
60
67
'invalid repository name: ' + optarg )
62
elif [ '--verbose', '-v' ].count( opt ):
71
elif opt in [ '--verbose', '-v' ]:
64
73
elif opt == "--help":
67
76
# discard first argument (the command)
71
80
self.url = args[ 0 ].strip() if len( args ) else None
82
# check remaining arguments
74
83
if len( args ) > 1:
75
84
raise the.program.UsageError( 'too many arguments' )
79
the.set_repo( self.repo )
81
# repo dir must not already exist
89
# set up repo and check it *doesn't* already exists
82
90
the.repo.check_dir_exists( False )
91
the.repo.set_vcs( self.vcs )
84
93
# ensure our top-level directory exists
85
if not os.path.exists( the.expanded_dir ):
86
os.mkdir( the.expanded_dir )
94
if not os.path.exists( the.full_dir ):
95
os.mkdir( the.full_dir )
97
# checkout a remote repo, or create an empty local one?
90
100
# expand url if it's a simple hostname
91
if re.match( '^[0-9a-zA-z.]+$', self.url ):
92
self.url = 'sftp://%s/%s/%s' % \
93
( self.url, the.dir, the.repo.name )
101
if re.search( '^[0-9a-zA-z.]+$', self.url ):
102
self.url = the.repo.vcs.expand_repo_url( self.url )
95
104
# initialise deployment (with an empty repo)
96
deployment = Deployment( self.repo )
105
deployment = Deployment()
97
106
deployment.copy_in()
99
108
# perform bzr checkout
100
print "checking out %s" % the.repo.dir
101
p = Popen( [ 'bzr', 'co', self.url, the.repo.name ],
102
cwd = the.expanded_dir,
103
stdout = subprocess.PIPE, stderr = subprocess.STDOUT )
104
out = p.communicate()[ 0 ]
107
# attempt to clean-up repo dir, and die
109
shutil.rmtree( the.repo.expanded_dir )
112
raise the.program.FatalError( 'checkout failed', out )
109
if the.verbose >= 1: print("checking out %s" % the.repo.dir)
111
the.repo.vcs.checkout( self.url )
114
# attempt to clean-up repo dir
115
if os.path.exists( the.repo.full_dir ):
117
shutil.rmtree( the.repo.full_dir )
125
# check for deployment conclicts
126
conflicts = deployment.get_conflicts()
128
message += 'deployment conflicts:\n %s' % \
129
'\n '.join( conflicts )
131
# stop if there are conflicts
133
raise the.program.FatalError(
134
'there were conflicts...\n' + message )
114
136
# perform deployment
115
deployment.copy_out()
137
deployment.copy_out( self.quiet )
119
141
# perform bzr init
120
print 'creating %s' % the.repo.dir
121
p = Popen( [ 'bzr', 'init', the.repo.name ],
122
cwd = the.expanded_dir,
123
stdout = subprocess.PIPE, stderr = subprocess.STDOUT )
124
out = p.communicate()[ 0 ]
142
if the.verbose >= 1: print('initialising %s' % the.repo.dir)
127
147
# attempt to clean-up repo dir, and die
129
shutil.rmtree( the.repo.expanded_dir )
132
raise the.program.FatalError( 'init failed', out )
148
if os.path.exists( the.repo.full_dir ):
150
shutil.rmtree( the.repo.full_dir )