Browse Source

wix: adds ability to modify attributes with patch

Adds the ability to attributes to generated XML files for features with
the WiX patch system.  To modify attributes additional attributes may be
added within the 'CPackWixFragment' xml tag.

Fixes: #16813
Signed-off-by: Keith Holman <[email protected]>
Keith Holman 8 years ago
parent
commit
58cf9d417e

+ 7 - 0
Help/release/dev/wix-attributes-patch.rst

@@ -0,0 +1,7 @@
+wix-attributes-patch
+--------------------
+
+* The patching system within the :module:`CPackWIX` module now allows the
+  ability to set additional attributes.  This can be done by specifying
+  addional attributes with the ``CPackWiXFragment`` XML tag after the
+  ``Id`` attribute.  See the :variable:`CPACK_WIX_PATCH_FILE` variable.

+ 1 - 1
Source/CPack/WiX/cmCPackWIXGenerator.cxx

@@ -906,12 +906,12 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
       directoryDefinitions.BeginElement("Directory");
       directoryDefinitions.AddAttribute("Id", subDirectoryId);
       directoryDefinitions.AddAttribute("Name", fileName);
+      this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions);
 
       AddDirectoryAndFileDefinitions(
         fullPath, subDirectoryId, directoryDefinitions, fileDefinitions,
         featureDefinitions, packageExecutables, desktopExecutables, shortcuts);
 
-      this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions);
       directoryDefinitions.EndElement("Directory");
     } else {
       cmInstalledFile const* installedFile = this->GetInstalledFile(

+ 2 - 2
Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx

@@ -44,6 +44,8 @@ void cmWIXFeaturesSourceWriter::EmitFeatureForComponentGroup(
   AddAttributeUnlessEmpty("Title", group.DisplayName);
   AddAttributeUnlessEmpty("Description", group.Description);
 
+  patch.ApplyFragment("CM_G_" + group.Name, *this);
+
   for (std::vector<cmCPackComponentGroup*>::const_iterator i =
          group.Subgroups.begin();
        i != group.Subgroups.end(); ++i) {
@@ -56,8 +58,6 @@ void cmWIXFeaturesSourceWriter::EmitFeatureForComponentGroup(
     EmitFeatureForComponent(**i, patch);
   }
 
-  patch.ApplyFragment("CM_G_" + group.Name, *this);
-
   EndElement("Feature");
 }
 

+ 2 - 2
Source/CPack/WiX/cmWIXFilesSourceWriter.cxx

@@ -136,6 +136,7 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
     }
   }
 
+  patch.ApplyFragment(componentId, *this);
   BeginElement("File");
   AddAttribute("Id", fileId);
   AddAttribute("Source", filePath);
@@ -147,16 +148,15 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
   if (!(fileMode & S_IWRITE)) {
     AddAttribute("ReadOnly", "yes");
   }
+  patch.ApplyFragment(fileId, *this);
 
   if (installedFile) {
     cmWIXAccessControlList acl(Logger, *installedFile, *this);
     acl.Apply();
   }
 
-  patch.ApplyFragment(fileId, *this);
   EndElement("File");
 
-  patch.ApplyFragment(componentId, *this);
   EndElement("Component");
   EndElement("DirectoryRef");
 

+ 5 - 1
Source/CPack/WiX/cmWIXPatch.cxx

@@ -29,7 +29,11 @@ void cmWIXPatch::ApplyFragment(std::string const& id,
     return;
 
   const cmWIXPatchElement& fragment = i->second;
-
+  for (cmWIXPatchElement::attributes_t::const_iterator attr_i =
+         fragment.attributes.begin();
+       attr_i != fragment.attributes.end(); ++attr_i) {
+    writer.AddAttribute(attr_i->first, attr_i->second);
+  }
   this->ApplyElementChildren(fragment, writer);
 
   Fragments.erase(i);

+ 20 - 6
Source/CPack/WiX/cmWIXPatchParser.cxx

@@ -72,9 +72,11 @@ void cmWIXPatchParser::StartElement(const std::string& name, const char** atts)
 
 void cmWIXPatchParser::StartFragment(const char** attributes)
 {
+  cmWIXPatchElement* new_element = CM_NULLPTR;
+  /* find the id of for fragment */
   for (size_t i = 0; attributes[i]; i += 2) {
-    std::string key = attributes[i];
-    std::string value = attributes[i + 1];
+    const std::string key = attributes[i];
+    const std::string value = attributes[i + 1];
 
     if (key == "Id") {
       if (Fragments.find(value) != Fragments.end()) {
@@ -83,10 +85,22 @@ void cmWIXPatchParser::StartFragment(const char** attributes)
         ReportValidationError(tmp.str());
       }
 
-      ElementStack.push_back(&Fragments[value]);
-    } else {
-      ReportValidationError(
-        "The only allowed 'CPackWixFragment' attribute is 'Id'");
+      new_element = &Fragments[value];
+      ElementStack.push_back(new_element);
+    }
+  }
+
+  /* add any additional attributes for the fragement */
+  if (!new_element) {
+    ReportValidationError("No 'Id' specified for 'CPackWixFragment' element");
+  } else {
+    for (size_t i = 0; attributes[i]; i += 2) {
+      const std::string key = attributes[i];
+      const std::string value = attributes[i + 1];
+
+      if (key != "Id") {
+        new_element->attributes[key] = value;
+      }
     }
   }
 }