Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/uu/chgrp/locales/en-US.ftl
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
chgrp-about = Change the group of each FILE to GROUP.
chgrp-usage = chgrp [OPTION]... GROUP FILE...
chgrp [OPTION]... --reference=RFILE FILE...

# Help messages
chgrp-help-print-help = Print help information.
chgrp-help-changes = like verbose but report only when a change is made
chgrp-help-quiet = suppress most error messages
chgrp-help-verbose = output a diagnostic for every file processed
chgrp-help-preserve-root = fail to operate recursively on '/'
chgrp-help-no-preserve-root = do not treat '/' specially (the default)
chgrp-help-reference = use RFILE's group rather than specifying GROUP values
chgrp-help-from = change the group only if its current group matches GROUP
chgrp-help-recursive = operate on files and directories recursively

# Error messages
chgrp-error-invalid-group-id = invalid group id: '{ $gid_str }'
chgrp-error-invalid-group = invalid group: '{ $group }'
chgrp-error-failed-to-get-attributes = failed to get attributes of { $file }
chgrp-error-invalid-user = invalid user: '{ $from_group }'
20 changes: 20 additions & 0 deletions src/uu/chgrp/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
chgrp-about = Changer le groupe de chaque FICHIER vers GROUPE.
chgrp-usage = chgrp [OPTION]... GROUPE FICHIER...
chgrp [OPTION]... --reference=RFICHIER FICHIER...

# Messages d'aide
chgrp-help-print-help = Afficher les informations d'aide.
chgrp-help-changes = comme verbeux mais rapporter seulement lors d'un changement
chgrp-help-quiet = supprimer la plupart des messages d'erreur
chgrp-help-verbose = afficher un diagnostic pour chaque fichier traité
chgrp-help-preserve-root = échouer à opérer récursivement sur '/'
chgrp-help-no-preserve-root = ne pas traiter '/' spécialement (par défaut)
chgrp-help-reference = utiliser le groupe de RFICHIER plutôt que spécifier les valeurs de GROUPE
chgrp-help-from = changer le groupe seulement si son groupe actuel correspond à GROUPE
chgrp-help-recursive = opérer sur les fichiers et répertoires récursivement

# Messages d'erreur
chgrp-error-invalid-group-id = identifiant de groupe invalide : '{ $gid_str }'
chgrp-error-invalid-group = groupe invalide : '{ $group }'
chgrp-error-failed-to-get-attributes = échec de l'obtention des attributs de { $file }
chgrp-error-invalid-user = utilisateur invalide : '{ $from_group }'
51 changes: 33 additions & 18 deletions src/uu/chgrp/src/chgrp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,33 @@
use uucore::perms::{GidUidOwnerFilter, IfFrom, chown_base, options};

use clap::{Arg, ArgAction, ArgMatches, Command};
use std::collections::HashMap;

use std::fs;
use std::os::unix::fs::MetadataExt;

use uucore::locale::get_message;
use uucore::locale::{get_message, get_message_with_args};

fn parse_gid_from_str(group: &str) -> Result<u32, String> {
if let Some(gid_str) = group.strip_prefix(':') {
// Handle :gid format
gid_str
.parse::<u32>()
.map_err(|_| format!("invalid group id: '{gid_str}'"))
gid_str.parse::<u32>().map_err(|_| {
get_message_with_args(
"chgrp-error-invalid-group-id",
HashMap::from([("gid_str".to_string(), gid_str.to_string())]),

Check warning on line 28 in src/uu/chgrp/src/chgrp.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/chgrp/src/chgrp.rs#L26-L28

Added lines #L26 - L28 were not covered by tests
)
})

Check warning on line 30 in src/uu/chgrp/src/chgrp.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/chgrp/src/chgrp.rs#L30

Added line #L30 was not covered by tests
} else {
// Try as group name first
match entries::grp2gid(group) {
Ok(g) => Ok(g),
// If group name lookup fails, try parsing as raw number
Err(_) => group
.parse::<u32>()
.map_err(|_| format!("invalid group: '{group}'")),
Err(_) => group.parse::<u32>().map_err(|_| {
get_message_with_args(
"chgrp-error-invalid-group",
HashMap::from([("group".to_string(), group.to_string())]),
)
}),
}
}
}
Expand All @@ -45,7 +52,12 @@
raw_group = entries::gid2grp(gid).unwrap_or_else(|_| gid.to_string());
Some(gid)
})
.map_err_context(|| format!("failed to get attributes of {}", file.quote()))?
.map_err_context(|| {
get_message_with_args(
"chgrp-error-failed-to-get-attributes",
HashMap::from([("file".to_string(), file.quote().to_string())]),

Check warning on line 58 in src/uu/chgrp/src/chgrp.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/chgrp/src/chgrp.rs#L56-L58

Added lines #L56 - L58 were not covered by tests
)
})?

Check warning on line 60 in src/uu/chgrp/src/chgrp.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/chgrp/src/chgrp.rs#L60

Added line #L60 was not covered by tests
} else {
let group = matches
.get_one::<String>(options::ARG_GROUP)
Expand Down Expand Up @@ -74,7 +86,10 @@
Err(_) => {
return Err(USimpleError::new(
1,
format!("invalid user: '{from_group}'"),
get_message_with_args(
"chgrp-error-invalid-user",
HashMap::from([("from_group".to_string(), from_group.to_string())]),
),
));
}
}
Expand Down Expand Up @@ -105,14 +120,14 @@
.arg(
Arg::new(options::HELP)
.long(options::HELP)
.help("Print help information.")
.help(get_message("chgrp-help-print-help"))
.action(ArgAction::Help),
)
.arg(
Arg::new(options::verbosity::CHANGES)
.short('c')
.long(options::verbosity::CHANGES)
.help("like verbose but report only when a change is made")
.help(get_message("chgrp-help-changes"))
.action(ArgAction::SetTrue),
)
.arg(
Expand All @@ -124,46 +139,46 @@
.arg(
Arg::new(options::verbosity::QUIET)
.long(options::verbosity::QUIET)
.help("suppress most error messages")
.help(get_message("chgrp-help-quiet"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::verbosity::VERBOSE)
.short('v')
.long(options::verbosity::VERBOSE)
.help("output a diagnostic for every file processed")
.help(get_message("chgrp-help-verbose"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::preserve_root::PRESERVE)
.long(options::preserve_root::PRESERVE)
.help("fail to operate recursively on '/'")
.help(get_message("chgrp-help-preserve-root"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::preserve_root::NO_PRESERVE)
.long(options::preserve_root::NO_PRESERVE)
.help("do not treat '/' specially (the default)")
.help(get_message("chgrp-help-no-preserve-root"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::REFERENCE)
.long(options::REFERENCE)
.value_name("RFILE")
.value_hint(clap::ValueHint::FilePath)
.help("use RFILE's group rather than specifying GROUP values"),
.help(get_message("chgrp-help-reference")),
)
.arg(
Arg::new(options::FROM)
.long(options::FROM)
.value_name("GROUP")
.help("change the group only if its current group matches GROUP"),
.help(get_message("chgrp-help-from")),
)
.arg(
Arg::new(options::RECURSIVE)
.short('R')
.long(options::RECURSIVE)
.help("operate on files and directories recursively")
.help(get_message("chgrp-help-recursive"))
.action(ArgAction::SetTrue),
)
// Add common arguments with chgrp, chown & chmod
Expand Down
Loading