Skip to content

Commit e6b6e01

Browse files
committed
feat(install): exclude workspaces and add --bin option
1 parent 82b1c12 commit e6b6e01

3 files changed

Lines changed: 49 additions & 16 deletions

File tree

include/cppship/cmd/install.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ namespace cppship::cmd {
66

77
struct InstallOptions {
88
Profile profile = Profile::debug;
9+
std::optional<std::string> binary;
910
};
1011

1112
int run_install(const InstallOptions& options);
1213

13-
}
14+
}

lib/cmd/install.cpp

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,73 @@
11
#include "cppship/cmd/install.h"
22

33
#include <cstdlib>
4+
#include <functional>
45

56
#include <gsl/narrow>
7+
#include <range/v3/range/conversion.hpp>
8+
#include <range/v3/view/transform.hpp>
69
#include <spdlog/spdlog.h>
710

811
#include "cppship/cmd/build.h"
12+
#include "cppship/core/layout.h"
913
#include "cppship/core/manifest.h"
14+
#include "cppship/exception.h"
1015
#include "cppship/util/fs.h"
1116
#include "cppship/util/log.h"
1217

1318
using namespace cppship;
1419

20+
namespace {
21+
22+
int do_install(const cmd::BuildContext& ctx, std::span<std::string> binaries, std::string_view prefix)
23+
{
24+
for (const auto& bin : binaries) {
25+
const auto bin_file = ctx.profile_dir / bin;
26+
if (!fs::exists(bin_file)) {
27+
warn("binary {} not found", bin_file.string());
28+
continue;
29+
}
30+
31+
const auto dst = fmt::format("{}/bin/{}", prefix, bin);
32+
status("install", "{} to {}", bin_file.string(), dst);
33+
fs::copy_file(bin_file, dst, fs::copy_options::overwrite_existing);
34+
}
35+
36+
return EXIT_SUCCESS;
37+
}
38+
39+
}
40+
1541
int cmd::run_install([[maybe_unused]] const InstallOptions& options)
1642
{
1743
// TODO(someone): fix me
1844
#ifdef _WINNDOWS
1945
throw Error { "install is not supported in Windows" };
2046
#else
21-
const int result = run_build({ .profile = options.profile });
22-
if (result != 0) {
23-
return EXIT_FAILURE;
47+
BuildContext ctx(options.profile);
48+
if (ctx.manifest.is_workspace()) {
49+
throw Error { "install for workspace is not supported" };
2450
}
2551

26-
BuildContext ctx(options.profile);
27-
Manifest manifest(ctx.metafile);
28-
if (manifest.is_workspace()) {
29-
throw Error { "install for workspace is not supported now" };
52+
const auto& layout = ctx.workspace.as_package();
53+
if (options.binary && !layout.binary(*options.binary).has_value()) {
54+
throw InvalidCmdOption { "--bin", fmt::format("specified binary {} is not found", *options.binary) };
3055
}
3156

32-
const auto bin_file = ctx.profile_dir / manifest.get_if_package()->name();
33-
if (!fs::exists(bin_file)) {
34-
warn("no binary to install");
35-
return EXIT_SUCCESS;
57+
const int result = run_build({ .profile = options.profile, .cmake_target = options.binary });
58+
if (result != 0) {
59+
return EXIT_FAILURE;
3660
}
3761

38-
const auto dst = fmt::format("/usr/local/bin/{}", manifest.get_if_package()->name());
39-
status("install", "{} to {}", bin_file.string(), dst);
40-
fs::copy_file(bin_file, dst, fs::copy_options::overwrite_existing);
41-
return EXIT_SUCCESS;
62+
std::vector<std::string> binaries = std::invoke([&] {
63+
if (options.binary) {
64+
return std::vector<std::string> { *options.binary };
65+
}
66+
67+
const auto tmp = layout.binaries();
68+
return tmp | ranges::views::transform(&Target::name) | ranges::to<std::vector>();
69+
});
70+
71+
return do_install(ctx, binaries, "/usr/local");
4272
#endif
4373
}

src/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ std::list<SubCommand> build_commands(const ArgumentParser& common)
165165
auto& install = commands.emplace_back("install", common, [](const ArgumentParser& cmd) {
166166
return cmd::run_install({
167167
.profile = parse_profile(cmd.get("--profile")),
168+
.binary = cmd.present("bin"),
168169
});
169170
});
170171

@@ -173,6 +174,7 @@ std::list<SubCommand> build_commands(const ArgumentParser& common)
173174
.help("build with specific profile")
174175
.metavar("profile")
175176
.default_value(std::string { kProfileRelease });
177+
install.parser.add_argument("--bin").metavar("name").help("install only the specified binary");
176178

177179
// run
178180
auto& run = commands.emplace_back("run", common, [](const ArgumentParser& cmd) {

0 commit comments

Comments
 (0)