forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Zucchini] Add command line processing framework with stubs.
This CL adds main_utils.*, which has the framework to dispatch Zucchini commands and print help messages. This is used by the Zucchini main program, and is not part of Zucchini library. - Add ::Command: A struct containing command name (e.g., "-gen", "-apply"), help message, and a base::Callback containing code for the main command. This allows Zucchini command dispatch without bulky bulky class hierarchy and superfluous instantialization. - Add ::CommandRegistry: A class to manage ::Command instances and dispatch commands, or print help messages. - Add ::ResourceUsageTracker: A class instantiated in main() to track resource usage for valid command invocations, and and print them at end. Specifically: - Zucchini.PeakPagefileUsage (KiB) - Zucchini.PeakWorkingSetSize (KiB) - Zucchini.TotalTime (s) Also add "-quiet" switch to disable this. - Add stubs for Zucchini-gen and Zucchini-apply, to be populated later. - Starting to use LOG(INFO) to display output. This requires updating PRESUBMIT.py to add Zucchini as an exception. Bug: 729154 Change-Id: Id5263435100dc73b2d8917ca2bcd04245ed41934 Reviewed-on: https://chromium-review.googlesource.com/567492 Commit-Queue: Samuel Huang <huangs@chromium.org> Reviewed-by: Dirk Pranke <dpranke@chromium.org> Cr-Commit-Position: refs/heads/master@{#486762}
- Loading branch information
1 parent
a308bcc
commit a13b5a0
Showing
5 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// Copyright 2017 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. | ||
|
||
#include "chrome/installer/zucchini/main_utils.h" | ||
|
||
#include <iostream> | ||
|
||
#include "base/bind.h" | ||
#include "base/command_line.h" | ||
#include "base/logging.h" | ||
#include "base/process/process_metrics.h" | ||
#include "build/build_config.h" | ||
#include "chrome/installer/zucchini/io_utils.h" | ||
|
||
namespace { | ||
|
||
// Translates |command_line| arguments to a vector of base::FilePath and returns | ||
// the result via |fnames|. Expects exactly |expected_count|. | ||
bool CheckAndGetFilePathParams(const base::CommandLine& command_line, | ||
size_t expected_count, | ||
std::vector<base::FilePath>* fnames) { | ||
const base::CommandLine::StringVector& args = command_line.GetArgs(); | ||
if (args.size() != expected_count) | ||
return false; | ||
|
||
fnames->clear(); | ||
for (size_t i = 0; i < args.size(); ++i) | ||
fnames->push_back(base::FilePath(args[i])); | ||
return true; | ||
} | ||
|
||
} // namespace | ||
|
||
/******** ResourceUsageTracker ********/ | ||
|
||
ResourceUsageTracker::ResourceUsageTracker() : start_time_(base::Time::Now()) {} | ||
|
||
ResourceUsageTracker::~ResourceUsageTracker() { | ||
base::Time end_time = base::Time::Now(); | ||
|
||
#if !defined(OS_MACOSX) | ||
std::unique_ptr<base::ProcessMetrics> process_metrics( | ||
base::ProcessMetrics::CreateProcessMetrics( | ||
base::GetCurrentProcessHandle())); | ||
|
||
LOG(INFO) << "Zucchini.PeakPagefileUsage " | ||
<< process_metrics->GetPeakPagefileUsage() / 1024 << " KiB"; | ||
LOG(INFO) << "Zucchini.PeakWorkingSetSize " | ||
<< process_metrics->GetPeakWorkingSetSize() / 1024 << " KiB"; | ||
#endif // !defined(OS_MACOSX) | ||
|
||
LOG(INFO) << "Zucchini.TotalTime " << (end_time - start_time_).InSecondsF() | ||
<< " s"; | ||
} | ||
|
||
/******** Command ********/ | ||
|
||
Command::Command(const char* name_in, | ||
const char* usage_in, | ||
int num_args_in, | ||
Command::Fun fun_in) | ||
: name(name_in), usage(usage_in), num_args(num_args_in), fun(fun_in) {} | ||
|
||
Command::Command(const Command&) = default; | ||
|
||
Command::~Command() = default; | ||
|
||
/******** CommandRegistry ********/ | ||
|
||
CommandRegistry::CommandRegistry() = default; | ||
|
||
CommandRegistry::~CommandRegistry() = default; | ||
|
||
void CommandRegistry::Register(const Command* command) { | ||
commands_.push_back(command); | ||
} | ||
|
||
void CommandRegistry::RunOrExit(const base::CommandLine& command_line) { | ||
const Command* command_use = nullptr; | ||
for (const Command* command : commands_) { | ||
if (command_line.HasSwitch(command->name)) { | ||
if (command_use) { // Too many commands found. | ||
command_use = nullptr; // Set to null to flag error. | ||
break; | ||
} | ||
command_use = command; | ||
} | ||
} | ||
|
||
// If we don't have exactly one matching command, print error and exit. | ||
if (!command_use) { | ||
std::cerr << "Must have exactly one of:\n ["; | ||
zucchini::PrefixSep sep(", "); | ||
for (const Command* command : commands_) | ||
std::cerr << sep << "-" << command->name; | ||
std::cerr << "]" << std::endl; | ||
PrintUsageAndExit(); | ||
} | ||
|
||
std::vector<base::FilePath> fnames; | ||
if (CheckAndGetFilePathParams(command_line, command_use->num_args, &fnames)) { | ||
command_use->fun.Run(command_line, fnames); | ||
} else { | ||
std::cerr << command_use->usage << std::endl; | ||
PrintUsageAndExit(); | ||
} | ||
} | ||
|
||
void CommandRegistry::PrintUsageAndExit() { | ||
std::cerr << "Usage:" << std::endl; | ||
for (const Command* command : commands_) | ||
std::cerr << " zucchini " << command->usage << std::endl; | ||
exit(1); | ||
} | ||
|
||
/******** Command Definitions ********/ | ||
|
||
Command kCommandGen = { | ||
"gen", "-gen <old_file> <new_file> <patch_file>", 3, | ||
base::Bind([](const base::CommandLine& command_line, | ||
const std::vector<base::FilePath>& fnames) -> void { | ||
// TODO(etiennep): Implement. | ||
})}; | ||
|
||
Command kCommandApply = { | ||
"apply", "-apply <old_file> <patch_file> <new_file>", 3, | ||
base::Bind([](const base::CommandLine& command_line, | ||
const std::vector<base::FilePath>& fnames) -> void { | ||
// TODO(etiennep): Implement. | ||
})}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Copyright 2017 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. | ||
|
||
#ifndef CHROME_INSTALLER_ZUCCHINI_MAIN_UTILS_H_ | ||
#define CHROME_INSTALLER_ZUCCHINI_MAIN_UTILS_H_ | ||
|
||
#include <memory> | ||
#include <vector> | ||
|
||
#include "base/callback.h" | ||
#include "base/macros.h" | ||
#include "base/time/time.h" | ||
|
||
namespace base { | ||
|
||
class CommandLine; | ||
class FilePath; | ||
|
||
} // namespace base | ||
|
||
// Class to track and print system resource usage. Should be instantiated early | ||
// in program flow to better track start time. | ||
class ResourceUsageTracker { | ||
public: | ||
ResourceUsageTracker(); | ||
~ResourceUsageTracker(); | ||
|
||
private: | ||
base::Time start_time_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(ResourceUsageTracker); | ||
}; | ||
|
||
// Specs for a Zucchini command. | ||
struct Command { | ||
using Fun = base::Callback<void(const base::CommandLine&, | ||
const std::vector<base::FilePath>&)>; | ||
|
||
Command(const char* name_in, | ||
const char* usage_in, | ||
int num_args_in, | ||
Fun fun_in); | ||
explicit Command(const Command&); | ||
~Command(); | ||
|
||
// Unique name of command. |-name| is used to select from command line. | ||
const char* name; | ||
|
||
// Usage help text of command. | ||
const char* usage; | ||
|
||
// Number of arguments (assumed to be filenames) used by the command. | ||
const int num_args; | ||
|
||
// Main code for the command. | ||
Fun fun; | ||
}; | ||
|
||
// Registry of Commands to select the command to run and to handle errors. | ||
class CommandRegistry { | ||
public: | ||
CommandRegistry(); | ||
~CommandRegistry(); | ||
|
||
void Register(const Command* command); | ||
|
||
// Uses |command_line| to find a Command instance. If a unique command is | ||
// found, then runs it. Otherwise prints error and exits. | ||
void RunOrExit(const base::CommandLine& command_line); | ||
|
||
private: | ||
void PrintUsageAndExit(); | ||
|
||
std::vector<const Command*> commands_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(CommandRegistry); | ||
}; | ||
|
||
// Command: Patch generation. | ||
extern Command kCommandGen; | ||
|
||
// Command: Patch application. | ||
extern Command kCommandApply; | ||
|
||
#endif // CHROME_INSTALLER_ZUCCHINI_MAIN_UTILS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters