PackageMaker: Enable postflight script in component mode (#12375)

Previously, setting CPACK_POSTFLIGHT_SCRIPT had no effect in
component mode, when CPACK_COMPONENTS_ALL was set.

In component mode, a .mpkg is created that contains multiple .pkg's.
Because postflight scripts only work in a .pkg, add another .pkg to the
.mpkg and put the postflight script in that.
This is the same approach taken by the PackageMaker GUI when adding
a postflight script to a metapackage.
This commit is contained in:
Clinton Stimpson 2012-10-27 11:07:31 -06:00 committed by Brad King
parent 4322816b6b
commit 4374441f3f
3 changed files with 97 additions and 36 deletions

View File

@ -42,7 +42,9 @@ public:
class cmCPackComponent class cmCPackComponent
{ {
public: public:
cmCPackComponent() : Group(0), TotalSize(0) { } cmCPackComponent() : Group(0), IsRequired(true), IsHidden(false),
IsDisabledByDefault(false), IsDownloaded(false),
TotalSize(0) { }
/// The name of the component (used to reference the component). /// The name of the component (used to reference the component).
std::string Name; std::string Name;

View File

@ -106,56 +106,101 @@ int cmCPackPackageMakerGenerator::PackageFiles()
resDir += "/en.lproj"; resDir += "/en.lproj";
} }
// Create directory structure
std::string preflightDirName = resDir + "/PreFlight";
std::string postflightDirName = resDir + "/PostFlight";
const char* preflight = this->GetOption("CPACK_PREFLIGHT_SCRIPT"); const char* preflight = this->GetOption("CPACK_PREFLIGHT_SCRIPT");
const char* postflight = this->GetOption("CPACK_POSTFLIGHT_SCRIPT"); const char* postflight = this->GetOption("CPACK_POSTFLIGHT_SCRIPT");
const char* postupgrade = this->GetOption("CPACK_POSTUPGRADE_SCRIPT"); const char* postupgrade = this->GetOption("CPACK_POSTUPGRADE_SCRIPT");
// if preflight or postflight scripts not there create directories
// of the same name, I think this makes it work if(this->Components.empty())
if(!preflight)
{ {
if ( !cmsys::SystemTools::MakeDirectory(preflightDirName.c_str())) // Create directory structure
std::string preflightDirName = resDir + "/PreFlight";
std::string postflightDirName = resDir + "/PostFlight";
// if preflight or postflight scripts not there create directories
// of the same name, I think this makes it work
if(!preflight)
{ {
cmCPackLogger(cmCPackLog::LOG_ERROR, if ( !cmsys::SystemTools::MakeDirectory(preflightDirName.c_str()))
"Problem creating installer directory: " {
<< preflightDirName.c_str() << std::endl); cmCPackLogger(cmCPackLog::LOG_ERROR,
return 0; "Problem creating installer directory: "
<< preflightDirName.c_str() << std::endl);
return 0;
}
}
if(!postflight)
{
if ( !cmsys::SystemTools::MakeDirectory(postflightDirName.c_str()))
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem creating installer directory: "
<< postflightDirName.c_str() << std::endl);
return 0;
}
}
// if preflight, postflight, or postupgrade are set
// then copy them into the resource directory and make
// them executable
if(preflight)
{
this->CopyInstallScript(resDir.c_str(),
preflight,
"preflight");
}
if(postflight)
{
this->CopyInstallScript(resDir.c_str(),
postflight,
"postflight");
}
if(postupgrade)
{
this->CopyInstallScript(resDir.c_str(),
postupgrade,
"postupgrade");
} }
} }
if(!postflight) else if(postflight)
{ {
if ( !cmsys::SystemTools::MakeDirectory(postflightDirName.c_str())) // create a postflight component to house the script
this->PostFlightComponent.Name = "PostFlight";
this->PostFlightComponent.DisplayName = "PostFlight";
this->PostFlightComponent.Description = "PostFlight";
this->PostFlightComponent.IsHidden = true;
// empty directory for pkg contents
std::string packageDir = toplevel + "/" + PostFlightComponent.Name;
if (!cmsys::SystemTools::MakeDirectory(packageDir.c_str()))
{ {
cmCPackLogger(cmCPackLog::LOG_ERROR, cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem creating installer directory: " "Problem creating component packages directory: "
<< postflightDirName.c_str() << std::endl); << packageDir.c_str() << std::endl);
return 0; return 0;
} }
}
// if preflight, postflight, or postupgrade are set // create package
// then copy them into the resource directory and make std::string packageFileDir = packageDirFileName + "/Contents/Packages/";
// them executable if (!cmsys::SystemTools::MakeDirectory(packageFileDir.c_str()))
if(preflight) {
{ cmCPackLogger(cmCPackLog::LOG_ERROR,
this->CopyInstallScript(resDir.c_str(), "Problem creating component PostFlight Packages directory: "
preflight, << packageFileDir.c_str() << std::endl);
"preflight"); return 0;
} }
if(postflight) std::string packageFile = packageFileDir +
{ this->GetPackageName(PostFlightComponent);
this->CopyInstallScript(resDir.c_str(), if (!this->GenerateComponentPackage(packageFile.c_str(),
packageDir.c_str(),
PostFlightComponent))
{
return 0;
}
// copy postflight script into resource directory of .pkg
std::string resourceDir = packageFile + "/Contents/Resources";
this->CopyInstallScript(resourceDir.c_str(),
postflight, postflight,
"postflight"); "postflight");
} }
if(postupgrade)
{
this->CopyInstallScript(resDir.c_str(),
postupgrade,
"postupgrade");
}
if (!this->Components.empty()) if (!this->Components.empty())
{ {
@ -778,6 +823,11 @@ WriteDistributionFile(const char* metapackageFile)
<< std::endl; << std::endl;
} }
} }
if(!this->PostFlightComponent.Name.empty())
{
choiceOut << "<line choice=\"" << PostFlightComponent.Name
<< "Choice\"></line>" << std::endl;
}
choiceOut << "</choices-outline>" << std::endl; choiceOut << "</choices-outline>" << std::endl;
// Create the actual choices // Create the actual choices
@ -792,6 +842,12 @@ WriteDistributionFile(const char* metapackageFile)
{ {
CreateChoice(compIt->second, choiceOut); CreateChoice(compIt->second, choiceOut);
} }
if(!this->PostFlightComponent.Name.empty())
{
CreateChoice(PostFlightComponent, choiceOut);
}
this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str()); this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());
// Create the distribution.dist file in the metapackage to turn it // Create the distribution.dist file in the metapackage to turn it

View File

@ -112,6 +112,9 @@ protected:
// value. // value.
std::string EscapeForXML(std::string str); std::string EscapeForXML(std::string str);
// The PostFlight component when creating a metapackage
cmCPackComponent PostFlightComponent;
double PackageMakerVersion; double PackageMakerVersion;
double PackageCompatibilityVersion; double PackageCompatibilityVersion;
}; };