Add support for installing uncompressed files during update installation.

* In addition to creating symlinks and installing files from .zip packages, support
   copying uncompressed files from the root of the package directory to the installation
   path.

   This is required for installing new versions of the updater itself which is downloaded
   uncompressed to the package installation directory.

 * Replace use of File.absolute_path with File.expand_path for compatibility with Ruby 1.8.7

 * Modify updater test to test installation of the updater binary to the install directory.
This commit is contained in:
Robert Knight 2011-09-13 17:24:48 +01:00
parent 724e91b216
commit 7bc98f75a6
6 changed files with 72 additions and 10 deletions

View file

@ -419,6 +419,39 @@ bool FileUtils::isRelative(const char* path)
#endif #endif
} }
void FileUtils::copyFile(const char* src, const char* dest) throw (IOException)
{
#ifdef PLATFORM_UNIX
std::ifstream inputFile(src,std::ios::binary);
std::ofstream outputFile(dest,std::ios::binary | std::ios::trunc);
if (!inputFile.good())
{
throw IOException("Failed to read file " + std::string(src));
}
if (!outputFile.good())
{
throw IOException("Failed to write file " + std::string(dest));
}
outputFile << inputFile.rdbuf();
if (inputFile.bad())
{
throw IOException("Error reading file " + std::string(src));
}
if (outputFile.bad())
{
throw IOException("Error writing file " + std::string(dest));
}
#else
if (!CopyFile(src,dest,FALSE))
{
throw IOException("Failed to copy " + std::string(src) + " to " + std::string(dest));
}
#endif
}
std::string FileUtils::makeAbsolute(const char* path, const char* basePath) std::string FileUtils::makeAbsolute(const char* path, const char* basePath)
{ {
if (isRelative(path)) if (isRelative(path))

View file

@ -55,6 +55,7 @@ class FileUtils
static void rmdir(const char* dir) throw (IOException); static void rmdir(const char* dir) throw (IOException);
static void createSymLink(const char* link, const char* target) throw (IOException); static void createSymLink(const char* link, const char* target) throw (IOException);
static void touch(const char* path) throw (IOException); static void touch(const char* path) throw (IOException);
static void copyFile(const char* src, const char* dest) throw (IOException);
/** Create all the directories in @p path which do not yet exist. /** Create all the directories in @p path which do not yet exist.
* @p path may be relative or absolute. * @p path may be relative or absolute.

View file

@ -224,6 +224,8 @@ void UpdateInstaller::installFile(const UpdateScriptFile& file)
if (target.empty()) if (target.empty())
{ {
// locate the package containing the file // locate the package containing the file
if (!file.package.empty())
{
std::string packageFile = m_packageDir + '/' + file.package + ".zip"; std::string packageFile = m_packageDir + '/' + file.package + ".zip";
if (!FileUtils::fileExists(packageFile.c_str())) if (!FileUtils::fileExists(packageFile.c_str()))
{ {
@ -233,6 +235,18 @@ void UpdateInstaller::installFile(const UpdateScriptFile& file)
// extract the file from the package and copy it to // extract the file from the package and copy it to
// the destination // the destination
FileUtils::extractFromZip(packageFile.c_str(),file.path.c_str(),destPath.c_str()); FileUtils::extractFromZip(packageFile.c_str(),file.path.c_str(),destPath.c_str());
}
else
{
// if no package is specified, look for an uncompressed file in the
// root of the package directory
std::string sourceFile = m_packageDir + '/' + FileUtils::fileName(file.path.c_str());
if (!FileUtils::fileExists(sourceFile.c_str()))
{
throw "Source file does not exist: " + sourceFile;
}
FileUtils::copyFile(sourceFile.c_str(),destPath.c_str());
}
// set the permissions on the newly extracted file // set the permissions on the newly extracted file
FileUtils::chmod(destPath.c_str(),file.permissions); FileUtils::chmod(destPath.c_str(),file.permissions);

View file

@ -24,6 +24,12 @@
<package>app-pkg</package> <package>app-pkg</package>
<is-main-binary>true</is-main-binary> <is-main-binary>true</is-main-binary>
</file> </file>
<file>
<name>$UPDATER_FILENAME</name>
<hash>$UPDATER_HASH</hash>
<size>$UPDATER_SIZE</size>
<permissions>0755</permissions>
</file>
<!-- Test symlink !--> <!-- Test symlink !-->
<file> <file>
<name>test-dir/app-symlink</name> <name>test-dir/app-symlink</name>

View file

@ -24,7 +24,8 @@ else
end end
file_list_vars = { file_list_vars = {
"APP_FILENAME" => APP_NAME "APP_FILENAME" => APP_NAME,
"UPDATER_FILENAME" => UPDATER_NAME
} }
def replace_vars(src_file,dest_file,vars) def replace_vars(src_file,dest_file,vars)
@ -89,7 +90,7 @@ FileUtils.cp("../#{UPDATER_NAME}","#{PACKAGE_DIR}/#{UPDATER_NAME}")
# make sure that it looks in the correct directory for # make sure that it looks in the correct directory for
# the file_list.xml file and packages # the file_list.xml file and packages
# #
install_path = File.absolute_path(INSTALL_DIR) install_path = File.expand_path(INSTALL_DIR)
Dir.chdir(INSTALL_DIR) do Dir.chdir(INSTALL_DIR) do
cmd = "#{PACKAGE_DIR}/#{UPDATER_NAME} --install-dir \"#{install_path}\" --package-dir \"#{PACKAGE_DIR}\" --script file_list.xml" cmd = "#{PACKAGE_DIR}/#{UPDATER_NAME} --install-dir \"#{install_path}\" --package-dir \"#{PACKAGE_DIR}\" --script file_list.xml"
puts "Running '#{cmd}'" puts "Running '#{cmd}'"
@ -101,7 +102,7 @@ sleep(1)
# Check that the app was updated # Check that the app was updated
app_path = "#{INSTALL_DIR}/#{APP_NAME}" app_path = "#{INSTALL_DIR}/#{APP_NAME}"
output = `#{app_path}` output = `"#{app_path}"`
if (output.strip != "new app starting") if (output.strip != "new app starting")
throw "Updated app produced unexpected output: #{output}" throw "Updated app produced unexpected output: #{output}"
end end

View file

@ -40,6 +40,13 @@
<package>app-pkg</package> <package>app-pkg</package>
<is-main-binary>true</is-main-binary> <is-main-binary>true</is-main-binary>
</file> </file>
<file>
<name>$UPDATER_FILENAME</name>
<hash>$UPDATER_HASH</hash>
<size>$UPDATER_SIZE</size>
<permissions>0755</permissions>
</file>
<!-- Test symlink !--> <!-- Test symlink !-->
<file> <file>
<name>test-dir/app-symlink</name> <name>test-dir/app-symlink</name>