summaryrefslogtreecommitdiffstats
path: root/Source/CPack
diff options
context:
space:
mode:
authorRobert Maynard <robert.maynard@kitware.com>2014-09-26 18:38:38 (GMT)
committerBrad King <brad.king@kitware.com>2015-11-13 13:44:15 (GMT)
commit167a465565cda9bb33d2e919509c23a761ea45e9 (patch)
tree8206168801645e40f39675c9e611b66bf2e56b42 /Source/CPack
parent9c1dfbfd600819a751d4c5058fd939650ee6d6b4 (diff)
downloadCMake-167a465565cda9bb33d2e919509c23a761ea45e9.zip
CMake-167a465565cda9bb33d2e919509c23a761ea45e9.tar.gz
CMake-167a465565cda9bb33d2e919509c23a761ea45e9.tar.bz2
CPack/DragNDrop: Optionally run an AppleScript when making a package
While the DragNDropGenerator supports custom DS_Store and backgrounds, it is still very hard to automatically setup nice looking packages. The primary issue is that the DS_Store embeds the name of the volume in the path to backgrounds, which means that if a package embeds the version in its volume name a new DS_Store must generated for each release. Instead one now can use applescript to setup the DS_Store. This change also ensures that temporary RW image has enough space for these changes, creating 1 MB dummy padding file, that is later removed from the image. Co-Author: Adam Strzelecki <adam.strzelecki@java.pl>
Diffstat (limited to 'Source/CPack')
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx110
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.h1
2 files changed, 100 insertions, 11 deletions
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index eff302c..7a93fc6 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -271,6 +271,28 @@ bool cmCPackDragNDropGenerator::CopyFile(std::ostringstream& source,
}
//----------------------------------------------------------------------
+bool cmCPackDragNDropGenerator::CreateEmptyFile(std::ostringstream& target,
+ size_t size)
+{
+ cmsys::ofstream fout(target.str().c_str(),
+ std::ios::out | std::ios::binary);
+ if(!fout)
+ {
+ return false;
+ }
+ else
+ {
+ // Seek to desired size - 1 byte
+ fout.seekp(size - 1, std::ios_base::beg);
+ char byte = 0;
+ // Write one byte to ensure file grows
+ fout.write(&byte, 1);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
bool cmCPackDragNDropGenerator::RunCommand(std::ostringstream& command,
std::string* output)
{
@@ -331,6 +353,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
this->GetOption("CPACK_DMG_LANGUAGES")
? this->GetOption("CPACK_DMG_LANGUAGES") : "";
+ const std::string cpack_dmg_ds_store_setup_script =
+ this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT")
+ ? this->GetOption("CPACK_DMG_DS_STORE_SETUP_SCRIPT") : "";
+
// only put license on dmg if is user provided
if(!cpack_license_file.empty() &&
cpack_license_file.find("CPack.GenericLicense.txt") != std::string::npos)
@@ -424,6 +450,25 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
}
}
+ bool remount_image = !cpack_package_icon.empty() ||
+ !cpack_dmg_ds_store_setup_script.empty();
+
+ // Create 1 MB dummy padding file in staging area when we need to remount
+ // image, so we have enough space for storing changes ...
+ if(remount_image)
+ {
+ std::ostringstream dummy_padding;
+ dummy_padding << staging.str() << "/.dummy-padding-file";
+ if(!this->CreateEmptyFile(dummy_padding, 1048576))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error creating dummy padding file."
+ << std::endl);
+
+ return 0;
+ }
+ }
+
// Create a temporary read-write disk image ...
std::string temp_image = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
temp_image += "/temp.dmg";
@@ -447,10 +492,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
return 0;
}
- // Optionally set the custom icon flag for the image ...
- if(!cpack_package_icon.empty())
+ if(remount_image)
{
- std::ostringstream temp_mount;
+ // Store that we have a failure so that we always unmount the image
+ // before we exit.
+ bool had_error = false;
std::ostringstream attach_command;
attach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
@@ -469,20 +515,57 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
cmsys::RegularExpression mountpoint_regex(".*(/Volumes/[^\n]+)\n.*");
mountpoint_regex.find(attach_output.c_str());
+ std::ostringstream temp_mount;
temp_mount << mountpoint_regex.match(1);
- std::ostringstream setfile_command;
- setfile_command << this->GetOption("CPACK_COMMAND_SETFILE");
- setfile_command << " -a C";
- setfile_command << " \"" << temp_mount.str() << "\"";
-
- if(!this->RunCommand(setfile_command))
+ // Remove dummy padding file so we have enough space on RW image ...
+ std::ostringstream dummy_padding;
+ dummy_padding << temp_mount.str() << "/.dummy-padding-file";
+ if(!cmSystemTools::RemoveFile(dummy_padding.str()))
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error assigning custom icon to temporary disk image."
+ "Error removing dummy padding file."
<< std::endl);
- return 0;
+ had_error = true;
+ }
+
+ // Optionally set the custom icon flag for the image ...
+ if(!had_error && !cpack_package_icon.empty())
+ {
+ std::ostringstream setfile_command;
+ setfile_command << this->GetOption("CPACK_COMMAND_SETFILE");
+ setfile_command << " -a C";
+ setfile_command << " \"" << temp_mount.str() << "\"";
+
+ if(!this->RunCommand(setfile_command))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error assigning custom icon to temporary disk image."
+ << std::endl);
+
+ had_error = true;
+ }
+ }
+
+ // Optionally we can execute a custom apple script to generate
+ // the .DS_Store for the volume folder ...
+ if(!had_error && !cpack_dmg_ds_store_setup_script.empty())
+ {
+ std::ostringstream setup_script_command;
+ setup_script_command << "osascript"
+ << " \"" << cpack_dmg_ds_store_setup_script << "\""
+ << " \"" << cpack_dmg_volume_name << "\"";
+ std::string error;
+ if(!this->RunCommand(setup_script_command, &error))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error executing custom script on disk image." << std::endl
+ << error
+ << std::endl);
+
+ had_error = true;
+ }
}
std::ostringstream detach_command;
@@ -498,6 +581,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
return 0;
}
+
+ if(had_error)
+ {
+ return 0;
+ }
}
if(!cpack_license_file.empty() || !slaDirectory.empty())
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index 12db469..53d38c4 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -36,6 +36,7 @@ protected:
bool CopyFile(std::ostringstream& source, std::ostringstream& target);
+ bool CreateEmptyFile(std::ostringstream& target, size_t size);
bool RunCommand(std::ostringstream& command, std::string* output = 0);
std::string