File: optuniv.ml

package info (click to toggle)
botch 0.24-6.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,084,624 kB
  • sloc: xml: 11,924,892; ml: 4,489; python: 3,890; sh: 1,268; makefile: 334
file content (171 lines) | stat: -rw-r--r-- 7,645 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
(**************************************************************************)
(*                                                                        *)
(*  Copyright (C) 2012-2014 Johannes 'josch' Schauer <j.schauer@email.de> *)
(*  Copyright (C) 2012      Pietro Abate <pietro.abate@pps.jussieu.fr>    *)
(*                                                                        *)
(*  This library is free software: you can redistribute it and/or modify  *)
(*  it under the terms of the GNU Lesser General Public License as        *)
(*  published by the Free Software Foundation, either version 3 of the    *)
(*  License, or (at your option) any later version.  A special linking    *)
(*  exception to the GNU Lesser General Public License applies to this    *)
(*  library, see the COPYING file for more information.                   *)
(**************************************************************************)

open! ExtLib
open Dose_common
open Dose_debian
open Dose_algo
open Dose_doseparse

#define __label __FILE__
let label =  __label ;;
include Util.Logging(struct let label = label end) ;;

module Options = struct
  open OptParse
  let description = (
    "remove all conflicts and calculate an optimal self-contained universe"
  )
  let usage = "%prog Packages... Sources"
  let options = OptParser.make ~description ~usage
  include BootstrapCommon.MakeOptions(struct let options = options end)

  let addarchall = StdOpt.store_true ()
  let allowsrcmismatch = StdOpt.store_true ()

  open OptParser ;;

  let prog_group = add_group options "Program specific options" in

  add options ~group:prog_group ~long_name:"all" ~help:"also add source packages for Architecture:all packages" addarchall;
  add options ~group:prog_group
    ~long_name:"allowsrcmismatch"
    ~help:("If a binary package is "^
           "without a source package but there is a source package of same name but "^
           "different version, match this binary package to that source package.") allowsrcmismatch;

  include StdOptions.InputOptions;;
  let default = List.filter (fun e -> not (List.mem e ["compare";"checkonly";"latest";"inputtype"])) StdOptions.InputOptions.default_options in
  StdOptions.InputOptions.add_options ~default options;;

  include StdOptions.OutputOptions;;
  let default = List.filter (fun e -> not (List.mem e ["outdir"; "dot"])) StdOptions.OutputOptions.default_options in
  StdOptions.OutputOptions.add_options ~default options;;

  include StdOptions.DistribOptions;;
  let default = List.filter (fun e -> not (List.mem e ["deb-profiles"; "deb-ignore-essential"; "deb-builds-from"])) StdOptions.DistribOptions.default_options in
  StdOptions.DistribOptions.add_debian_options ~default options;;
end

let main () =
  let posargs = OptParse.OptParser.parse_argv Options.options in
  StdDebug.enable_debug (OptParse.Opt.get Options.verbose);
  StdDebug.all_quiet (OptParse.Opt.get Options.quiet);

  let options = Options.set_deb_options () in
  let buildarch = Option.get options.Debcudf.native in
  let hostarch = match options.Debcudf.host with None -> "" | Some s -> s in
  let foreignarchs = options.Debcudf.foreign in
  let addarchall = OptParse.Opt.get Options.addarchall in
  let noindep = options.Debcudf.drop_bd_indep in
  let allowsrcmismatch = OptParse.Opt.get Options.allowsrcmismatch in

  let binlist, (fgsrclist, bgsrclist), _ = BootstrapCommon.parse_packages ~noindep Options.parse_cmdline buildarch hostarch foreignarchs posargs in
  let tables = Debcudf.init_tables (fgsrclist@bgsrclist@binlist) in
  let fgsl = List.map (Debcudf.tocudf ?inst:None ~options tables) fgsrclist in
  let bgsl = List.map (Debcudf.tocudf ?inst:None ~options tables) bgsrclist in
  let bl = List.map (Debcudf.tocudf ?inst:None ~options tables) binlist in

  (* create a hashtable mapping cudf package name,version,arch tuples to
   * Packages.package format822 stanzas *)
  let cudftobin_table = Hashtbl.create 30000 in
  List.iter2 (fun cudfpkg -> fun binpkg ->
      let id = (cudfpkg.Cudf.package, cudfpkg.Cudf.version) in
      Hashtbl.add cudftobin_table id binpkg
    ) bl binlist;

  let universe = Cudf.load_universe (BootstrapCommon.unique [bl;fgsl;bgsl]) in

  info "creating conflict free universe..."; (* pun intended *)

  let prepare_cudf_sources = List.map (fun srcpkg ->
      let issource = ("issource",`Int 1) in
      { srcpkg with Cudf.conflicts = [];
                    Cudf.pkg_extra = issource :: srcpkg.Cudf.pkg_extra;
                    (* FIXME: source package provides have to be versioned - this should be fixed in dose3:
                            *https://gforge.inria.fr/tracker/?func=detail&group_id=4395&atid=13808&aid=17556 *)
                    Cudf.provides = [(srcpkg.Cudf.package, Some (`Eq, srcpkg.Cudf.version))] }
    ) in
  let fgsl = prepare_cudf_sources fgsl in
  let bgsl = prepare_cudf_sources bgsl in

  let newbl = List.map (fun binpkg ->
      if (not addarchall) && (BootstrapCommon.pkg_is_arch_all binpkg) then
        (* do not connect arch:all packages to source packages *)
        { binpkg with Cudf.conflicts = []; }
      else begin
        (* get the source package for the non-arch:all binary package *)
        let srcpkg = try BootstrapCommon.get_src_package ~allowmismatch:allowsrcmismatch universe binpkg
          with Sources.NotfoundSrc ->
            failwith (Printf.sprintf "cannot find source for binary package %s"
                        (BootstrapCommon.string_of_package binpkg))
        in
        (* connect to source package as "builds-from" *)
        let srcdep = (srcpkg.Cudf.package,Some(`Eq,srcpkg.Cudf.version)) in
        { binpkg with Cudf.conflicts = [];
                      Cudf.depends = [srcdep] :: binpkg.Cudf.depends }
      end
    ) bl in

  let universe = Cudf.load_universe(BootstrapCommon.unique [fgsl;bgsl;newbl]) in
  info "solving...";

  let preamble = Debcudf.preamble in
  let preamble = CudfAdd.add_properties preamble [("issource",(`Int (Some 0)))] in
  (* any source package that builds part of the minimal builds system will draw in everything else *)
  let to_install = List.map
      (fun pkg -> (pkg.Cudf.package, Some (`Eq, pkg.Cudf.version))) fgsl
  in

  let request = { Cudf.default_request
                  with Cudf.request_id = "";
                       Cudf.install = to_install } in
  let criteria = "-sum(solution,issource)" in
  let cmd = "aspcud $in $out $pref" in
  let dummy = { Depsolver.dummy_request with
                Cudf.depends =
                  List.map (fun (_,pkglist) ->
                      List.map (fun pkg ->
                          (pkg.Cudf.package,Some(`Eq,pkg.Cudf.version))
                        ) pkglist
                    ) (Debcudf.get_essential tables) }
  in
  let r = Depsolver.check_request ~dummy ~cmd ~criteria (preamble,universe,request) in

  info "writing output...";
  let oc =
    if OptParse.Opt.is_set Options.outfile then
      open_out (OptParse.Opt.get Options.outfile)
    else
      stdout
  in
  begin match r with
    |Depsolver.Error s -> fatal "%s" s
    |Depsolver.Unsat _ -> fatal "(UNSAT) No Solutions according to the given preferences"
    |Depsolver.Sat (_,soluniv) ->
      (* print out all selected binary packages *)
      Cudf.iter_packages (fun pkg ->
          let is_src = try (Cudf.lookup_package_property pkg "type") = "src"
            with Not_found -> false
          in
          if not is_src then begin
            let id = (pkg.Cudf.package, pkg.Cudf.version) in
            let b = Hashtbl.find cudftobin_table id in
            b#pp oc;
          end
        ) soluniv
  end;
  close_out oc;
;;

main ();;