fix(relinker): align console progress columns
This commit is contained in:
parent
a534bd67ca
commit
04899cb0f7
|
|
@ -6,6 +6,8 @@
|
|||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
namespace Cli {
|
||||
|
||||
|
|
@ -13,6 +15,12 @@ class ConsoleProgress final : public Domain::IProgress {
|
|||
public:
|
||||
explicit ConsoleProgress(std::ostream& stream) : stream(stream) {}
|
||||
|
||||
void IncludeFile(std::string_view path) {
|
||||
const auto separator = path.find_last_of("/\\");
|
||||
const auto name = path.substr(separator == std::string_view::npos ? 0 : separator + 1);
|
||||
nameWidth = std::max(nameWidth, textWidth(name));
|
||||
}
|
||||
|
||||
void Report(const Domain::ProgressEvent& event) override {
|
||||
if (event.Completed > event.Total) throw std::logic_error("Invalid progress counters");
|
||||
const char* label = nullptr;
|
||||
|
|
@ -51,9 +59,9 @@ public:
|
|||
if (!changed && !complete && now - lastUpdate < std::chrono::milliseconds(80)) return;
|
||||
if (changed || messages) Finish();
|
||||
std::ostringstream line;
|
||||
line << label;
|
||||
if (!name.empty()) line << " | " << name;
|
||||
line << " | " << percent << '%';
|
||||
line << std::left << std::setw(22) << label;
|
||||
line << " | " << name << std::string(nameWidth > textWidth(name) ? nameWidth - textWidth(name) : 0, ' ');
|
||||
line << " | " << std::right << std::setw(3) << percent << '%';
|
||||
if (event.Stage == Domain::ProgressStage::Modules) line << " (" << event.Completed << '/' << event.Total << ')';
|
||||
const auto text = line.str();
|
||||
stream << '\r' << text;
|
||||
|
|
@ -84,6 +92,11 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
static std::size_t textWidth(std::string_view text) {
|
||||
return static_cast<std::size_t>(std::count_if(text.begin(), text.end(), [](unsigned char character) { return (character & 0xc0) != 0x80; }));
|
||||
}
|
||||
|
||||
std::size_t nameWidth = 0;
|
||||
std::ostream& stream;
|
||||
Domain::ProgressStage lastStage = Domain::ProgressStage::Write;
|
||||
std::string lastInput;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ struct ConvertedExecutable {
|
|||
std::string Diagnostics;
|
||||
};
|
||||
|
||||
ConvertedExecutable Convert(const Cli::Args& args, const std::string& inputPath, const std::string& absPath, const bool mainExecutable, Domain::IProgress& progress) {
|
||||
ConvertedExecutable Convert(const Cli::Args& args, const std::string& inputPath, const std::string& absPath, const bool mainExecutable, Cli::ConsoleProgress& progress) {
|
||||
Io::FileReader fileReader;
|
||||
Relinker::ConversionInput input;
|
||||
input.Executable = fileReader.Read(inputPath);
|
||||
|
|
@ -59,6 +59,9 @@ ConvertedExecutable Convert(const Cli::Args& args, const std::string& inputPath,
|
|||
options.WindowsGui = args.windowsGui;
|
||||
options.WindowsDiagnostics = args.windowsDiagnostics && mainExecutable;
|
||||
options.ExcludedModules = args.excludedSceModules;
|
||||
progress.IncludeFile(Io::Utf8Path(input.InputPath));
|
||||
progress.IncludeFile(Io::Utf8Path(input.OutputPath));
|
||||
for (const auto& module : input.Modules) progress.IncludeFile(Io::Utf8Path(module.Path));
|
||||
auto converted = Relinker::Conversion(progress).Convert(std::move(input), options);
|
||||
return {inputPath, absPath, std::move(converted.Analysis), std::move(converted.Modules), std::move(converted.Executable), std::move(converted.WindowsDiagnostics)};
|
||||
}
|
||||
|
|
@ -121,6 +124,12 @@ int Run(const int argc, char* argv[]) {
|
|||
extraExecutables.push_back({executable, relative, input, output});
|
||||
}
|
||||
|
||||
progress.IncludeFile(args.inputPath);
|
||||
progress.IncludeFile(absPath);
|
||||
for (const auto& extra : extraExecutables) {
|
||||
progress.IncludeFile(Io::Utf8Path(extra.Input));
|
||||
progress.IncludeFile(Io::Utf8Path(extra.Output));
|
||||
}
|
||||
std::vector<ConvertedExecutable> executables;
|
||||
executables.push_back(Convert(args, args.inputPath, absPath, true, progress));
|
||||
for (const auto& [executable, relative, input, output] : extraExecutables) {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ def main():
|
|||
assert secondary.read_bytes().startswith(b"MZ" if windows else b"\x7fELF"), secondary
|
||||
assert "Executable: picker/picker.bin\n" in result.stdout, result.stdout
|
||||
assert f"Executable file: {secondary}\n" in result.stdout, result.stdout
|
||||
assert f"app{suffix}\npicker.picker.bin{suffix}\nlibs/\n" in result.stdout, result.stdout
|
||||
assert f" |-- app{suffix}\n |-- picker.picker.bin{suffix}\n |-- libs/\n" in result.stdout, result.stdout
|
||||
assert (output.parent / "picker.picker.bin.registry.json").is_file()
|
||||
assert sorted(path.name for path in output.parent.rglob("*.guest.prx")) == ["bundled.prx.guest.prx"]
|
||||
if not windows:
|
||||
|
|
|
|||
Loading…
Reference in New Issue