// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This file provides a command-line interface to // upgrade_test::GenerateAlternateVersion(). #include #include #include #include "base/at_exit.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" #include "base/macros.h" #include "base/path_service.h" #include "chrome/installer/test/alternate_version_generator.h" namespace { const wchar_t kDefaultMiniInstallerFile[] = L"mini_installer.exe"; const wchar_t kDefaultOutPath[] = L"mini_installer_new.exe"; namespace switches { const char kForce[] = "force"; const char kHelp[] = "help"; const char kMiniInstaller[] = "mini_installer"; const char kOut[] = "out"; const char kPrevious[] = "previous"; } // namespace switches namespace errors { enum ErrorCode { SHOW_HELP, MINI_INSTALLER_NOT_FOUND, OUT_FILE_EXISTS, GENERATION_FAILED }; const wchar_t* const Messages[] = { NULL, L"original mini_installer.exe not found", L"output file already exists", L"failed to generate a newly versioned mini_installer.exe" }; const wchar_t* GetErrorMessage(ErrorCode error_code) { DCHECK_LE(0, error_code); DCHECK_GT(arraysize(Messages), static_cast(error_code)); return Messages[error_code]; } } // namespace errors // Display usage information to stderr along with an optional error message with // details. void DumpUsage(const base::CommandLine& cmd_line, errors::ErrorCode error_code, const std::wstring& detail) { const wchar_t* error_message = errors::GetErrorMessage(error_code); if (error_message != NULL) { fwprintf(stderr, L"%s: %s", cmd_line.GetProgram().value().c_str(), errors::GetErrorMessage(error_code)); if (!detail.empty()) fwprintf(stderr, L" (%s)\n", detail.c_str()); else fwprintf(stderr, L"\n"); } fwprintf(stderr, L"Usage: %s [ OPTIONS ]\n" L" Where OPTIONS is one or more of:\n" L" --help Display this help message.\n" L" --force Overwrite any existing output files.\n" L" --mini_installer=SRC_PATH Path to mini_installer.exe. Default value is\n" L" \"mini_installer.exe\" in the same directory as\n" L" this program.\n" L" --out=OUT_PATH Path to output file. Default value is\n" L" \"mini_installer_new.exe\" in the current\n" L" directory.\n" L" --previous OUT_PATH will have a lower version than\n" L" SRC_PATH. By default, OUT_PATH will have a\n" L" higher version.\n" L" --7za_path=7ZA_PATH Path to the directory holding 7za.exe. Defaults\n" L" to ..\\..\\third_party\\lzma_sdk\\Executable\n" L" relative to this program's location.\n", cmd_line.GetProgram().value().c_str()); } // Gets the path to the source mini_installer.exe on which to operate, putting // the result in |mini_installer|. Returns true on success. bool GetMiniInstallerPath(const base::CommandLine& cmd_line, base::FilePath* mini_installer) { DCHECK(mini_installer); base::FilePath result = cmd_line.GetSwitchValuePath(switches::kMiniInstaller); if (result.empty() && PathService::Get(base::DIR_EXE, &result)) result = result.Append(kDefaultMiniInstallerFile); if (result.empty()) return false; *mini_installer = result; return true; } // Gets the path to the output file, putting the result in |out|. void GetOutPath(const base::CommandLine& cmd_line, base::FilePath* out) { DCHECK(out); base::FilePath result = cmd_line.GetSwitchValuePath(switches::kOut); if (result.empty()) *out = base::FilePath(kDefaultOutPath); else *out = result; } // Returns the direction in which the version should be adjusted. upgrade_test::Direction GetDirection(const base::CommandLine& cmd_line) { return cmd_line.HasSwitch(switches::kPrevious) ? upgrade_test::PREVIOUS_VERSION : upgrade_test::NEXT_VERSION; } } // namespace // The main program. int wmain(int argc, wchar_t *argv[]) { base::AtExitManager exit_manager; base::CommandLine::Init(0, NULL); base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); if (cmd_line->HasSwitch(switches::kHelp)) { DumpUsage(*cmd_line, errors::SHOW_HELP, std::wstring()); return EXIT_SUCCESS; } base::FilePath mini_installer; if (!GetMiniInstallerPath(*cmd_line, &mini_installer)) { DumpUsage(*cmd_line, errors::MINI_INSTALLER_NOT_FOUND, std::wstring()); return EXIT_FAILURE; } if (!base::PathExists(mini_installer)) { DumpUsage(*cmd_line, errors::MINI_INSTALLER_NOT_FOUND, mini_installer.value()); return EXIT_FAILURE; } base::FilePath out; GetOutPath(*cmd_line, &out); if (!cmd_line->HasSwitch(switches::kForce) && base::PathExists(out)) { DumpUsage(*cmd_line, errors::OUT_FILE_EXISTS, out.value()); return EXIT_FAILURE; } upgrade_test::Direction direction = GetDirection(*cmd_line); std::wstring original_version; std::wstring new_version; if (upgrade_test::GenerateAlternateVersion(mini_installer, out, direction, &original_version, &new_version)) { fwprintf(stdout, L"Generated version %s from version %s\n", new_version.c_str(), original_version.c_str()); return EXIT_SUCCESS; } DumpUsage(*cmd_line, errors::GENERATION_FAILED, mini_installer.value()); return EXIT_FAILURE; }