(* febootstrap 3
- * Copyright (C) 2009-2010 Red Hat Inc.
+ * Copyright (C) 2009-2011 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
file_exists "/etc/debian_version" &&
Config.aptitude <> "no" && Config.apt_cache <> "no" && Config.dpkg <> "no"
+let installed_pkgs = ref []
+
+let debian_init () =
+ installed_pkgs :=
+ run_command_get_lines "dpkg-query --show --showformat='${Package}\\n'"
+
+let get_installed_pkgs () =
+ match !installed_pkgs with
+ | [] -> assert false
+ | pkgs -> pkgs
+
let rec debian_resolve_dependencies_and_download names =
let cmd =
- sprintf "%s depends --recurse -i %s | grep -v '^[<[:space:]]'"
+ sprintf "%s depends --recurse -i %s | grep -v '^[<[:space:]]' | grep -Ev ':\\w+\\b'"
Config.apt_cache
(String.concat " " (List.map Filename.quote names)) in
let pkgs = run_command_get_lines cmd in
not (List.exists (fun re -> Str.string_match re name 0) excludes)
) pkgs in
+ let present_pkgs, download_pkgs =
+ if not use_installed then
+ [], pkgs
+ else
+ List.partition (
+ fun pkg -> List.exists ((=) pkg) (get_installed_pkgs ())
+ ) pkgs in
+
+ debug "packages already present: %s" (String.concat " " present_pkgs);
+ debug "wanted packages to download: %s" (String.concat " " download_pkgs);
+
(* Download the packages. *)
- let cmd =
- sprintf "umask 0000; cd %s && %s download %s"
- (Filename.quote tmpdir)
- Config.aptitude
- (String.concat " " (List.map Filename.quote pkgs)) in
- run_command cmd;
+ if (List.length download_pkgs > 0)
+ then (
+ let cmd =
+ sprintf "umask 0000; cd %s && %s download %s"
+ (Filename.quote tmpdir)
+ Config.aptitude
+ (String.concat " " (List.map Filename.quote download_pkgs)) in
+ run_command cmd
+ );
(* Find out what aptitude downloaded. *)
let files = Sys.readdir tmpdir in
- let pkgs = List.map (
+ let download_pkgs = List.map (
fun pkg ->
(* Look for 'pkg_*.deb' in the list of files. *)
let pre = pkg ^ "_" in
exit 1
with
Exit -> !r
- ) pkgs in
+ ) download_pkgs in
- List.sort compare pkgs
+ List.sort compare (List.append present_pkgs download_pkgs)
(* On Ubuntu 10.04 LTS, apt-cache depends --recurse is broken. It
* doesn't return the full list of dependencies. Therefore recurse
else
names
-let debian_list_files pkg =
+let debian_list_files_downloaded pkg =
debug "unpacking %s ..." pkg;
(* We actually need to extract the file in order to get the
files
+let debian_list_files_installed pkg =
+ debug "using installed package %s ..." pkg;
+ let cmd = sprintf "dpkg-query --listfiles %s" pkg in
+ let lines = run_command_get_lines cmd in
+ (* filter out lines not directly describing fs objects such as
+ "package diverts others to: /path/to/..." *)
+ let lines = List.filter (
+ fun l -> l.[0] = '/' && l.[1] != '.'
+ ) lines in
+ let files = List.map (
+ fun path ->
+ let statbuf = lstat path in
+ let is_dir = statbuf.st_kind = S_DIR in
+ let config = statbuf.st_kind = S_REG && string_prefix "/etc/" path in
+ let mode = statbuf.st_perm in
+ (path, { ft_dir = is_dir; ft_config = config; ft_mode = mode;
+ ft_ghost = false; ft_size = statbuf.st_size })
+ ) lines in
+ files
+
+let debian_list_files pkg =
+ if use_installed && List.exists ((=) pkg) (get_installed_pkgs ()) then
+ debian_list_files_installed pkg
+ else
+ debian_list_files_downloaded pkg
+
(* Easy because we already unpacked the archive above. *)
let debian_get_file_from_package pkg file =
- tmpdir // pkg ^ ".d" // file
+ if use_installed && List.exists (fun p -> p = pkg) (get_installed_pkgs ())
+ then
+ file
+ else
+ tmpdir // pkg ^ ".d" // file
let () =
let ph = {
ph_detect = debian_detect;
+ ph_init = debian_init;
ph_resolve_dependencies_and_download =
debian_resolve_dependencies_and_download;
ph_list_files = debian_list_files;