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 <keith.holman@windriver.com>
This commit is contained in:
Keith Holman
2017-04-21 10:42:35 -04:00
committed by Brad King
parent 03628bb699
commit 58cf9d417e
6 changed files with 37 additions and 12 deletions

View File

@@ -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.

View File

@@ -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(

View File

@@ -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");
}

View File

@@ -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");

View File

@@ -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);

View File

@@ -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;
}
}
}
}