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
{
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).
std::string Name;

View File

@ -106,56 +106,101 @@ int cmCPackPackageMakerGenerator::PackageFiles()
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* postflight = this->GetOption("CPACK_POSTFLIGHT_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(!preflight)
if(this->Components.empty())
{
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,
"Problem creating installer directory: "
<< preflightDirName.c_str() << std::endl);
return 0;
if ( !cmsys::SystemTools::MakeDirectory(preflightDirName.c_str()))
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"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,
"Problem creating installer directory: "
<< postflightDirName.c_str() << std::endl);
"Problem creating component packages directory: "
<< packageDir.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(),
// create package
std::string packageFileDir = packageDirFileName + "/Contents/Packages/";
if (!cmsys::SystemTools::MakeDirectory(packageFileDir.c_str()))
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem creating component PostFlight Packages directory: "
<< packageFileDir.c_str() << std::endl);
return 0;
}
std::string packageFile = packageFileDir +
this->GetPackageName(PostFlightComponent);
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");
}
if(postupgrade)
{
this->CopyInstallScript(resDir.c_str(),
postupgrade,
"postupgrade");
}
if (!this->Components.empty())
{
@ -778,6 +823,11 @@ WriteDistributionFile(const char* metapackageFile)
<< std::endl;
}
}
if(!this->PostFlightComponent.Name.empty())
{
choiceOut << "<line choice=\"" << PostFlightComponent.Name
<< "Choice\"></line>" << std::endl;
}
choiceOut << "</choices-outline>" << std::endl;
// Create the actual choices
@ -792,6 +842,12 @@ WriteDistributionFile(const char* metapackageFile)
{
CreateChoice(compIt->second, choiceOut);
}
if(!this->PostFlightComponent.Name.empty())
{
CreateChoice(PostFlightComponent, choiceOut);
}
this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());
// Create the distribution.dist file in the metapackage to turn it

View File

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