diff options
author | Robert Maynard <robert.maynard@kitware.com> | 2014-09-26 18:38:38 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2015-11-13 13:44:15 (GMT) |
commit | 167a465565cda9bb33d2e919509c23a761ea45e9 (patch) | |
tree | 8206168801645e40f39675c9e611b66bf2e56b42 /Source/CPack | |
parent | 9c1dfbfd600819a751d4c5058fd939650ee6d6b4 (diff) | |
download | CMake-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.cxx | 110 | ||||
-rw-r--r-- | Source/CPack/cmCPackDragNDropGenerator.h | 1 |
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 |