Browse Source

Fix symlink handling and --dry-run on PATH updates

default_compile_flags
vector-of-bool 3 years ago
parent
commit
9e14e6a6b7
1 changed files with 44 additions and 38 deletions
  1. +44
    -38
      src/dds/cli/cmd/install_yourself.cpp

+ 44
- 38
src/dds/cli/cmd/install_yourself.cpp View File

} }


#if _WIN32 #if _WIN32
void fixup_path_env(const wil::unique_hkey& env_hkey, fs::path want_path) {
void fixup_path_env(const options& opts, const wil::unique_hkey& env_hkey, fs::path want_path) {
DWORD len = 0; DWORD len = 0;
// Get the length // Get the length
auto err = ::RegGetValueW(env_hkey.get(), auto err = ::RegGetValueW(env_hkey.get(),
dds_log(info, "PATH is up-to-date"); dds_log(info, "PATH is up-to-date");
return; return;
} }
if (opts.dry_run) {
dds_log(info, "The PATH environment variable would be modified.");
return;
}
// It's not there. Add it now. // It's not there. Add it now.
auto want_str = want_entry.string(); auto want_str = want_entry.string();
path_elems.insert(path_elems.begin(), want_str); path_elems.insert(path_elems.begin(), want_str);
} }
#endif #endif


void fixup_system_path(const options&) {
void fixup_system_path(const options& opts [[maybe_unused]]) {
#if !_WIN32 #if !_WIN32
// We install into /usr/local/bin, and every nix-like system we support already has that on the // We install into /usr/local/bin, and every nix-like system we support already has that on the
// global PATH // global PATH
"Failed to open user-local environment variables registry " "Failed to open user-local environment variables registry "
"entry"); "entry");
} }
fixup_path_env(env_hkey, "C:/bin");
fixup_path_env(opts, env_hkey, "C:/bin");
#endif #endif
} }


if (dds::contains(profile_content, "$HOME/.local/bin")) { if (dds::contains(profile_content, "$HOME/.local/bin")) {
// We'll assume that this is properly loading .local/bin for .profile // We'll assume that this is properly loading .local/bin for .profile
dds_log(info, "[.br.cyan[{}]] is okay"_styled, profile_file.string()); dds_log(info, "[.br.cyan[{}]] is okay"_styled, profile_file.string());
} else if (opts.dry_run) {
dds_log(info,
"Would update [.br.cyan[{}]] to have ~/.local/bin on $PATH"_styled,
profile_file.string());
} else { } else {
// Let's add it // Let's add it
profile_content profile_content
+= ("\n# This entry was added by 'dds install-yourself' for the user-local " += ("\n# This entry was added by 'dds install-yourself' for the user-local "
"binaries path\nPATH=$HOME/bin:$HOME/.local/bin:$PATH\n"); "binaries path\nPATH=$HOME/bin:$HOME/.local/bin:$PATH\n");
if (opts.dry_run) {
dds_log(info,
"Would update [.br.cyan[{}]] to have ~/.local/bin on $PATH"_styled,
profile_file.string());
} else {
dds_log(info,
"Updating [.br.cyan[{}]] with a user-local binaries PATH entry"_styled,
profile_file.string());
auto tmp_file = profile_file;
tmp_file += ".tmp";
auto bak_file = profile_file;
bak_file += ".bak";
// Move .profile back into place if we abore for any reason
neo_defer {
if (!fs::exists(profile_file)) {
safe_rename(bak_file, profile_file);
}
};
// Write the temporary version
dds::write_file(tmp_file, profile_content).value();
// Make a backup
safe_rename(profile_file, bak_file);
// Move the tmp over the final location
safe_rename(tmp_file, profile_file);
// Okay!
dds_log(info,
"[.br.green[{}]] was updated. Prior contents are safe in [.br.cyan[{}]]"_styled,
profile_file.string(),
bak_file.string());
dds_log(
info,
".bold.cyan[NOTE:] Running applications may need to be restarted to see this change"_styled);
}
dds_log(info,
"Updating [.br.cyan[{}]] with a user-local binaries PATH entry"_styled,
profile_file.string());
auto tmp_file = profile_file;
tmp_file += ".tmp";
auto bak_file = profile_file;
bak_file += ".bak";
// Move .profile back into place if we abore for any reason
neo_defer {
if (!fs::exists(profile_file)) {
safe_rename(bak_file, profile_file);
}
};
// Write the temporary version
dds::write_file(tmp_file, profile_content).value();
// Make a backup
safe_rename(profile_file, bak_file);
// Move the tmp over the final location
safe_rename(tmp_file, profile_file);
// Okay!
dds_log(info,
"[.br.green[{}]] was updated. Prior contents are safe in [.br.cyan[{}]]"_styled,
profile_file.string(),
bak_file.string());
dds_log(
info,
".bold.cyan[NOTE:] Running applications may need to be restarted to see this change"_styled);
} }


auto fish_config = dds::user_config_dir() / "fish/config.fish"; auto fish_config = dds::user_config_dir() / "fish/config.fish";
dds_log(info, dds_log(info,
"Fish configuration in [.br.cyan[{}]] is okay"_styled, "Fish configuration in [.br.cyan[{}]] is okay"_styled,
fish_config.string()); fish_config.string());
} else if (opts.dry_run) {
dds_log(info,
"Would update [.br.cyan[{}]] to have ~/.local/bin on $PATH"_styled,
fish_config.string());
} else { } else {
dds_log( dds_log(
info, info,
"Failed to open user-local environment variables registry " "Failed to open user-local environment variables registry "
"entry"); "entry");
} }
fixup_path_env(env_hkey, "%LocalAppData%/bin");
fixup_path_env(opts, env_hkey, "%LocalAppData%/bin");
#endif #endif
} }


dest_path += ".exe"; dest_path += ".exe";
} }


if (fs::weakly_canonical(dest_path) == fs::canonical(self_exe)) {
if (fs::absolute(dest_path).lexically_normal() == fs::canonical(self_exe)) {
dds_log(error, dds_log(error,
"We cannot install over our own executable (.br.red[{}])"_styled, "We cannot install over our own executable (.br.red[{}])"_styled,
self_exe.string()); self_exe.string());

Loading…
Cancel
Save