git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCHv2 2/8] gitweb: Option for filling only specified info in fill_project_list_info

From
Jakub Narebski <jnareb@gmail.com>
Date
Feb 22, 2012, 22:05 UTC
Message-ID
<201202222305.14387.jnareb@gmail.com>
In-Reply-To
<7vfwe6ng8u.fsf@alter.siamese.dyndns.org>
On Mon, 20 Feb 2012, Junio C Hamano wrote:
Show 5 quoted lines
> Jakub Narebski <jnareb@gmail.com> writes:
> 
> > Introduce project_info_needs_filling($pr, $key[, \%fill_only]), which
> 
> That's "project_info_needs_filling($pr, @key[, \%fill_only])", isn't it?

Yes it is. I'm sorry, I have missed that this needs fixing from the first version of patch series. Since then I have noticed that in few cases we fill two fields at once, so we have to ask about two fields at once as well.

Show 22 quoted lines
> > +# entry for given @keys needs filling if at least one of interesting keys
> > +# in list is not present in %$project_info; key is interesting if $fill_only
> > +# is not passed, or is empty (all keys are interesting in both of those cases),
> > +# or if key is in $fill_only hash
> > +#
> > +# USAGE:
> > +# * project_info_needs_filling($project_info, 'key', ...)
> > +# * project_info_needs_filling($project_info, 'key', ..., \%fill_only)
> > +#   where %fill_only = map { $_ => 1 } @fill_only;
> 
> The reason this spells bad to me is that it gives the readers (and anybody
> who may want to touch gitweb code) that the caller has _two_ ways to say
> the same thing.
> 
> If a caller is interested in finding out $key in $project_info, it can
> either (1) pass $key as one of the earlier parameters to the function and
> not pass any \%fill_only, or (2) pass $key and pass \%fill_only but after
> making sure \%fill_only also has $key defined.
> 
> And if the caller passes \%fill_only, it has to remember that it needs to
> add $key to it; otherwise the earlier request "I want $key" is ignored by
> the function.

Yes, you are right. All of this is caused by fill_project_list_info() trying to do *two* things, instead of doing one thing and doing it well, as is Unix philosophy. It tried to check both that key is needed and that key is wanted.

> Why is it a good thing to have such a convoluted API?
Thanks for a sanity check.
Show 6 quoted lines
> Is it that "fill_project_list_info" is called by multiple callers, and
> they do not necessarily need to see all the fields that can be filled by
> the function (namely, age, age_string, descr, descr_long, owner, ctags and
> category)?  If that is the case, I must say that the approach to put the
> set filtering logic inside project_info_needs_filling function smells like
> a bad API design.
You are right.
Show 13 quoted lines
> In other words, wouldn't a callchain that uses a more natural set of API
> functions be like this?
> 
> 	# the top-level caller that is interested only in these two fields
> 	fill_project_list_info($projlist, 'age', 'owner');
> 
> 	# in fill_project_list_info()
> 	my $projlist = shift;
> 	my %wanted = map { $_ => 1 } @_;
> 
> 	foreach my $pr (@$projlist) {
> 		if (project_info_needs_filling($pr,
> 			filter_set(\%wanted, 'age', 'age_string'))) {
That or
 		if (project_info_needs_filling($pr,  'age', 'age_string') &&
 		    project_info_is_wanted(\%wanted, 'age', 'age_string')) {
and in your case there is no duplication of field names.

filter_set() is simply intersection of two sets, but it treats empty %wanted as a full set.

Show 10 quoted lines
> 			... get @activity ...
>                         ($pr->{'age'}, $pr->{'age_string'}) = @activity;
> 		}
> 		...
> 	}
> 
> That way, "needs_filling" has to do one and only one thing well: it checks
> if any of the fields it was asked is missing and answers.  And a generic
> set filtering helper that takes a filtering hashref and an array can be
> used later outside of the "needs_filling" function.
Right.
Show 19 quoted lines
> >  sub project_info_needs_filling {
> > +	my $fill_only = ref($_[-1]) ? pop : undef;
> >  	my ($project_info, @keys) = @_;
> >  
> >  	# return List::MoreUtils::any { !exists $project_info->{$_} } @keys;
> >  	foreach my $key (@keys) {
> > -		if (!exists $project_info->{$key}) {
> > +		if ((!$fill_only || !%$fill_only || $fill_only->{$key}) &&
> > +		    !exists $project_info->{$key}) {
> >  			return 1;
> >  		}
> >  	}
> >  	return;
> >  }
> >  
> > -
> 
> Shouldn't the previous patch updated not to add this blank line in the
> first place?
O.K.
> >  # fills project list info (age, description, owner, category, forks)
> 
> Is this enumeration up-to-date?  If we cannot keep it up-to-date, it may
> make sense to show only a few as examples and add ellipses.
O.K.
Show 16 quoted lines
> >  # for each project in the list, removing invalid projects from
> > -# returned list
> > +# returned list, or fill only specified info (removing invalid projects
> > +# only when filling 'age').
> 
> It is unclear what the added clause wants to say; especially, the link
> between the mention of 'age' and 'only when' is unclear.  Is asking of
> 'age' what makes a request a notable exception to remove invalid projects?
> Or is asking to partially fill fields what triggers the removal of invalid
> projects, and you mentioned 'age' as an example?
> 
> If it is the former (I am guessing it is), it would be much clearer to
> say:
> 
>     Invalid projects are removed from the returned list if and only if you
>     ask 'age' to be filled, because of such and such reasons.
 
O.K.
Sidenote: the reason is that to check that project is valid you really
have to run git command that requires repository in it[1].  Only when
filling 'age' and 'age_string' using git_get_last_activity() we always
run git command.
[1] Gitweb actually uses --git-dir=<PATH> parameter to git wrapper.
-- 
Jakub Narebski
Poland
Previous: Junio C HamanoNext: Jakub Narebski
Message 5 of 16 in “[PATCHv2 0/8] gitweb: Faster and improved project search”
  1. Jakub NarebskiFeb 15, 2012
  2. 1/8 gitweb: Refactor checking if part of project info need fillingJakub Narebski, Feb 15, 2012
  3. 2/8 gitweb: Option for filling only specified info in fill_project_list_infoJakub Narebski, Feb 15, 2012
  4. Junio C HamanoFeb 20, 2012
  5. Jakub NarebskiFeb 22, 2012
  6. 3/8 gitweb: Faster project searchJakub Narebski, Feb 15, 2012
  7. Junio C HamanoFeb 20, 2012
  8. 4/8 gitweb: Introduce esc_html_hl_regionsJakub Narebski, Feb 15, 2012
  9. 5/8 gitweb: Highlight matched part of project name when searching projectsJakub Narebski, Feb 15, 2012
  10. 6/8 gitweb: Highlight matched part of project description when searching projectsJakub Narebski, Feb 15, 2012
  11. 7/8 gitweb: Highlight matched part of shortened project descriptionJakub Narebski, Feb 15, 2012
  12. 8/8 gitweb: Use esc_html_match_hl() in 'grep' searchJakub Narebski, Feb 15, 2012
  13. Junio C HamanoFeb 16, 2012
  14. Jakub NarebskiFeb 16, 2012
  15. Junio C HamanoFeb 20, 2012
  16. Jakub NarebskiFeb 22, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.