mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
release command
This commit is contained in:
+441
-74
File diff suppressed because it is too large
Load Diff
+56
-10
@@ -6,7 +6,6 @@ namespace mob
|
||||
class command
|
||||
{
|
||||
public:
|
||||
command();
|
||||
virtual ~command() = default;
|
||||
|
||||
struct common_options
|
||||
@@ -24,21 +23,35 @@ public:
|
||||
static common_options common;
|
||||
|
||||
static clipp::group common_options_group();
|
||||
virtual clipp::group group() = 0;
|
||||
|
||||
void force_exit_code(int code);
|
||||
void force_pick();
|
||||
|
||||
bool picked() const;
|
||||
bool wants_help() const;
|
||||
|
||||
clipp::group group();
|
||||
int run();
|
||||
|
||||
protected:
|
||||
bool picked_;
|
||||
enum flags
|
||||
{
|
||||
noflags = 0x00,
|
||||
requires_options = 0x01,
|
||||
};
|
||||
|
||||
bool picked_;
|
||||
bool help_;
|
||||
|
||||
command(flags f=noflags);
|
||||
|
||||
virtual clipp::group do_group() = 0;
|
||||
virtual void do_pre_run() {};
|
||||
virtual int do_run() = 0;
|
||||
virtual std::string do_doc() { return {}; }
|
||||
|
||||
private:
|
||||
flags flags_;
|
||||
std::optional<int> code_;
|
||||
};
|
||||
|
||||
@@ -46,9 +59,9 @@ private:
|
||||
class version_command : public command
|
||||
{
|
||||
public:
|
||||
clipp::group group() override;
|
||||
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
};
|
||||
|
||||
@@ -56,9 +69,9 @@ protected:
|
||||
class help_command : public command
|
||||
{
|
||||
public:
|
||||
clipp::group group() override;
|
||||
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
};
|
||||
|
||||
@@ -66,19 +79,22 @@ protected:
|
||||
class options_command : public command
|
||||
{
|
||||
public:
|
||||
clipp::group group() override;
|
||||
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
std::string do_doc() override;
|
||||
};
|
||||
|
||||
|
||||
class build_command : public command
|
||||
{
|
||||
public:
|
||||
clipp::group group() override;
|
||||
build_command();
|
||||
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
void do_pre_run() override;
|
||||
int do_run() override;
|
||||
|
||||
private:
|
||||
@@ -93,20 +109,50 @@ private:
|
||||
class list_command : public command
|
||||
{
|
||||
public:
|
||||
clipp::group group() override;
|
||||
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
std::string do_doc() override;
|
||||
};
|
||||
|
||||
|
||||
class devbuild_command : public command
|
||||
class release_command : public command
|
||||
{
|
||||
public:
|
||||
clipp::group group() override;
|
||||
release_command();
|
||||
|
||||
void make_bin();
|
||||
void make_pdbs();
|
||||
void make_src();
|
||||
|
||||
protected:
|
||||
clipp::group do_group() override;
|
||||
int do_run() override;
|
||||
std::string do_doc() override;
|
||||
|
||||
private:
|
||||
bool bin_ = true;
|
||||
bool src_ = true;
|
||||
bool pdbs_ = true;
|
||||
std::string utf8out_;
|
||||
fs::path out_;
|
||||
std::string version_;
|
||||
bool version_exe_ = false;
|
||||
bool version_rc_ = false;
|
||||
std::string utf8_rc_path_;
|
||||
fs::path rc_path_;
|
||||
bool force_;
|
||||
std::string suffix_;
|
||||
|
||||
fs::path make_filename(const std::string& what) const;
|
||||
|
||||
void walk_dir(
|
||||
const fs::path& dir, std::vector<fs::path>& files,
|
||||
const std::vector<std::regex>& ignore_re, std::size_t& total_size);
|
||||
|
||||
std::string version_from_exe() const;
|
||||
std::string version_from_rc() const;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
+6
-6
@@ -329,19 +329,19 @@ void set_option(const std::string& s)
|
||||
void dump_available_options()
|
||||
{
|
||||
for (auto&& [k, v] : g_options)
|
||||
u8cout << "options/" << k << "\n";
|
||||
u8cout << "options/" << k << " = " << v << "\n";
|
||||
|
||||
for (auto&& [k, v] : g_tools)
|
||||
u8cout << "tools/" << k << "\n";
|
||||
u8cout << "tools/" << k << " = " << v << "\n";
|
||||
|
||||
for (auto&& [k, v] : g_prebuilt)
|
||||
u8cout << "prebuilt/" << k << "\n";
|
||||
u8cout << "prebuilt/" << k << " = " << v << "\n";
|
||||
|
||||
for (auto&& [k, v] : g_versions)
|
||||
u8cout << "versions/" << k << "\n";
|
||||
u8cout << "versions/" << k << " = " << v << "\n";
|
||||
|
||||
for (auto&& [k, v] : g_paths)
|
||||
u8cout << "paths/" << k << "\n";
|
||||
u8cout << "paths/" << k << " = " << v << "\n";
|
||||
}
|
||||
|
||||
bool try_parts(fs::path& check, const std::vector<std::string>& parts)
|
||||
@@ -931,7 +931,7 @@ void init_options(const fs::path& ini, const std::vector<std::string>& opts)
|
||||
make_canonical_path("install", paths::prefix(), "install");
|
||||
make_canonical_path("install_bin", paths::install(), "bin");
|
||||
make_canonical_path("install_libs", paths::install(), "libs");
|
||||
make_canonical_path("install_pdbs", paths::install(), "pdbs");
|
||||
make_canonical_path("install_pdbs", paths::install(), "pdb");
|
||||
make_canonical_path("install_dlls", paths::install_bin(), "dlls");
|
||||
make_canonical_path("install_loot", paths::install_bin(), "loot");
|
||||
make_canonical_path("install_plugins", paths::install_bin(), "plugins");
|
||||
|
||||
+24
-3
@@ -22,7 +22,7 @@ std::shared_ptr<command> handle_command_line(const std::vector<std::string>& arg
|
||||
std::make_unique<options_command>(),
|
||||
build,
|
||||
std::make_unique<list_command>(),
|
||||
std::make_unique<devbuild_command>(),
|
||||
std::make_unique<release_command>(),
|
||||
};
|
||||
|
||||
|
||||
@@ -43,14 +43,36 @@ std::shared_ptr<command> handle_command_line(const std::vector<std::string>& arg
|
||||
|
||||
if (!pr)
|
||||
{
|
||||
pr = clipp::parse(args, command::common_options_group());
|
||||
// some commands have mandatory options, like devbuild, which requires
|
||||
// the build number
|
||||
//
|
||||
// doing `devbuild -h` therefore fails to parse because of the missing
|
||||
// build number
|
||||
//
|
||||
// but options are actually still set correctly, so -h can be checked
|
||||
// manually here
|
||||
for (auto&& c : commands)
|
||||
{
|
||||
if (c->picked() && c->wants_help())
|
||||
return std::move(c);
|
||||
}
|
||||
|
||||
// another way parsing can fail is if no commands are given, like just
|
||||
// running `mob` as-is; clipp doesn't really have a ways of setting
|
||||
// a default command to use, to the arguments can be reparsed with
|
||||
// only the common options
|
||||
cli = command::common_options_group();
|
||||
pr = clipp::parse(args, cli);
|
||||
|
||||
if (!pr)
|
||||
{
|
||||
// bad command line
|
||||
help->force_exit_code(1);
|
||||
return help;
|
||||
}
|
||||
|
||||
// if this parsing works, it means the user invoked `mob` without a
|
||||
// command; default to `build`
|
||||
build->force_pick();
|
||||
}
|
||||
|
||||
@@ -60,7 +82,6 @@ std::shared_ptr<command> handle_command_line(const std::vector<std::string>& arg
|
||||
if (c->picked())
|
||||
return std::move(c);
|
||||
}
|
||||
u8cout << "!!\n";
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
+80
@@ -3,6 +3,7 @@
|
||||
#include "utility.h"
|
||||
#include "conf.h"
|
||||
#include "context.h"
|
||||
#include "process.h"
|
||||
|
||||
namespace mob::op
|
||||
{
|
||||
@@ -473,6 +474,85 @@ void write_text_file(
|
||||
"finished writing {} bytes to {}", bytes.size(), p);
|
||||
}
|
||||
|
||||
void archive_from_glob(
|
||||
const context& cx,
|
||||
const fs::path& src_glob, const fs::path& dest_file,
|
||||
const std::vector<std::string>& ignore)
|
||||
{
|
||||
cx.trace(context::fs, "archiving {} into {}", src_glob, dest_file);
|
||||
|
||||
if (conf::dry())
|
||||
return;
|
||||
|
||||
op::create_directories(cx, dest_file.parent_path());
|
||||
|
||||
auto p = process()
|
||||
.binary(tools::sevenz::binary())
|
||||
.arg("a")
|
||||
.arg(dest_file)
|
||||
.arg("-r")
|
||||
.arg("-mx=5")
|
||||
.arg(src_glob);
|
||||
|
||||
for (auto&& i : ignore)
|
||||
p.arg("-xr!", i, process::nospace);
|
||||
|
||||
p.run();
|
||||
p.join();
|
||||
}
|
||||
|
||||
void archive_from_files(
|
||||
const context& cx,
|
||||
const std::vector<fs::path>& files, const fs::path& files_root,
|
||||
const fs::path& dest_file)
|
||||
{
|
||||
cx.trace(context::fs,
|
||||
"archiving {} files rooted in {} into {}",
|
||||
files.size(), files_root, dest_file);
|
||||
|
||||
if (conf::dry())
|
||||
return;
|
||||
|
||||
std::string list_file_text;
|
||||
std::error_code ec;
|
||||
|
||||
for (auto&& f : files)
|
||||
{
|
||||
fs::path rf = fs::relative(f, files_root, ec);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
cx.bail_out(context::fs,
|
||||
"file {} is not in root {}", f, files_root);
|
||||
}
|
||||
|
||||
list_file_text += path_to_utf8(rf) + "\n";
|
||||
}
|
||||
|
||||
const auto list_file = make_temp_file();
|
||||
guard g([&]
|
||||
{
|
||||
if (fs::exists(list_file))
|
||||
{
|
||||
std::error_code ec;
|
||||
fs::remove(list_file, ec);
|
||||
}
|
||||
});
|
||||
|
||||
op::write_text_file(gcx(), encodings::utf8, list_file, list_file_text);
|
||||
op::create_directories(cx, dest_file.parent_path());
|
||||
|
||||
auto p = process()
|
||||
.binary(tools::sevenz::binary())
|
||||
.arg("a")
|
||||
.arg(dest_file)
|
||||
.arg("@", list_file, process::nospace)
|
||||
.cwd(files_root);
|
||||
|
||||
p.run();
|
||||
p.join();
|
||||
}
|
||||
|
||||
|
||||
void do_touch(const context& cx, const fs::path& p)
|
||||
{
|
||||
|
||||
@@ -62,4 +62,14 @@ void write_text_file(
|
||||
const context& cx, encodings e, const fs::path& p, std::string_view utf8,
|
||||
flags f=noflags);
|
||||
|
||||
void archive_from_glob(
|
||||
const context& cx,
|
||||
const fs::path& src_glob, const fs::path& dest_file,
|
||||
const std::vector<std::string>& ignore);
|
||||
|
||||
void archive_from_files(
|
||||
const context& cx,
|
||||
const std::vector<fs::path>& files, const fs::path& files_root,
|
||||
const fs::path& dest_file);
|
||||
|
||||
} // namespace
|
||||
|
||||
+1
-2
@@ -261,6 +261,7 @@ public:
|
||||
static bool prebuilt();
|
||||
|
||||
static fs::path source_path();
|
||||
static fs::path super_path();
|
||||
|
||||
bool is_super() const override;
|
||||
|
||||
@@ -274,8 +275,6 @@ private:
|
||||
void initialize_super(const fs::path& super_root);
|
||||
|
||||
fs::path this_source_path() const;
|
||||
|
||||
static fs::path super_path();
|
||||
};
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>..\third-party\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>Ws2_32.lib;Crypt32.lib;Wldap32.lib;Shlwapi.lib;DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>Ws2_32.lib;Crypt32.lib;Wldap32.lib;Shlwapi.lib;DbgHelp.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
|
||||
Reference in New Issue
Block a user