cpack_repository/commit

ADDED: Support replying installation data for multiple packages

authorJan Wielemaker
Thu Nov 25 22:31:57 2010 +0100
committerJan Wielemaker
Thu Nov 25 22:31:57 2010 +0100
commit8f4935f8dbe228a15214ac720d810db21b0f9ce3
treede7cf3c3fef9cb16d42eb3cc763f0ea39371d44d
parent25d1137d21a685ed0d3933dbe0547002206b3e81
Diff style: patch stat
diff --git a/api/cpack.pl b/api/cpack.pl
index 5589bf7..642f8d8 100644
--- a/api/cpack.pl
+++ b/api/cpack.pl
@@ -36,6 +36,7 @@
 :- use_module(library(semweb/rdfs)).
 :- use_module(library(semweb/rdf_label)).
 :- use_module(library(http/http_dispatch)).
+:- use_module(library(http/http_parameters)).
 
 /** <module> CPACK API for installing packages
 
@@ -73,22 +74,47 @@ To *discover* a package, we will search for
 
 %%	cpack_install_data(+Request)
 %
-%	Return installation info for installing Pack.  The data is
-%	returned as a Prolog term.
+%	Return installation info  for  installing   Pack.  The  data  is
+%	returned as a Prolog term. This handler   acts  both as a prefix
+%	handler, extracting the desired package   from  the remainder of
+%	the request URI or  it  handles   one  or  more  =p= parameters.
+%	Requesting multiple packages makes the system order the packages
+%	considering the dependencies.
+%
+%	@tbd	Probably we should also send the ClioPatria version, so
+%		the client can verify that his ClioPatria is at least as
+%		new.
 
 cpack_install_data(Request) :-
-	memberchk(path_info(PackName), Request),
+	memberchk(path_info(PackName), Request), !,
 	(   rdf_has(Pack, cpack:packageName, literal(PackName))
-	->  (   catch(pack_install_data(Pack, Data), E, true)
-	    ->  (   nonvar(E)
-		->  client_error(E, Error),
-		    reply(PackName, error(Error))
-		;   reply(PackName, cpack(PackName, Data))
-		)
-	    ;	reply(PackName, fail)
-	    )
+	->  reply_install_data(PackName, [Pack])
 	;   reply(PackName, no_pack(PackName))
 	).
+cpack_install_data(Request) :-
+	http_parameters(Request,
+			[ p(PackNames,
+			    [ list(atom),
+			      description('Name of the desired packages')
+			    ])
+			]),
+	maplist(pack_uri, PackNames, Packs),
+	reply_install_data(PackNames, Packs).
+
+pack_uri(PackName, Pack) :-
+	rdf_has(Pack, cpack:packageName, literal(PackName)), !.
+pack_uri(PackName, _) :-
+	existence_error(cpack, PackName).
+
+reply_install_data(PackName, Packs) :-
+	(   catch(pack_install_data(Packs, Data), E, true)
+	->  (   nonvar(E)
+	    ->  client_error(E, Error),
+		reply(PackName, error(Error))
+	    ;   reply(PackName, cpack(PackName, Data))
+	    )
+	;   reply(PackName, fail)
+	).
 
 reply(PackName, Data) :-
 	format('Content-type: application/x-prolog~n~n'),
diff --git a/lib/cpack/dependency.pl b/lib/cpack/dependency.pl
index c27f32f..3d96fac 100644
--- a/lib/cpack/dependency.pl
+++ b/lib/cpack/dependency.pl
@@ -140,6 +140,9 @@ cpack_conflicts_by(Package, Conflict, same_file(Path,File1,File2)) :-
 %	PackList is a list of all packages  that need to be installed to
 %	get Pack working. This list is ensured to contain Pack.
 %
+%	@param	Pack is either the URI of a single Pack or a list of
+%		these.
+%
 %	@tbd	Toplogical sorting may not be possible.  As ordering is
 %		not always necessary, we should try to relax
 %		dependencies if a topological sort is not possible due
@@ -176,8 +179,12 @@ cpack_satisfied(_).
 %	Create a full dependency graph for pack as a ugraph.
 
 dependency_ugraph(Pack, Ugraph) :-
+	(   is_list(Pack)
+	->  Agenda = Pack
+	;   Agenda = [Pack]
+	),
 	empty_assoc(Visited),
-	dependency_ugraph([Pack], Visited, Ugraph).
+	dependency_ugraph(Agenda, Visited, Ugraph).
 
 dependency_ugraph([], _, []).
 dependency_ugraph([H|T], Visited, Graph) :-