/stdhome

To get this branch, use:
bzr branch http://bzr.ed.am/stdhome
8 by Tim Marston
added diff command; moved all command to commands subdir; made stage-revert
1
# init.py
1 by Tim Marston
initial commit; basic app startup and initial command-line processing
2
#
3
# Copyright (C) 2013 Tim Marston <tim@edm.am>
4
#
5
# This file is part of stdhome (hereafter referred to as "this program").
6
# See http://ed.am/dev/stdhome for more information.
7
#
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
# GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
22
import sys, os, re, getopt, shutil, subprocess
88 by Tim Marston
python3ification
23
from .command import Command
8 by Tim Marston
added diff command; moved all command to commands subdir; made stage-revert
24
import stdhome.the as the
25
from stdhome.deployment import Deployment
26
27
28
class InitCommand( Command ):
1 by Tim Marston
initial commit; basic app startup and initial command-line processing
29
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
30
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
31
	def __init__( self ):
32
		self.quiet = False
33
		self.vcs = the.config.default_vcs
34
35
1 by Tim Marston
initial commit; basic app startup and initial command-line processing
36
	def print_help( self ):
88 by Tim Marston
python3ification
37
		print("Usage: " + the.program.name + " init [URL] [--repo=REPO]")
38
		print()
1 by Tim Marston
initial commit; basic app startup and initial command-line processing
39
		#      01234567890123456789012345678901234567890123456789012345678901234567890123456789
88 by Tim Marston
python3ification
40
		print("Initialise a local repository.")
41
		print()
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).")
47
		print()
48
		print("Options:")
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")
1 by Tim Marston
initial commit; basic app startup and initial command-line processing
54
		exit( 0 )
55
56
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
57
	def parse_command_line( self ):
58
		opts, args = getopt.gnu_getopt(
59
			sys.argv[ 1: ], "r:v",
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
60
			[ "quiet", "repo=", "vcs=", "verbose", "help" ] )
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
61
		for opt, optarg in opts:
61 by Tim Marston
added home directory change reporting to CopyOutWalker; added --quiet option to
62
			if opt == "--quiet":
63
				self.quiet = True
64
			elif opt in [ '--repo', '-r' ]:
65
				if not re.search( '^[-a-zA-z0-9.]+$', optarg ):
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
66
					raise the.program.FatalError(
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
67
						'invalid repository name: ' + optarg )
17 by Tim Marston
read ~/.stdhomerc; commands set repo before run(); program performs late
68
				the.repo = optarg
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
69
			elif opt == "--vcs":
70
				self.vcs = optarg
71
			elif opt in [ '--verbose', '-v' ]:
72
				the.verbose += 1
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
73
			elif opt == "--help":
1 by Tim Marston
initial commit; basic app startup and initial command-line processing
74
				self.print_help()
55 by Tim Marston
moved handling of --verbose to main program; manuall parse config file (because
75
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
76
		# discard first argument (the command)
77
		args.pop( 0 )
78
79
		# URL argument
80
		self.url = args[ 0 ].strip() if len( args ) else None
81
35 by Tim Marston
made checks for verbose >= 1 explicit
82
		# check remaining arguments
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
83
		if len( args ) > 1:
84
			raise the.program.UsageError( 'too many arguments' )
85
86
87
	def run( self ):
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
88
89
		# set up repo and check it *doesn't* already exists
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
90
		the.repo.check_dir_exists( False )
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
91
		the.repo.set_vcs( self.vcs )
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
92
93
		# ensure our top-level directory exists
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
94
		if not os.path.exists( the.full_dir ):
95
			os.mkdir( the.full_dir )
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
96
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
97
		# checkout a remote repo, or create an empty local one?
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
98
		if self.url:
99
100
			# expand url if it's a simple hostname
61 by Tim Marston
added home directory change reporting to CopyOutWalker; added --quiet option to
101
			if re.search( '^[0-9a-zA-z.]+$', self.url ):
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
102
				self.url = the.repo.vcs.expand_repo_url( self.url )
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
103
104
			# initialise deployment (with an empty repo)
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
105
			deployment = Deployment()
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
106
			deployment.copy_in()
107
108
			# perform bzr checkout
88 by Tim Marston
python3ification
109
			if the.verbose >= 1: print("checking out %s" % the.repo.dir)
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
110
			try:
111
				the.repo.vcs.checkout( self.url )
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
112
			except Exception:
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
113
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
114
				# attempt to clean-up repo dir
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
115
				if os.path.exists( the.repo.full_dir ):
116
					try:
117
						shutil.rmtree( the.repo.full_dir )
118
					except OSError:
119
						pass
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
120
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
121
				raise
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
122
60 by Tim Marston
fixed init command
123
			message = ''
124
59 by Tim Marston
switched init command (and update command) to checking for conflicts prior to
125
			# check for deployment conclicts
126
			conflicts = deployment.get_conflicts()
127
			if conflicts:
128
				message += 'deployment conflicts:\n  %s' % \
129
						   '\n  '.join( conflicts )
130
60 by Tim Marston
fixed init command
131
			# stop if there are conflicts
132
			if message:
133
				raise the.program.FatalError(
134
					'there were conflicts...\n' + message )
135
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
136
			# perform deployment
61 by Tim Marston
added home directory change reporting to CopyOutWalker; added --quiet option to
137
			deployment.copy_out( self.quiet )
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
138
139
		else:
140
141
			# perform bzr init
88 by Tim Marston
python3ification
142
			if the.verbose >= 1: print('initialising %s' % the.repo.dir)
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
143
			try:
144
				the.repo.vcs.init()
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
145
			except Exception:
2 by Tim Marston
added global objects (the.repo, the.program), deployment object and implemented
146
147
				# attempt to clean-up repo dir, and die
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
148
				if os.path.exists( the.repo.full_dir ):
149
					try:
150
						shutil.rmtree( the.repo.full_dir )
151
					except OSError:
152
						pass
3 by Tim Marston
added bzr as a vcs backend; finished init command; implemented deployment
153
63 by Tim Marston
determine and instantiate repo vcs dynamically; for new repos, added default vcs
154
				raise