diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2013-01-07 19:12:15 +0100 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@gmail.com> | 2013-01-07 22:42:41 +0100 |
commit | 78924b09d5cc79a8e2ee437877a8d23a2d522832 (patch) | |
tree | e71fa86684ec1521714ab46d04a260a53c16cd0c | |
parent | 43072f6d85baf2de3919cdd7fc2dd2062947843f (diff) | |
download | msitools-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.am | 1 | ||||
-rw-r--r-- | src/builder.vala | 82 | ||||
-rw-r--r-- | src/wix.vala | 81 | ||||
-rw-r--r-- | src/wixl.vala | 37 |
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) { |