Don't modify shell profile files if they are symlinks (#767)

* Don't modify shell profile files if they are symlinks

* Fixup remote building step
This commit is contained in:
Ana Hobden 2023-12-05 11:14:46 -08:00 committed by GitHub
parent 0419422de0
commit b84ebf0841
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 50 deletions

View file

@ -44,25 +44,29 @@ impl ConfigureShellProfile {
for profile_target in locations.bash.iter().chain(locations.zsh.iter()) { for profile_target in locations.bash.iter().chain(locations.zsh.iter()) {
let profile_target_path = Path::new(profile_target); let profile_target_path = Path::new(profile_target);
if let Some(parent) = profile_target_path.parent() { if let Some(parent) = profile_target_path.parent() {
if !parent.exists() { // Some tools (eg `nix-darwin`) create symlinks to these files, don't write to them if that's the case.
create_directories.push( if !profile_target_path.is_symlink() {
CreateDirectory::plan(parent, None, None, 0o0755, false) if !parent.exists() {
.await create_directories.push(
.map_err(Self::error)?, CreateDirectory::plan(parent, None, None, 0o0755, false)
.await
.map_err(Self::error)?,
);
}
create_or_insert_files.push(
CreateOrInsertIntoFile::plan(
profile_target_path,
None,
None,
0o644,
shell_buf.to_string(),
create_or_insert_into_file::Position::Beginning,
)
.await
.map_err(Self::error)?,
); );
} }
create_or_insert_files.push(
CreateOrInsertIntoFile::plan(
profile_target_path,
None,
None,
0o644,
shell_buf.to_string(),
create_or_insert_into_file::Position::Beginning,
)
.await
.map_err(Self::error)?,
);
} }
} }
@ -88,23 +92,27 @@ impl ConfigureShellProfile {
let mut profile_target = fish_prefix_path; let mut profile_target = fish_prefix_path;
profile_target.push(locations.fish.confd_suffix.clone()); profile_target.push(locations.fish.confd_suffix.clone());
if let Some(conf_d) = profile_target.parent() { // Some tools (eg `nix-darwin`) create symlinks to these files, don't write to them if that's the case.
create_directories.push( if !profile_target.is_symlink() {
CreateDirectory::plan(conf_d.to_path_buf(), None, None, 0o755, false).await?, if let Some(conf_d) = profile_target.parent() {
create_directories.push(
CreateDirectory::plan(conf_d.to_path_buf(), None, None, 0o755, false)
.await?,
);
}
create_or_insert_files.push(
CreateOrInsertIntoFile::plan(
profile_target,
None,
None,
0o644,
fish_buf.to_string(),
create_or_insert_into_file::Position::Beginning,
)
.await?,
); );
} }
create_or_insert_files.push(
CreateOrInsertIntoFile::plan(
profile_target,
None,
None,
0o644,
fish_buf.to_string(),
create_or_insert_into_file::Position::Beginning,
)
.await?,
);
} }
for fish_prefix in &locations.fish.vendor_confd_prefixes { for fish_prefix in &locations.fish.vendor_confd_prefixes {
let fish_prefix_path = PathBuf::from(fish_prefix); let fish_prefix_path = PathBuf::from(fish_prefix);

View file

@ -12,7 +12,7 @@ This enables remote building, which requires `ssh host nix` to work.
*/ */
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
pub struct ConfigureRemoteBuilding { pub struct ConfigureRemoteBuilding {
create_or_insert_into_file: StatefulAction<CreateOrInsertIntoFile>, create_or_insert_into_file: Option<StatefulAction<CreateOrInsertIntoFile>>,
} }
impl ConfigureRemoteBuilding { impl ConfigureRemoteBuilding {
@ -29,16 +29,24 @@ fi
"# "#
); );
let create_or_insert_into_file = CreateOrInsertIntoFile::plan( let zshenv = Path::new("/etc/zshenv");
Path::new("/etc/zshenv"),
None, let create_or_insert_into_file = if !zshenv.is_symlink() {
None, Some(
0o644, CreateOrInsertIntoFile::plan(
shell_buf.to_string(), zshenv,
create_or_insert_into_file::Position::Beginning, None,
) None,
.await 0o644,
.map_err(Self::error)?; shell_buf.to_string(),
create_or_insert_into_file::Position::Beginning,
)
.await
.map_err(Self::error)?,
)
} else {
None
};
Ok(Self { Ok(Self {
create_or_insert_into_file, create_or_insert_into_file,
@ -63,7 +71,11 @@ impl Action for ConfigureRemoteBuilding {
fn execute_description(&self) -> Vec<ActionDescription> { fn execute_description(&self) -> Vec<ActionDescription> {
vec![ActionDescription::new( vec![ActionDescription::new(
self.tracing_synopsis(), if self.create_or_insert_into_file.is_none() {
"Skipping configuring zsh to support using Nix in non-interactive shells, `/etc/zshenv` is a symlink".to_string()
} else {
self.tracing_synopsis()
},
vec!["Update `/etc/zshenv` to import Nix".to_string()], vec!["Update `/etc/zshenv` to import Nix".to_string()],
)] )]
} }
@ -71,11 +83,13 @@ impl Action for ConfigureRemoteBuilding {
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
async fn execute(&mut self) -> Result<(), ActionError> { async fn execute(&mut self) -> Result<(), ActionError> {
let span = tracing::Span::current().clone(); let span = tracing::Span::current().clone();
self.create_or_insert_into_file if let Some(create_or_insert_into_file) = &mut self.create_or_insert_into_file {
.try_execute() create_or_insert_into_file
.instrument(span) .try_execute()
.await .instrument(span)
.map_err(Self::error)?; .await
.map_err(Self::error)?;
}
Ok(()) Ok(())
} }
@ -89,7 +103,9 @@ impl Action for ConfigureRemoteBuilding {
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
async fn revert(&mut self) -> Result<(), ActionError> { async fn revert(&mut self) -> Result<(), ActionError> {
self.create_or_insert_into_file.try_revert().await?; if let Some(create_or_insert_into_file) = &mut self.create_or_insert_into_file {
create_or_insert_into_file.try_revert().await?
};
Ok(()) Ok(())
} }