diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2013-01-10 16:05:32 +0100 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@gmail.com> | 2013-01-11 13:10:34 +0100 |
commit | 734bddba1cfa2a712a99a1bff784a617aec73c45 (patch) | |
tree | df02b9362cb0ac1c5d16ded1ae91953be26b0a9e | |
parent | 1e664f3c0f043297b5d90cd596cfa04ed901b6be (diff) | |
download | msitools-734bddba1cfa2a712a99a1bff784a617aec73c45.tar.gz msitools-734bddba1cfa2a712a99a1bff784a617aec73c45.tar.xz msitools-734bddba1cfa2a712a99a1bff784a617aec73c45.zip |
tools: add wixl-heat
A tool to generate WiX fragments
-rw-r--r-- | Makefile.am | 21 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | tools/wixl/util.vala | 10 | ||||
-rw-r--r-- | tools/wixl/wixl-heat.vala | 129 |
4 files changed, 165 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 76d4aa0..c7c1cef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -77,6 +77,27 @@ wixl_LDADD = \ wixl_DEPENDENCIES = libmsi/libmsi.la +if !WIN32 +bin_PROGRAMS += wixl-heat + +wixl_heat_CFLAGS = -w + +wixl_heat_VALAFLAGS = \ + --vapidir=. \ + --pkg config \ + --enable-experimental \ + --pkg gio-unix-2.0 \ + $(NULL) + +wixl_heat_SOURCES = \ + tools/wixl/wixl-heat.vala \ + tools/wixl/util.vala \ + $(NULL) + +wixl_heat_CPPFLAGS = $(wixl_CPPFLAGS) +wixl_heat_LDADD = $(wixl_LDADD) +endif + # Autotest support dist_noinst_DATA = tests/testsuite.at tests/package.m4 tests/testsuite diff --git a/configure.ac b/configure.ac index fc930a1..f47bafa 100644 --- a/configure.ac +++ b/configure.ac @@ -35,10 +35,14 @@ AC_PATH_PROG(VAPIGEN, vapigen, no) AC_SUBST(VAPIGEN) AM_CONDITIONAL([VAPI], [test "x$VAPIGEN" != xno]) +AS_IF([test $win32 = no], + [WIXL_UNIX="gio-unix-2.0"]) + PKG_CHECK_MODULES([WIXL], [gio-2.0 >= 2.26.0 libgcab-1.0 uuid >= 1.41.3 - libxml-2.0 >= 2.9], + libxml-2.0 >= 2.9 + $WIXL_UNIX], [wixl_ok=yes], [wixl_ok=no]) AC_ARG_ENABLE([wixl], diff --git a/tools/wixl/util.vala b/tools/wixl/util.vala index 308b511..29d9734 100644 --- a/tools/wixl/util.vala +++ b/tools/wixl/util.vala @@ -90,6 +90,16 @@ namespace Wixl { return str; } + public string random_id (string prefix) { + var data = new uint32[8] {}; + for (var i = 0; i < 8; i++) + data[i] = Random.next_int (); + + var hash = Checksum.compute_for_data (ChecksumType.MD5, (uint8[])data); + + return prefix + hash[0:32].up (); + } + public bool parse_yesno (string? str, bool default = false) { if (str == null) return default; diff --git a/tools/wixl/wixl-heat.vala b/tools/wixl/wixl-heat.vala new file mode 100644 index 0000000..560367d --- /dev/null +++ b/tools/wixl/wixl-heat.vala @@ -0,0 +1,129 @@ +using Wixl; + +static string cg; +static string dr; +static string prefix; +static string vardir; +[CCode (array_length = false, array_null_terminated = true)] +static string[] exclude; + +private const OptionEntry[] options = { + { "directory-ref", 0, 0, OptionArg.STRING, ref dr, N_("Directory Ref"), null }, + { "component-group", 0, 0, OptionArg.STRING, ref cg, N_("Component Group"), null }, + { "var", 0, 0, OptionArg.STRING, ref vardir, N_("Variable for source dir"), null }, + { "prefix", 'p', 0, OptionArg.STRING, ref prefix, N_("Prefix"), null }, + { "exclude", 'x', 0, OptionArg.STRING_ARRAY, ref exclude, N_("Exclude prefix"), null }, + { null } +}; + +bool filtered (string file) { + foreach (var f in exclude) + if (file.has_prefix (f)) + return true; + + return false; +} + +public int main (string[] args) { + + var cmdline = string.joinv (" ", args); + var opt_context = new OptionContext (""); + opt_context.set_help_enabled (true); + opt_context.add_main_entries (options, null); + + // default values + dr = "TARGETDIR"; + var sourcedir = "SourceDir"; + + try { + opt_context.parse (ref args); + } catch (OptionError.BAD_VALUE err) { + GLib.stdout.printf (opt_context.get_help (true, null)); + return 1; + } catch (OptionError error) { + warning (error.message); + } + + if (prefix == null) { + GLib.stderr.printf ("Please specify source dir prefix\n"); + return 1; + } + if (vardir != null) + sourcedir = "$(%s)".printf (vardir); + + stdout.printf ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); + stdout.printf ("<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\">\n"); + stdout.printf (" <Fragment>\n"); + stdout.printf (" <DirectoryRef Id=\"%s\">\n".printf (dr)); + + string[] last_path = null; + List<string> cmpref = null; + var indent = " "; + + try { + var dis = new DataInputStream (new UnixInputStream (0, false)); + string line; + + while ((line = dis.read_line (null)) != null) { + if (!line.has_prefix (prefix)) + continue; + + var file = line[prefix.length:line.length]; + if (filtered (file)) + continue; + + var gfile = File.new_for_path (line); + var is_directory = gfile.query_file_type (FileQueryInfoFlags.NONE) == FileType.DIRECTORY; + + var dir = is_directory ? file : Path.get_dirname (file); + var path = dir.split (Path.DIR_SEPARATOR_S, -1); + var i = 0; + if (last_path != null) { + while ((path[i] != null && last_path[i] != null) && + path[i] == last_path[i]) + i++; + for (var j = last_path.length - i; j > 0; j--) { + indent = indent[0:-2]; + stdout.printf (indent + "</Directory>\n"); + } + } + for (; i < path.length; i++) { + stdout.printf (indent + "<Directory Id=\"%s\" Name=\"%s\">\n".printf (random_id ("dir"), path[i])); + indent += " "; + } + last_path = path; + + if (!is_directory) { + var id = generate_id ("cmp", 1, line); + cmpref.append (id); + stdout.printf (indent + "<Component Id=\"%s\" Guid=\"*\">\n".printf (id)); + file = sourcedir + Path.DIR_SEPARATOR_S + file; + stdout.printf (indent + " <File Id=\"%s\" KeyPath=\"yes\" Source=\"%s\"/>\n".printf (generate_id ("fil", 1, file), file)); + stdout.printf (indent + "</Component>\n"); + } + } + } catch (GLib.Error error) { + warning (error.message); + } + + foreach (var l in last_path) { + stdout.printf (indent + "</Directory>\n"); + indent = indent[0:-2]; + } + + stdout.printf (" </DirectoryRef>\n"); + stdout.printf (" </Fragment>\n"); + if (cg != null) { + stdout.printf (" <Fragment>\n"); + stdout.printf (" <ComponentGroup Id=\"%s\">\n".printf (cg)); + foreach (var id in cmpref) + stdout.printf (" <ComponentRef Id=\"%s\"/>\n".printf (id)); + stdout.printf (" </ComponentGroup>\n"); + stdout.printf (" </Fragment>\n"); + stdout.printf ("</Wix>\n"); + } + + stdout.printf ("<!-- generated with %s -->\n", Config.PACKAGE_STRING); + stdout.printf ("<!-- %s -->\n", cmdline.replace ("--", "-")); + return 0; +}
\ No newline at end of file |