diff --git a/README.md b/README.md index 3478086..0789f79 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,10 @@ Configuration binary-path, binary These are the same as their respective arguments. + wix_version, version + The version to use to generate the MSI, in a dot separated number + format. + embedded A list of files paths to include in the installation directory. Each element in this list should be a list of two elements: the diff --git a/src/file.ml b/src/file.ml index 5225d84..73046e5 100644 --- a/src/file.ml +++ b/src/file.ml @@ -16,13 +16,14 @@ let conf_default = OpamFilename.of_string "opam-wix.conf" module Syntax = struct let internal = "conf" - let format_version = OpamVersion.of_string "0.1" + let format_version = OpamVersion.of_string "0.2" type images = { ico: string option; dlg: string option; ban: string option } type t = { c_version: OpamVersion.t; c_images: images; c_binary_path: string option; c_binary: string option; + c_wix_version: Wix.Version.t option; c_embedded : (string * string) list; c_envvar: (string * string) list; } @@ -36,6 +37,7 @@ module Syntax = struct }; c_binary_path = None; c_binary = None; + c_wix_version = None; c_embedded = []; c_envvar = []; } @@ -63,6 +65,10 @@ module Syntax = struct "binary", OpamPp.ppacc_opt (fun binary t -> { t with c_binary = Some binary }) (fun t -> t.c_binary) OpamFormat.V.string; + "wix-version", OpamPp.ppacc_opt + (fun c_wix_version t -> { t with c_wix_version = Some c_wix_version }) + (fun t -> t.c_wix_version) + (OpamFormat.V.string -| OpamPp.of_module "wix_version" (module Wix.Version)); "embedded", OpamPp.ppacc (fun file t -> { t with c_embedded = file }) (fun t -> t.c_embedded) (OpamFormat.V.map_list ~depth:2 diff --git a/src/file.mli b/src/file.mli index 835100b..0dbc0e1 100644 --- a/src/file.mli +++ b/src/file.mli @@ -30,6 +30,7 @@ module Conf: sig c_images: images; (* Images files that are treated not as other embedded files *) c_binary_path: string option; (* Path to binary to install *) c_binary: string option; (* Binary name to install *) + c_wix_version: Wix.Version.t option; (* Wix compatible version to use for install *) c_embedded : (string * string) list; (* Files/directories to embed in installation directory *) c_envvar: (string * string) list; (* Environement variables to set in Windows Terminal on installation *) } diff --git a/src/opamWixMain.ml b/src/opamWixMain.ml index b554648..f630722 100644 --- a/src/opamWixMain.ml +++ b/src/opamWixMain.ml @@ -17,6 +17,7 @@ type config = { package : OpamPackage.Name.t; path : filename option; binary: string option; + wix_version: Wix.Version.t option; output_dir : dirname; wix_path : string; package_guid: string option; @@ -54,6 +55,14 @@ end module Args = struct open Arg + let wix_version_conv = + let parse str = + try `Ok (Wix.Version.of_string str) + with Failure s -> `Error s + in + let print ppf wxv = Format.pp_print_string ppf (Wix.Version.to_string wxv) in + parse, print + module Section = struct let package_arg = "PACKAGE ARGUMENT" let bin_args = "BINARY ARGUMENT" @@ -75,6 +84,10 @@ module Args = struct value & opt (some string) None & info ["binary";"b"] ~docs:Section.bin_args ~docv:"NAME" ~doc: "The binary name to handle. Specified package should contain the binary with the same name." + let wix_version = + value & opt (some wix_version_conv) None & info ["with-version"] ~docv:"VERSION" + ~doc:"The version to use for the installer, in an msi format, i.e. numbers and dots, [0-9.]+" + let output_dir = value & opt OpamArg.dirname (OpamFilename.Dir.of_string ".") & info ["o";"output"] ~docv:"DIR" ~doc: "The output directory where bundle will be stored" @@ -106,10 +119,10 @@ module Args = struct value & flag & info ["keep-wxs"] ~doc:"Keep Wix source files." let term = - let apply conf package path binary output_dir wix_path package_guid icon_file dlg_bmp ban_bmp keep_wxs = - { conf; package; path; binary; output_dir; wix_path; package_guid; icon_file; dlg_bmp; ban_bmp; keep_wxs } + let apply conf package path binary wix_version output_dir wix_path package_guid icon_file dlg_bmp ban_bmp keep_wxs = + { conf; package; path; binary; wix_version; output_dir; wix_path; package_guid; icon_file; dlg_bmp; ban_bmp; keep_wxs } in - Term.(const apply $ conffile $ package $ path $ binary $ output_dir $ wix_path $ package_guid $ icon_file $ + Term.(const apply $ conffile $ package $ path $ binary $ wix_version $ output_dir $ wix_path $ package_guid $ icon_file $ dlg_bmp $ ban_bmp $ keep_wxs) end @@ -171,6 +184,7 @@ let normalize_conf env conf file = { conf with binary = merge_opt conf.binary file.c_binary; + wix_version = merge_opt conf.wix_version file.c_wix_version; path = merge_opt conf.path (Option.map (resolve_path env (module File_impl)) file.c_binary_path); icon_file = merge_opt conf.icon_file @@ -201,6 +215,39 @@ let create_bundle cli = (OpamConsole.colorise `bold (OpamPackage.Name.to_string conf.package)) (OpamConsole.colorise `bold ("opam install " ^ (OpamPackage.Name.to_string conf.package))) in + let package_version = + match conf.wix_version with + | Some v -> v + | None -> + let pkg_version = + OpamPackage.Version.to_string (OpamPackage.version package) + in + try Wix.Version.of_string pkg_version + with Failure _ -> + (OpamConsole.warning + "Package version %s contains characters not accepted by MSI." + (OpamConsole.colorise `underline pkg_version); + let use = "use config file to set it or option --with-version" in + let version = + let n = + OpamStd.String.find_from (function '0'..'9' | '.' -> false | _ -> true) + pkg_version 0 + in + if n = 0 then + OpamConsole.error_and_exit `Not_found + "No version can be retrieved from '%s', %s." + pkg_version use + else + String.sub pkg_version 0 n + in + OpamConsole.msg + "It must be only dot separated numbers. You can %s.\n" use; + if + OpamConsole.confirm "Do you want to use simplified version %s?" + (OpamConsole.colorise `underline version) + then version + else OpamStd.Sys.exit_because `Aborted) + in let opam = OpamSwitchState.opam st package in let bin_path = OpamPath.Switch.bin gt.root st.switch st.switch_config in let changes = @@ -333,11 +380,7 @@ let create_bundle cli = Filename.basename @@ OpamFilename.Dir.to_string bundle_dir let package_name = OpamPackage.Name.to_string (OpamPackage.name package) - let package_version = - let version = OpamPackage.Version.to_string (OpamPackage.version package) in - match String.index_opt version '~' with - | None -> version - | Some i -> String.sub version 0 i + let package_version = package_version let description = (OpamFile.OPAM.synopsis opam) ++ (OpamFile.OPAM.descr_body opam) @@ -535,6 +578,7 @@ let create_bundle cli = `I ("$(i,opamwix-version)","The version of the config file. The current version is $(b,0.1)."); `I ("$(i,ico, bng, ban)","These are the same as their respective arguments."); `I ("$(i,binary-path, binary)","These are the same as their respective arguments."); + `I ("$(i,wix_version)","The version to use to generate the MSI, in a dot separated number format."); `I ("$(i,embedded)", "A list of files or directories paths to include in the installation directory. \ Each element in this list should be a list of two elements: the first being the destination \ basename (the name of the file in the installation directory), and the second being the \ diff --git a/src/wix.ml b/src/wix.ml index 0bcd8e5..999b21d 100644 --- a/src/wix.ml +++ b/src/wix.ml @@ -16,6 +16,20 @@ type component_group = string type directory_ref = string +module Version = struct +type t = string +let to_string s = s +let of_string s = + String.iter (function + | '0'..'9' | '.' -> () + | c -> + failwith + (Printf.sprintf "Invalid character '%c' in WIX version %S" c s)) + s; + s +end + + let xml_declaration = { version = "1.0"; encoding = Some "windows-1252"; diff --git a/src/wix.mli b/src/wix.mli index d90e06f..2ee73f1 100644 --- a/src/wix.mli +++ b/src/wix.mli @@ -17,6 +17,13 @@ type component_group = string (** Directory id reference *) type directory_ref = string +(** Version in the form [0-9.]+, i.e dot separated numbers *) +module Version: sig + type t = string + val to_string : t -> string + val of_string : string -> t +end + (** Information module used to generated main wxs document. *) module type INFO = sig (** Path to the bundle containing all required files. Every relative file path will be concatenated to this path *) diff --git a/tests/basic.t b/tests/basic.t index 6e61cce..3a5057b 100644 --- a/tests/basic.t +++ b/tests/basic.t @@ -399,3 +399,46 @@ Testing config file that embeds directory and file and set environment variables + +================== Test 6 ==================== +Version testing + $ mkdir bar + $ cp compile bar/compile + $ cat > bar/bar-with-plus.opam << EOF + > opam-version: "2.0" + > version: "0.1+23" + > name: "bar-with-plus" + > install: [ "cp" "compile" "%{bin}%/%{name}%" ] + > EOF + $ cat > bar/bar-beg-alpha << EOF + > opam-version: "2.0" + > version: "v012" + > name: "bar-with-plus" + > install: [ "cp" "compile" "%{bin}%/%{name}%" ] + > EOF + $ cat > bar/bar-only-alpha.opam << EOF + > opam-version: "2.0" + > version: "aversion" + > name: "bar-with-plus" + > install: [ "cp" "compile" "%{bin}%/%{name}%" ] + > EOF + $ opam pin ./bar -y + $ opam-wix --wix-path=$WIX_PATH bar-with-plus + $ opam-wix --wix-path=$WIX_PATH bar-with-plus -y + $ opam-wix --wix-path=$WIX_PATH bar-beg-alpha + $ opam-wix --wix-path=$WIX_PATH bar-only-alpha + $ opam-wix --wix-path=$WIX_PATH bar-only-alpha --with-version 4.2 + $ cat > conf << EOF + > opamwix-version: "0.1" + > wix_version: "3.2+3" + > EOF + $ opam-wix --wix-path=$WIX_PATH --conf conf bar-only-alpha + $ cat > conf << EOF + > opamwix-version: "0.1" + > wix_version: "3.2" + > EOF + $ opam-wix --wix-path=$WIX_PATH --conf conf bar-only-alpha + + + +