summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2013-01-10 16:05:32 +0100
committerMarc-André Lureau <marcandre.lureau@gmail.com>2013-01-11 13:10:34 +0100
commit734bddba1cfa2a712a99a1bff784a617aec73c45 (patch)
treedf02b9362cb0ac1c5d16ded1ae91953be26b0a9e
parent1e664f3c0f043297b5d90cd596cfa04ed901b6be (diff)
downloadmsitools-734bddba1cfa2a712a99a1bff784a617aec73c45.tar.gz
msitools-734bddba1cfa2a712a99a1bff784a617aec73c45.tar.xz
msitools-734bddba1cfa2a712a99a1bff784a617aec73c45.zip
tools: add wixl-heat
A tool to generate WiX fragments
-rw-r--r--Makefile.am21
-rw-r--r--configure.ac6
-rw-r--r--tools/wixl/util.vala10
-rw-r--r--tools/wixl/wixl-heat.vala129
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