CPack/PackageMaker: port to cmXMLWriter

This commit is contained in:
Daniel Pfeifer 2016-06-08 23:35:31 +02:00 committed by Brad King
parent ba92e11f8b
commit e9da5192e5
3 changed files with 85 additions and 85 deletions

View File

@ -18,6 +18,7 @@
#include "cmLocalGenerator.h" #include "cmLocalGenerator.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h" #include "cmake.h"
#include <cmsys/Glob.hxx> #include <cmsys/Glob.hxx>
@ -76,14 +77,15 @@ void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile)
// Create the choice outline, which provides a tree-based view of // Create the choice outline, which provides a tree-based view of
// the components in their groups. // the components in their groups.
std::ostringstream choiceOut; std::ostringstream choiceOut;
choiceOut << "<choices-outline>" << std::endl; cmXMLWriter xout(choiceOut, 1);
xout.StartElement("choices-outline");
// Emit the outline for the groups // Emit the outline for the groups
std::map<std::string, cmCPackComponentGroup>::iterator groupIt; std::map<std::string, cmCPackComponentGroup>::iterator groupIt;
for (groupIt = this->ComponentGroups.begin(); for (groupIt = this->ComponentGroups.begin();
groupIt != this->ComponentGroups.end(); ++groupIt) { groupIt != this->ComponentGroups.end(); ++groupIt) {
if (groupIt->second.ParentGroup == 0) { if (groupIt->second.ParentGroup == 0) {
CreateChoiceOutline(groupIt->second, choiceOut); CreateChoiceOutline(groupIt->second, xout);
} }
} }
@ -92,28 +94,32 @@ void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile)
for (compIt = this->Components.begin(); compIt != this->Components.end(); for (compIt = this->Components.begin(); compIt != this->Components.end();
++compIt) { ++compIt) {
if (!compIt->second.Group) { if (!compIt->second.Group) {
choiceOut << "<line choice=\"" << compIt->first << "Choice\"></line>" xout.StartElement("line");
<< std::endl; xout.Attribute("choice", compIt->first + "Choice");
xout.Content(""); // Avoid self-closing tag.
xout.EndElement();
} }
} }
if (!this->PostFlightComponent.Name.empty()) { if (!this->PostFlightComponent.Name.empty()) {
choiceOut << "<line choice=\"" << PostFlightComponent.Name xout.StartElement("line");
<< "Choice\"></line>" << std::endl; xout.Attribute("choice", PostFlightComponent.Name + "Choice");
xout.Content(""); // Avoid self-closing tag.
xout.EndElement();
} }
choiceOut << "</choices-outline>" << std::endl; xout.EndElement(); // choices-outline>
// Create the actual choices // Create the actual choices
for (groupIt = this->ComponentGroups.begin(); for (groupIt = this->ComponentGroups.begin();
groupIt != this->ComponentGroups.end(); ++groupIt) { groupIt != this->ComponentGroups.end(); ++groupIt) {
CreateChoice(groupIt->second, choiceOut); CreateChoice(groupIt->second, xout);
} }
for (compIt = this->Components.begin(); compIt != this->Components.end(); for (compIt = this->Components.begin(); compIt != this->Components.end();
++compIt) { ++compIt) {
CreateChoice(compIt->second, choiceOut); CreateChoice(compIt->second, xout);
} }
if (!this->PostFlightComponent.Name.empty()) { if (!this->PostFlightComponent.Name.empty()) {
CreateChoice(PostFlightComponent, choiceOut); CreateChoice(PostFlightComponent, xout);
} }
this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str()); this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());
@ -124,40 +130,44 @@ void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile)
} }
void cmCPackPKGGenerator::CreateChoiceOutline( void cmCPackPKGGenerator::CreateChoiceOutline(
const cmCPackComponentGroup& group, std::ostringstream& out) const cmCPackComponentGroup& group, cmXMLWriter& xout)
{ {
out << "<line choice=\"" << group.Name << "Choice\">" << std::endl; xout.StartElement("line");
xout.Attribute("choice", group.Name + "Choice");
std::vector<cmCPackComponentGroup*>::const_iterator groupIt; std::vector<cmCPackComponentGroup*>::const_iterator groupIt;
for (groupIt = group.Subgroups.begin(); groupIt != group.Subgroups.end(); for (groupIt = group.Subgroups.begin(); groupIt != group.Subgroups.end();
++groupIt) { ++groupIt) {
CreateChoiceOutline(**groupIt, out); CreateChoiceOutline(**groupIt, xout);
} }
std::vector<cmCPackComponent*>::const_iterator compIt; std::vector<cmCPackComponent*>::const_iterator compIt;
for (compIt = group.Components.begin(); compIt != group.Components.end(); for (compIt = group.Components.begin(); compIt != group.Components.end();
++compIt) { ++compIt) {
out << " <line choice=\"" << (*compIt)->Name << "Choice\"></line>" xout.StartElement("line");
<< std::endl; xout.Attribute("choice", (*compIt)->Name + "Choice");
xout.Content(""); // Avoid self-closing tag.
xout.EndElement();
} }
out << "</line>" << std::endl; xout.EndElement();
} }
void cmCPackPKGGenerator::CreateChoice(const cmCPackComponentGroup& group, void cmCPackPKGGenerator::CreateChoice(const cmCPackComponentGroup& group,
std::ostringstream& out) cmXMLWriter& xout)
{ {
out << "<choice id=\"" << group.Name << "Choice\" " xout.StartElement("choice");
<< "title=\"" << group.DisplayName << "\" " xout.Attribute("id", group.Name + "Choice");
<< "start_selected=\"true\" " xout.Attribute("title", group.DisplayName);
<< "start_enabled=\"true\" " xout.Attribute("start_selected", "true");
<< "start_visible=\"true\" "; xout.Attribute("start_enabled", "true");
xout.Attribute("start_visible", "true");
if (!group.Description.empty()) { if (!group.Description.empty()) {
out << "description=\"" << EscapeForXML(group.Description) << "\""; xout.Attribute("description", group.Description);
} }
out << "></choice>" << std::endl; xout.EndElement();
} }
void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component, void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component,
std::ostringstream& out) cmXMLWriter& xout)
{ {
std::string packageId = "com."; std::string packageId = "com.";
packageId += this->GetOption("CPACK_PACKAGE_VENDOR"); packageId += this->GetOption("CPACK_PACKAGE_VENDOR");
@ -166,18 +176,16 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component,
packageId += '.'; packageId += '.';
packageId += component.Name; packageId += component.Name;
out << "<choice id=\"" << component.Name << "Choice\" " xout.StartElement("choice");
<< "title=\"" << component.DisplayName << "\" " xout.Attribute("id", component.Name + "Choice");
<< "start_selected=\"" xout.Attribute("title", component.DisplayName);
<< (component.IsDisabledByDefault && !component.IsRequired ? "false" xout.Attribute(
: "true") "start_selected",
<< "\" " component.IsDisabledByDefault && !component.IsRequired ? "false" : "true");
<< "start_enabled=\"" << (component.IsRequired ? "false" : "true") xout.Attribute("start_enabled", component.IsRequired ? "false" : "true");
<< "\" " xout.Attribute("start_visible", component.IsHidden ? "false" : "true");
<< "start_visible=\"" << (component.IsHidden ? "false" : "true")
<< "\" ";
if (!component.Description.empty()) { if (!component.Description.empty()) {
out << "description=\"" << EscapeForXML(component.Description) << "\" "; xout.Attribute("description", component.Description);
} }
if (!component.Dependencies.empty() || if (!component.Dependencies.empty() ||
!component.ReverseDependencies.empty()) { !component.ReverseDependencies.empty()) {
@ -195,16 +203,17 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component,
// This way, selecting C will automatically select everything it depends // This way, selecting C will automatically select everything it depends
// on (B and A), while selecting something that depends on C--either D // on (B and A), while selecting something that depends on C--either D
// or E--will automatically cause C to get selected. // or E--will automatically cause C to get selected.
out << "selected=\"my.choice.selected"; std::ostringstream selected("my.choice.selected");
std::set<const cmCPackComponent*> visited; std::set<const cmCPackComponent*> visited;
AddDependencyAttributes(component, visited, out); AddDependencyAttributes(component, visited, selected);
visited.clear(); visited.clear();
AddReverseDependencyAttributes(component, visited, out); AddReverseDependencyAttributes(component, visited, selected);
out << "\""; xout.Attribute("selected", selected.str());
} }
out << ">" << std::endl; xout.StartElement("pkg-ref");
out << " <pkg-ref id=\"" << packageId << "\"></pkg-ref>" << std::endl; xout.Attribute("id", packageId);
out << "</choice>" << std::endl; xout.EndElement(); // pkg-ref
xout.EndElement(); // choice
// Create a description of the package associated with this // Create a description of the package associated with this
// component. // component.
@ -219,17 +228,20 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component,
unsigned long installedSize = unsigned long installedSize =
component.GetInstalledSizeInKbytes(dirName.c_str()); component.GetInstalledSizeInKbytes(dirName.c_str());
out << "<pkg-ref id=\"" << packageId << "\" " xout.StartElement("pkg-ref");
<< "version=\"" << this->GetOption("CPACK_PACKAGE_VERSION") << "\" " xout.Attribute("id", packageId);
<< "installKBytes=\"" << installedSize << "\" " xout.Attribute("version", this->GetOption("CPACK_PACKAGE_VERSION"));
<< ">"; xout.Attribute("installKBytes", installedSize);
xout.Attribute("auth", "Admin");
xout.Attribute("onConclusion", "None");
if (component.IsDownloaded) { if (component.IsDownloaded) {
out << this->GetOption("CPACK_DOWNLOAD_SITE") xout.Content(this->GetOption("CPACK_DOWNLOAD_SITE"));
<< this->GetPackageName(component); xout.Content(this->GetPackageName(component));
} else { } else {
out << "file:./" << relativePackageLocation; xout.Content("file:./");
xout.Content(relativePackageLocation);
} }
out << "</pkg-ref>" << std::endl; xout.EndElement(); // pkg-ref
} }
void cmCPackPKGGenerator::AddDependencyAttributes( void cmCPackPKGGenerator::AddDependencyAttributes(
@ -244,7 +256,7 @@ void cmCPackPKGGenerator::AddDependencyAttributes(
std::vector<cmCPackComponent*>::const_iterator dependIt; std::vector<cmCPackComponent*>::const_iterator dependIt;
for (dependIt = component.Dependencies.begin(); for (dependIt = component.Dependencies.begin();
dependIt != component.Dependencies.end(); ++dependIt) { dependIt != component.Dependencies.end(); ++dependIt) {
out << " &amp;&amp; choices['" << (*dependIt)->Name << "Choice'].selected"; out << " && choices['" << (*dependIt)->Name << "Choice'].selected";
AddDependencyAttributes(**dependIt, visited, out); AddDependencyAttributes(**dependIt, visited, out);
} }
} }
@ -266,15 +278,6 @@ void cmCPackPKGGenerator::AddReverseDependencyAttributes(
} }
} }
std::string cmCPackPKGGenerator::EscapeForXML(std::string str)
{
cmSystemTools::ReplaceString(str, "&", "&amp;");
cmSystemTools::ReplaceString(str, "<", "&lt;");
cmSystemTools::ReplaceString(str, ">", "&gt;");
cmSystemTools::ReplaceString(str, "\"", "&quot;");
return str;
}
bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name, bool cmCPackPKGGenerator::CopyCreateResourceFile(const std::string& name,
const std::string& dirName) const std::string& dirName)
{ {

View File

@ -16,6 +16,7 @@
#include "cmCPackGenerator.h" #include "cmCPackGenerator.h"
class cmCPackComponent; class cmCPackComponent;
class cmXMLWriter;
/** \class cmCPackPKGGenerator /** \class cmCPackPKGGenerator
* \brief A generator for pkg files * \brief A generator for pkg files
@ -78,21 +79,15 @@ protected:
// their components in a form that can be used by distribution // their components in a form that can be used by distribution
// metapackages. // metapackages.
void CreateChoiceOutline(const cmCPackComponentGroup& group, void CreateChoiceOutline(const cmCPackComponentGroup& group,
std::ostringstream& out); cmXMLWriter& xout);
/// Create the "choice" XML element to describe a component group /// Create the "choice" XML element to describe a component group
/// for the installer GUI. /// for the installer GUI.
void CreateChoice(const cmCPackComponentGroup& group, void CreateChoice(const cmCPackComponentGroup& group, cmXMLWriter& xout);
std::ostringstream& out);
/// Create the "choice" XML element to describe a component for the /// Create the "choice" XML element to describe a component for the
/// installer GUI. /// installer GUI.
void CreateChoice(const cmCPackComponent& component, void CreateChoice(const cmCPackComponent& component, cmXMLWriter& xout);
std::ostringstream& out);
// Escape the given string to make it usable as an XML attribute
// value.
std::string EscapeForXML(std::string str);
// The PostFlight component when creating a metapackage // The PostFlight component when creating a metapackage
cmCPackComponent PostFlightComponent; cmCPackComponent PostFlightComponent;

View File

@ -17,6 +17,7 @@
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h" #include "cmake.h"
#include <cmsys/FStream.hxx> #include <cmsys/FStream.hxx>
@ -523,21 +524,22 @@ bool cmCPackPackageMakerGenerator::GenerateComponentPackage(
std::string descriptionFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); std::string descriptionFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
descriptionFile += '/' + component.Name + "-Description.plist"; descriptionFile += '/' + component.Name + "-Description.plist";
cmsys::ofstream out(descriptionFile.c_str()); cmsys::ofstream out(descriptionFile.c_str());
out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl cmXMLWriter xout(out);
<< "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\"" xout.StartDocument();
<< "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << std::endl xout.Doctype("plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
<< "<plist version=\"1.4\">" << std::endl "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
<< "<dict>" << std::endl xout.StartElement("plist");
<< " <key>IFPkgDescriptionTitle</key>" << std::endl xout.Attribute("version", "1.4");
<< " <string>" << component.DisplayName << "</string>" << std::endl xout.StartElement("dict");
<< " <key>IFPkgDescriptionVersion</key>" << std::endl xout.Element("key", "IFPkgDescriptionTitle");
<< " <string>" << this->GetOption("CPACK_PACKAGE_VERSION") xout.Element("string", component.DisplayName);
<< "</string>" << std::endl xout.Element("key", "IFPkgDescriptionVersion");
<< " <key>IFPkgDescriptionDescription</key>" << std::endl xout.Element("string", this->GetOption("CPACK_PACKAGE_VERSION"));
<< " <string>" + this->EscapeForXML(component.Description) xout.Element("key", "IFPkgDescriptionDescription");
<< "</string>" << std::endl xout.Element("string", component.Description);
<< "</dict>" << std::endl xout.EndElement(); // dict
<< "</plist>" << std::endl; xout.EndElement(); // plist
xout.EndDocument();
out.close(); out.close();
// Create the Info.plist file for this component // Create the Info.plist file for this component