Functional tests work.  DELETE is unimplemented; branching is untested.
1 files changed, 81 insertions(+), 37 deletions(-)

M config.rb
M config.rb +81 -37
@@ 57,9 57,7 @@ module Config
 
 			elsif object.kind_of?( Array )
 				if object[0].kind_of?( Store )
-					'{components":{' +
-						object.each { |store| mk_store( store ) } +
-						"}"
+					'{'+ object.each { |store| mk_store( store ) } + '}'
 					
 				else
 					"[" + object.collect {|o| o.inspect}.join(",") + "]"

          
@@ 144,7 142,7 @@ module Config
 				`hg init`
 				if $? == 0
 					File.open("config.json", "w") {|fout|
-						fout.puts( '{ "components": {} }' )
+						fout.puts( '{}' )
 					}
 					`hg add config.json`
 					`hg ci -m "initial commit"`

          
@@ 219,27 217,36 @@ module Config
 		def do_GET( request, response ) 
 			components = @config[:components]
 			marshal = @config[:marshal]
-			
-			component_path = paths(request)
-			return error( response, 400 ) if component_path.length < 1 || component_path[0] != "component"
+			vcs = @config[:vcs]
 			
-			content = if component_path.length == 1     # /component
-				component_names = components.sort[-1].keys
-				marshal.serialize( component_names )
-			else
-				component_name = component_path[1]        # /component/COMPONENT
-				comps = if component_path.length > 2      # /component/COMPONENT/VERSION
-					version = component_path[2]
-					components[ version.to_i ]
+			begin
+				component_path = paths(request)
+				return error( response, 400 ) if component_path.length < 1 || component_path[0] != "component"
+				
+				content = if component_path.length == 1     # /component
+					component_names = components.sort[-1].keys
+					marshal.serialize( component_names )
 				else
-					components.sort[-1]
+					component_name = component_path[1]        # /component/COMPONENT
+					comps = if component_path.length > 2      # /component/COMPONENT/VERSION
+						version = component_path[2]
+						get_version( version.to_i )
+					else
+						tip = vcs.tip
+						get_version( tip )
+					end
+					comps[component_name]
 				end
-				comps[component_name]
+				
+				response.status = 200
+				response['Content-Type'] = "application/json"
+				response.body = marshal.serialize( content, true )
+			rescue
+				STDERR.puts $!, $@
+				response.status = 500
+				response['Content-Type'] = "text/plain"
+				response.body = $!.to_s
 			end
-			
-			response.status = 200
-			response['Content-Type'] = "application/json"
-			response.body = marshal.serialize( content, true )
 		end
 		
 		# - PUT stores a unit

          
@@ 257,7 264,14 @@ module Config
 			component_path = paths(request)
 			return error( response, 400 ) if component_path.length < 2
 			namespace = component_path[0]
-			method( ("put_"+namespace).to_sym ).call( component_path, request.body, response )
+			begin
+				method( ("put_"+namespace).to_sym ).call( component_path, request.body, response )
+			rescue
+				STDERR.puts $!, $@
+				response.status = 500
+				response['Content-Type'] = "text/plain"
+				response.body = $!.to_s
+			end
 		end
 		
 		def put_component( path, payload, response )

          
@@ 277,10 291,10 @@ module Config
 			marshal = @config[:marshal]
 			components = @config[:components]
 			# TODO: Support more workspaces
-			vcs.commit( "config.json", marshal.serialize( components ) )
+			vcs.commit( "config.json", marshal.serialize( components[path[1].to_i] ) )
 			response.status = 200
 			response['Content-Type'] = "text/plain"
-			response.body = vcs.tip
+			response.body = vcs.tip.to_s
 		end
 
 		# POST creates a new component or revision

          
@@ 289,23 303,53 @@ module Config
   	#   Creates a new workspace, optionally branching off of a specified version.
 		def do_POST( request, response )
 			components = @config[:components]
+			vcs = @config[:vcs]
+			marshal = @config[:marshal]
 
-			component_path = paths(request)
-			return error( response, 400 ) if component_path.length < 2
-			
-			workspace_version = component_path[1].to_i
-			return error( response, 400, "Bad workspace number #{workspace_version}" ) unless workspace_version == 0
+			begin
+				component_path = paths(request)
+				return error( response, 400 ) if component_path.length < 2
+
+				workspace_version = component_path[1].to_i
+				return error( response, 400, "Bad workspace number #{workspace_version}" ) unless workspace_version == 0
+
+				# TODO: validate that no workspace is currently in use
+				parent_version = component_path[2].to_i
+				vcs.branch( parent_version )
+				components[0] = get_version( parent_version )
+			rescue
+				STDERR.puts $!, $@
+				response.status = 500
+				response['Content-Type'] = "text/plain"
+				response.body = $!.to_s
+			end
+		end
+		
+		def get_version(version)
+			components = @config[:components]
+			vcs = @config[:vcs]
+			marshal = @config[:marshal]
 			
-			# TODO: validate that no workspace is currently in use
-			if component_path.length > 2
-				parent_version = component_path[2].to_i
-				# FIXME: these might not be loaded.  Need to go to VCS for this.
-				components[0] = components[parent_version]
+			unless components[version]
+				conf = vcs.load( "config.json", version )
+				vers = marshal.deserialize(conf)
+				comp = marshal.to_store_list(vers)
+				components[version] = comp
 			end
+			components[version]
 		end
 
 		def do_DELETE
-				# FIXME: unimplemented
+			begin
+				response.status = 404
+				response['Content-Type'] = "text/plain"
+				response.body = "Not yet implemented"
+			rescue
+				STDERR.puts $!, $@
+				response.status = 500
+				response['Content-Type'] = "text/plain"
+				response.body = $!.to_s
+			end
 		end
 		
 		def error( response, code=400, message="" )

          
@@ 326,8 370,8 @@ module Config
 			marshal = JSON.new
 			trim_size = mount_point.split("/").size
 			version = vcs.tip
-			configs = marshal.deserialize( vcs.load( "config.json", version ) )
-			components = { version => configs }
+			config_objs = marshal.deserialize( vcs.load( "config.json", version ) )
+			components = { version => marshal.to_store_list(config_objs) }
 			
 			@@server.mount( mount_point, Config::Server, {
 				:vcs => vcs,