summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2013-01-07 19:12:15 +0100
committerMarc-André Lureau <marcandre.lureau@gmail.com>2013-01-07 22:42:41 +0100
commit78924b09d5cc79a8e2ee437877a8d23a2d522832 (patch)
treee71fa86684ec1521714ab46d04a260a53c16cd0c
parent43072f6d85baf2de3919cdd7fc2dd2062947843f (diff)
downloadmsitools-78924b09d5cc79a8e2ee437877a8d23a2d522832.tar.gz
msitools-78924b09d5cc79a8e2ee437877a8d23a2d522832.tar.xz
msitools-78924b09d5cc79a8e2ee437877a8d23a2d522832.zip
Learn to build from fragments: wixl out.msi Foo.wxs Bar.wxs
-rw-r--r--src/Makefile.am1
-rw-r--r--src/builder.vala82
-rw-r--r--src/wix.vala81
-rw-r--r--src/wixl.vala37
4 files changed, 156 insertions, 45 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ce618fb..3ff0034 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,6 +4,7 @@ bin_PROGRAMS = wixl
AM_CFLAGS = -w
AM_VALAFLAGS = \
+ -H wixl.h --use-header \
--vapidir=$(srcdir) --pkg config \
--enable-experimental \
--pkg gio-2.0 \
diff --git a/src/builder.vala b/src/builder.vala
index b546e0b..9f3ea1d 100644
--- a/src/builder.vala
+++ b/src/builder.vala
@@ -2,8 +2,7 @@ namespace Wixl {
class WixBuilder: WixElementVisitor {
- public WixBuilder (WixRoot root) {
- this.root = root;
+ public WixBuilder () {
add_path (".");
}
@@ -16,9 +15,35 @@ namespace Wixl {
path.append (file);
}
+ List<WixRoot> roots;
+ public void load_xml (string data) throws GLib.Error {
+ var doc = Xml.Parser.read_memory (data, data.length);
+ var root = new WixRoot ();
+ root.load_xml (doc);
+ roots.append (root);
+ }
+
+ public G? find_element<G> (string Id) {
+ foreach (var r in roots) {
+ var e = r.find_element<G> (Id);
+ if (e != null)
+ return e;
+ }
+
+ return null;
+ }
+
+ public G[] get_elements<G> () {
+ G[] elems = {};
+ foreach (var r in roots)
+ elems = r.add_elements<G> (elems);
+
+ return elems;
+ }
+
delegate void AddSequence (string action, int sequence) throws GLib.Error;
- void sequence_actions () throws GLib.Error {
+ private void sequence_actions () throws GLib.Error {
AddSequence add = (action, sequence) => {
db.table_admin_execute_sequence.add (action, sequence);
};
@@ -91,10 +116,10 @@ namespace Wixl {
add ("ExecuteAction", 1300);
}
- public void build_cabinet () throws GLib.Error {
+ private void build_cabinet () throws GLib.Error {
var sequence = 0;
- var medias = root.get_elements<WixMedia> ();
- var files = root.get_elements<WixFile> ();
+ var medias = get_elements<WixMedia> ();
+ var files = get_elements<WixFile> ();
foreach (var m in medias) {
var folder = new GCab.Folder (GCab.Compression.MSZIP);
@@ -121,8 +146,8 @@ namespace Wixl {
}
}
- public void shortcut_target () throws GLib.Error {
- var shortcuts = root.get_elements<WixShortcut> ();
+ private void shortcut_target () throws GLib.Error {
+ var shortcuts = get_elements<WixShortcut> ();
foreach (var sc in shortcuts) {
var component = sc.get_component ();
@@ -134,7 +159,12 @@ namespace Wixl {
public MsiDatabase build () throws GLib.Error {
db = new MsiDatabase ();
- root.accept (this);
+ foreach (var r in roots) {
+ root = r;
+ root.accept (this);
+ }
+ root = null;
+
shortcut_target ();
sequence_actions ();
build_cabinet ();
@@ -210,18 +240,32 @@ namespace Wixl {
SHARED,
}
+ G? resolve<G> (WixElement element) throws GLib.Error {
+ if (element.get_type () == typeof (G))
+ return element;
+ else if (element is WixElementRef) {
+ var ref = element as WixElementRef<G>;
+ if (ref.ref_type != typeof (G))
+ return null;
+ if (ref.resolved != null)
+ return ref.resolved;
+ ref.resolved = find_element<G> (element.Id);
+ return ref.resolved;
+ }
+
+ throw new Wixl.Error.FAILED ("couldn't resolve %s", element.Id);
+ }
+
public override void visit_component (WixComponent comp) throws GLib.Error {
var attr = 0;
if (comp.key is WixRegistryValue)
attr |= ComponentAttribute.REGISTRY_KEY_PATH;
- if (comp.parent.get_type () == typeof (WixDirectory)) {
- var parent = comp.parent as WixDirectory;
- db.table_component.add (comp.Id, add_braces (comp.Guid), parent.Id, attr,
- comp.key != null ? comp.key.Id : null);
- } else
- warning ("unhandled parent type %s", comp.parent.name);
+ var parent = resolve<WixDirectory> (comp.parent);
+ db.table_component.add (comp.Id, add_braces (comp.Guid), parent.Id, attr,
+ comp.key != null ? comp.key.Id : null);
+
}
public override void visit_feature (WixFeature feature) throws GLib.Error {
@@ -232,7 +276,7 @@ namespace Wixl {
if (ref.parent is WixFeature) {
var feature = ref.parent as WixFeature;
- var component = root.find_element (typeof (WixComponent), @ref.Id) as WixComponent;
+ var component = resolve<WixComponent> (@ref);
component.in_feature.append (feature);
db.table_feature_components.add (feature.Id, @ref.Id);
} else
@@ -363,6 +407,12 @@ namespace Wixl {
public override void visit_create_folder (WixCreateFolder folder) throws GLib.Error {
}
+
+ public override void visit_fragment (WixFragment fragment) throws GLib.Error {
+ }
+
+ public override void visit_directory_ref (WixDirectoryRef ref) throws GLib.Error {
+ }
}
} // Wixl
diff --git a/src/wix.vala b/src/wix.vala
index 2c824f8..324d391 100644
--- a/src/wix.vala
+++ b/src/wix.vala
@@ -15,6 +15,8 @@ namespace Wixl {
public abstract void visit_file (WixFile reg) throws GLib.Error;
public abstract void visit_shortcut (WixShortcut shortcut) throws GLib.Error;
public abstract void visit_create_folder (WixCreateFolder folder) throws GLib.Error;
+ public abstract void visit_fragment (WixFragment fragment) throws GLib.Error;
+ public abstract void visit_directory_ref (WixDirectoryRef ref) throws GLib.Error;
}
public abstract class WixElement: Object {
@@ -35,8 +37,8 @@ namespace Wixl {
public class void add_child_types (HashTable<string, Type> table, Type[] child_types) {
foreach (var t in child_types) {
- var name = ((WixElement) Object.new (t)).name;
- table.insert (name, t);
+ var n = ((WixElement) Object.new (t)).name;
+ table.insert (n, t);
}
}
@@ -45,7 +47,7 @@ namespace Wixl {
children.append (e);
}
- private G[] add_elements<G> (owned G[] a) {
+ public G[] add_elements<G> (owned G[] a) {
// jeez, vala, took me a while to workaround generics & array issues..
var array = a;
var type = typeof (G);
@@ -63,12 +65,13 @@ namespace Wixl {
return add_elements<G> ({});
}
- public WixElement? find_element (Type type, string Id) {
+ public G? find_element<G> (string Id) {
+ var type = typeof (G);
if (this.Id == Id && this.get_type () == type)
return this;
foreach (var c in children) {
- var e = c.find_element (type, Id);
+ var e = c.find_element<G> (Id);
if (e != null)
return e;
}
@@ -150,6 +153,22 @@ namespace Wixl {
}
}
+ public class WixFragment: WixElement {
+ static construct {
+ name = "Fragment";
+
+ add_child_types (child_types, {
+ typeof (WixDirectory),
+ typeof (WixDirectoryRef),
+ });
+ }
+
+ public override void accept (WixElementVisitor visitor) throws GLib.Error {
+ base.accept (visitor);
+ visitor.visit_fragment (this);
+ }
+ }
+
public class WixProperty: WixElement {
static construct {
name = "Property";
@@ -292,10 +311,17 @@ namespace Wixl {
static construct {
name = "Feature";
- add_child_types (child_types, { typeof (WixComponentRef) });
+ add_child_types (child_types, {
+ typeof (WixComponentRef),
+ typeof (WixFeature),
+ });
}
public string Level { get; set; }
+ public string Title { get; set; }
+ public string Description { get; set; }
+ public string Display { get; set; }
+ public string ConfigurableDirectory { get; set; }
public override void accept (WixElementVisitor visitor) throws GLib.Error {
base.accept (visitor);
@@ -303,9 +329,10 @@ namespace Wixl {
}
}
- public class WixComponentRef: WixElement {
+ public class WixComponentRef: WixElementRef<WixComponent> {
static construct {
name = "ComponentRef";
+ ref_type = typeof (WixComponent);
}
public override void accept (WixElementVisitor visitor) throws GLib.Error {
@@ -318,12 +345,12 @@ namespace Wixl {
name = "Product";
add_child_types (child_types, {
- typeof (WixPackage),
+ typeof (WixDirectory),
+ typeof (WixFeature),
typeof (WixIcon),
- typeof (WixProperty),
typeof (WixMedia),
- typeof (WixDirectory),
- typeof (WixFeature)
+ typeof (WixPackage),
+ typeof (WixProperty)
});
}
@@ -399,11 +426,41 @@ namespace Wixl {
}
}
+ public class WixElementRef<G>: WixElement {
+ public class Type ref_type;
+ public G? resolved;
+
+ // protected WixElementRef () {
+ // // FIXME vala: class init/construct fails, construct fails...
+ // ref_type = typeof (G);
+ // }
+ }
+
+ public class WixDirectoryRef: WixElementRef<WixDirectory> {
+ static construct {
+ name = "DirectoryRef";
+ ref_type = typeof (WixDirectory);
+
+ add_child_types (child_types, {
+ typeof (WixDirectory),
+ typeof (WixComponent),
+ });
+ }
+
+ public override void accept (WixElementVisitor visitor) throws GLib.Error {
+ base.accept (visitor);
+ visitor.visit_directory_ref (this);
+ }
+ }
+
class WixRoot: WixElement {
static construct {
name = "Wix";
- add_child_types (child_types, { typeof (WixProduct) });
+ add_child_types (child_types, {
+ typeof (WixProduct),
+ typeof (WixFragment),
+ });
}
public string xmlns { get; set; }
diff --git a/src/wixl.vala b/src/wixl.vala
index 68451c9..db3d3ac 100644
--- a/src/wixl.vala
+++ b/src/wixl.vala
@@ -2,15 +2,15 @@ using Posix;
namespace Wixl {
-static bool version;
-[CCode (array_length = false, array_null_terminated = true)]
-static string[] files;
+ static bool version;
+ [CCode (array_length = false, array_null_terminated = true)]
+ static string[] files;
-private const OptionEntry[] options = {
- { "version", 0, 0, OptionArg.NONE, ref version, N_("Display version number"), null },
- { "", 0, 0, OptionArg.FILENAME_ARRAY, ref files, null, N_("OUTPUT_FILE INPUT_FILE...") },
- { null }
-};
+ private const OptionEntry[] options = {
+ { "version", 0, 0, OptionArg.NONE, ref version, N_("Display version number"), null },
+ { "", 0, 0, OptionArg.FILENAME_ARRAY, ref files, null, N_("OUTPUT_FILE INPUT_FILE...") },
+ { null }
+ };
int main (string[] args) {
Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
@@ -37,20 +37,23 @@ private const OptionEntry[] options = {
exit (0);
}
- if (files.length != 2) {
+ if (files.length < 2) {
GLib.stderr.printf (_("Please specify output and input files.\n"));
exit (1);
}
try {
- var file = File.new_for_commandline_arg (files[1]);
- string data;
- FileUtils.get_contents (file.get_path (), out data);
- var doc = Xml.Parser.read_memory (data, data.length);
- var root = new WixRoot ();
- root.load_xml (doc);
- var builder = new WixBuilder (root);
- builder.add_path (file.get_parent ().get_path ());
+ var builder = new WixBuilder ();
+ foreach (var arg in files[1:files.length]) {
+ print ("Loading %s...\n", arg);
+ var file = File.new_for_commandline_arg (arg);
+ string data;
+ FileUtils.get_contents (file.get_path (), out data);
+ builder.load_xml (data);
+ builder.add_path (file.get_parent ().get_path ());
+ }
+
+ print ("Building %s...\n", files[0]);
var msi = builder.build ();
msi.build (files[0]);
} catch (GLib.Error error) {