Skip to content

Add use_author() #833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Apr 21, 2023
Merged

Add use_author() #833

merged 27 commits into from
Apr 21, 2023

Conversation

avalcarcel9
Copy link
Contributor

I talked with @jennybc at useR! about adding functionality to easily add or adapt authors in the Authors@R field in the description. Essentially the same functionality and use as use_package(). I think expert users add their information to the .Rprofile but more novice developers still add manually and often miss the field in use_description(). This could be useful for adding an author after package development as well.

I've never contributed to a tidyverse package so I'm not sure of your conventions. I tried to look up a few similar functions in the package and mimic those styles. I am happy to adapt the function or documentation to match your conventions, in the event of bugs, or to add functionality. Additionally, I did not provide tests for the new function. If you'd like to incorporate the use_author() function/feature I'm again happy to add tests or more documentation.

Possible TODOs:
TODO allow generic authors input like desc_set_authors(authors, file = ".", normalize = FALSE) for multiple author input
TODO create addin to prompt for author information
TODO create a snippet with author information for DESCRIPTION
TODO add tests
TODO check if the author input has partial overlap with one already listed and ask user if they would like to add the person as a new author or replace the existing author

@avalcarcel9
Copy link
Contributor Author

avalcarcel9 commented Jul 11, 2019

Bug in line 89 (sorry). role must be a string in the desc::desc_add_author function. I can fix and re-pull if you're interested in incorporating.

Copy link
Member

@jennybc jennybc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Looking good. I've given some comments to move things along. You can keep committing to your add_use_author branch, push that into your fork and this PR will automatically update.

R/authors.R Outdated
# Adapted from use_dependency code and tools provided in the desc package
# TODO allow generic authors input like desc_set_authors(authors, file = ".", normalize = FALSE) for multiple author input
# TODO create addin to prompt for author information
# TODO create a snippet with author information for DESCRIPTION
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are interesting ideas, but let's set them aside at this time.

Copy link
Contributor Author

@avalcarcel9 avalcarcel9 Aug 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've adjusted these TODOs to 'long term' to keep them as ideas but allow us to move forward now. I've added a few more ideas/TODOs in this version that may still be relevant in the near future.

R/authors.R Outdated
# TODO allow generic authors input like desc_set_authors(authors, file = ".", normalize = FALSE) for multiple author input
# TODO create addin to prompt for author information
# TODO create a snippet with author information for DESCRIPTION
# TODO add tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely yes!

Copy link
Contributor Author

@avalcarcel9 avalcarcel9 Aug 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added tests! I have one test I'd like to add to check that a message is returned from the use_author() function when the usethis default author (First, Last...) is in the description. I used ui_yeah() to prompt the message. It seems this is interactive and so expect_message() didn't work. Is there a way to add a test in that case?

R/authors.R Outdated
# TODO create addin to prompt for author information
# TODO create a snippet with author information for DESCRIPTION
# TODO add tests

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be some checks for obviously bad input here. The internal helper is_string() will be useful to you.

Copy link
Contributor Author

@avalcarcel9 avalcarcel9 Aug 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't manually check inputs since the inputs for my function are all passed to desc package functions. They do seems to have checks on inputs when someone is input incorrectly as a vector or numeric for example. I'm happy to add these checks if you prefer they be done within the usethis function directly.

R/authors.R Outdated
author = utils::person(given = given, family = given, role = role, email = email, comment = comment)

# Obtain the current DESCRIPTION fields
current_desc_fields <- desc::desc_fields()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you can't just load up the DESCRIPTION file, grab the current authors (possibly none, but that's going to be very very rare), and just call desc::desc_add_author()? What I'm really saying is: does there need to be so much conditional logic?

In general, I'm comfortable assuming that we start with our own output, i.e. that we (usethis) created the DESCRIPTION file. Or that it's not pathological in some way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to incorporate this flow into this version of the function and get rid of the conditional logic. I still have some if() to assess what the state of the current description is in order to add an author or error the function.

I now error if the DESCRIPTION has 'Author:' rather than 'Authors@R' and send the user a message. I allow for addition of an author so long as 'Authors@R@' is a field (blank or pre-filled). I do not make changes if the author being input with use_author() is already in the DESCRIPTION. I ask the user if they would like to delete the usethis default author (First, Last, ...) if it is found in the DESCRIPTION.

I'd like to eventually change the error from finding 'Author' to prompting the user if they want to replace it with 'Authors@R' and continue adding and also prompt the user to add 'Authors@R' if it is missing and Authors was not found. Not sure if I'm over-thinking this though. I tried to stick with your advice and start by assuming the user used usethis or at least the generic DESCRIPTION generated when using File > New Directory > R Package...

@avalcarcel9
Copy link
Contributor Author

Thanks so much @jennybc ! I'll take a look at all of this and start working on incorporating the changes this week.

@avalcarcel9
Copy link
Contributor Author

@jennybc This version seems to be working fine. I made sure to fetch and merge updates between my old branch and the current devel usethis on gh. Some checks on travis are failing for the R devel version but they seem to be unrelated to this content. I tried to rigorously test out the function manually myself by assessing different test cases and prompting errors. I eventually made as many of these real tests so hopefully most major bugs are out but a grad student only has so much time in the day.

Looking forward to your feedback and I hope its ready to merge!

@GitHunter0
Copy link

Hey @avalcarcel9 , it is a helpful feature, any update here?

@avalcarcel9
Copy link
Contributor Author

@GitHunter0 no updates! I was waiting to hear back about next steps to get this incorporated into the package.

@GitHunter0
Copy link

It is a pity, @avalcarcel9 , so let's wait for @jennybc

@jennybc
Copy link
Member

jennybc commented Nov 2, 2020

I took a look recently and decided it needs work before it can be merged. For starters, copy editing of the docs and code restyling. And, much more vaguely, editing to be more consistent with existing code base.

@avalcarcel9
Copy link
Contributor Author

@jennybc is there anything I can do to help with the edits and todos or does the remaining work need to be done with someone on your team? As a sort of independent contributor I'm not sure what you mean exactly by these comments and would need some more specific TODOs to help out. But I'm still more than happy to help in any way I can!

@jennybc
Copy link
Member

jennybc commented Nov 2, 2020

The contributing guide for this repo contains good information, such as re: code style:

https://github.com/r-lib/usethis/blob/master/.github/CONTRIBUTING.md

You could also read the documentation carefully and copy edit it. I think there are some missing words / typos in places.

@jennybc
Copy link
Member

jennybc commented Nov 2, 2020

Also the tests use a helper that has since been renamed to create_local_package().

You generally need to merge in current main development from master of the main repo.

All of this is stuff I can do, but this is why finishing the PR isn't a quick and easy process.

@avalcarcel9
Copy link
Contributor Author

avalcarcel9 commented Nov 5, 2020

@jennybc I completely understand the process takes a long time to rigorously validate and check. I started this process while in grad school and have since moved onto a new job during this crazy time. I'd still love the opportunity to help and as time permits would love to help out with these last tasks to get the code and functionality ready to integrate. That being said, I'm not sure when that time will pop up with my new responsibilities during this crazy time. So if you get to this and I haven't contributed feel free to finish it off. If not, hopefully at some point (soon-ish) I can go through the documentation for contributing, make the changes, and re-push changes. So sorry I can't help more immediately.

@jennybc jennybc requested a review from ateucher April 21, 2023 01:54
@jennybc
Copy link
Member

jennybc commented Apr 21, 2023

I refactored this a lot since various things have changed considerably since this story arc first started!

Comment on lines +6 to +7
#' file, creating that field if necessary. It will not modify, e.g., the role(s)
#' or email of an existing author (judged using their "Given Family" name). For
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to address the 80% use case and keep things fairly simple. For more fiddly changes, I think folks should just edit DESCRIPTION or use desc themselves.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's a good decision.

})
if (any(m)) {
aut_name <- glue("{given %||% ''} {family %||% ''}")
usethis_abort(c(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usethis's UI needs an overhaul (pivoting towards cli), which I'm not necessarily biting off right now. But when we touch errors, we're phasing in usethis_abort().

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the overhaul, will the ui_oops(), ui_info() etc. be part of that? I.e., usethis_abort() is just the start?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it will be everything. Some of those function will certainly live on, but their guts will be modified to use cli.

Copy link
Collaborator

@ateucher ateucher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it looks great! I agree with the the 80% use case otherwise it would get overly complex. I had just a couple of suggestions/questions. Thanks for the explanations of conventions and development direction.

#' )
#' }
#'
use_author <- function(given = NULL, family = NULL, ..., role = "ctb") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we should expose the email argument explicitly? I think the others are fine behind ... but I would think email will be used the vast majority of the time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it and did take a look at author info for some existing CRAN packages. It feels pretty common to only include email for cre and I'm not sure there's a real purpose for including email for other contributors? Anyhow, that's how I ended up here.

So I guess I'm assuming that use_author() is going to be used mostly for adding folks in a non-cre role, i.e. that the maintainer is probably already set up. And that it's fine to omit email in this case.

This did inspire me to add #' @inheritDotParams utils::person, which leads to much better documentation of ..., so that is a big improvement.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That all makes sense to me!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worked on the examples a bit, so use of email and role is demonstrated, but I think most calls will be more like the last one: use_author("Charlie", "Brown").

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I like that

#' cre] (YOUR-ORCID-ID)` and `use_author()` offers to remove it in interactive
#' sessions.
#'
#' @inheritParams utils::person
Copy link
Collaborator

@ateucher ateucher Apr 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#' @inheritParams utils::person
#' @inheritParams utils::person
#' @param ... Arguments passed on to [utils::person()]

I think we need this since utils::person() doesn't have a ... argument, so it shows up in the use_authors.Rd file as "currently not used".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I handled this above before I got to this point in the review.

Comment on lines +6 to +7
#' file, creating that field if necessary. It will not modify, e.g., the role(s)
#' or email of an existing author (judged using their "Given Family" name). For
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's a good decision.

#' `use_author()` also surfaces two other situations you might want to address:

#' * Explicit use of the fields `Author` or `Maintainer`. We recommend switching
#' to the more modern `Authors@R` field instead, because it offers richer
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% convinced it's a net win to have lots of links from actual packages into the book, especially links to specific sections. It feels kind of brittle/perishable. So my current posture is that there has to be a really reason to do this. I did go back and read that passage and intentionally paraphrased it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that makes sense

})
if (any(m)) {
aut_name <- glue("{given %||% ''} {family %||% ''}")
usethis_abort(c(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the overhaul, will the ui_oops(), ui_info() etc. be part of that? I.e., usethis_abort() is just the start?

authors <- d$get_authors()
authors_given <- purrr::map(authors, "given")
authors_family <- purrr::map(authors, "family")
m <- purrr::map2_lgl(authors_given, authors_family, function(x, y) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think checking the email would also be good? It's a pretty unique identifier. I can see cases like "Andy Teucher" vs "Andrew Teucher" or "Jenny Bryan" vs "Jennifer Bryan" slipping through...

Could be (using pmap()):

identical(x, given) && identical(y, family) || identical(z, email)

But maybe that's overkill

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I convinced myself that this level of matching was overkill.

R/author.R Outdated
Comment on lines 117 to 120
withr::with_options(
list(usethis.description = NULL),
defaults <- use_description_defaults()
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an option to pull this out into a function that returns that list, and consult it for the default Authors@R?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Done.

R/author.R Outdated
{ui_field('Authors@R')} appears to include a placeholder author:
{format(default_author, style = 'text')}")
if (any(m) && is_interactive() && ui_yeah("Would you like to remove it?")) {
# TODO: Do I want to suppress this output?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the output is fine, I think it's nice to see confirmation that it's doing something

@jennybc jennybc changed the title Add use author Add use_author() Apr 21, 2023
@jennybc jennybc merged commit 98f1853 into r-lib:main Apr 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants