From e8f7b5385dbc30604c0f8fdcece100a0bf7a1705 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Fri, 2 Jul 2021 13:16:55 -0700 Subject: [PATCH] CLIUtil.pm: try harder in get_project As CLIUtil provides services for command line clients, allow a path to be passed in to get_project instead of just a project name. However, only activate the "try harder" code if an optional second argument is passed that has a "true" value. Provide a new convenience/self-documenting function `get_project_harder` that calls get_project with its first arg and passes true for the second. This way the "allow a path" logic remains opt-in only to avoid any unexpected nasty surprises. Signed-off-by: Kyle J. McKay --- Girocco/CLIUtil.pm | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/Girocco/CLIUtil.pm b/Girocco/CLIUtil.pm index b972928..cf84cf2 100644 --- a/Girocco/CLIUtil.pm +++ b/Girocco/CLIUtil.pm @@ -42,7 +42,7 @@ BEGIN { yes_to_continue yes_to_continue_or_die get_all_users get_user get_all_projects get_project get_full_users nice_me setup_pager setup_pager_stdout - pager_in_use + pager_in_use get_project_harder ); @EXPORT_OK = qw( _parse_options _prompt_rl _prompt_rl_or_die @@ -53,6 +53,7 @@ BEGIN { use File::Basename; use File::Spec; +use Cwd qw(getcwd); use POSIX qw(:fcntl_h); use Girocco::Config; use Girocco::Util; @@ -565,13 +566,43 @@ sub get_all_projects { @project_list; } -# Result of Girocco::Project->load or fatal die if that fails +# Result of Girocco::Project->load or fatal die if that fails, but +# if the optional second argument is true and the initial +# Girocco::Project->does_exist fails and the first argument names an +# existing path, an attempt is made to translate that path into a Girocco +# project name and if successful a Girocco::Project->load will be done on that. # Returns undef if passed undef or "" sub get_project { - my $projname = shift; - $projname =~ s/\.git$//i if defined($projname); - defined($projname) && $projname ne "" or return undef; - Girocco::Project::does_exist($projname, 1) or die "No such project: \"$projname\"\n"; + my ($projnameorpath, $tryharder) = @_; + (my $projname = $projnameorpath) =~ s/\.git$//i if defined($projnameorpath); + defined($projnameorpath) && defined($projname) or return undef; + $projname ne "" && Girocco::Project::does_exist($projname, 1) or do {{ + $projname = undef; + last unless $tryharder; + # attempt to translate a path into a project + my $pn = undef; + $pn = get_project_from_dir($projnameorpath) if $projnameorpath ne ""; + defined($pn) && $pn eq "" and $pn = undef; + if (!defined($pn) && $projnameorpath ne "" && -d $projnameorpath) { + # see if Git can tell us a --git-dir for the directory + my $gd = undef; + my $oldcd = getcwd(); + $oldcd = $1 if defined($oldcd) && $oldcd =~ m{^(/.+)$}; + if (chdir($projnameorpath)) { + $gd = get_git("rev-parse", "--git-dir"); + chdir($oldcd); + defined($gd) and chomp($gd); + } + # could be ugly relative thing + defined($gd) && $gd ne "" && substr($gd,0,1) ne "/" and + $gd = "$projnameorpath/$gd"; + # try it again if we got something (could be a "gitdir" file) + defined($gd) && $gd ne "" && -e $gd and + $pn = get_project_from_dir($gd); + } + defined($pn) && $pn ne "" and $projname = $pn; + }}; + defined($projname) && $projname ne "" or die "No such project: \"$projnameorpath\"\n"; my $project; eval { $project = Girocco::Project->load($projname); @@ -580,6 +611,13 @@ sub get_project { $project; } +# convenience/self-documenting function that calls get_project +# with its first argument and passes true for the second +sub get_project_harder { + my $projnameorpath = shift; + return get_project($projnameorpath, 1); +} + # return true if $enc_passwd is a match for $plain_passwd sub check_passwd_match { my ($enc_passwd, $plain_passwd) = @_; -- 2.11.4.GIT