Skip to content

Commit

Permalink
Support multiple authors
Browse files Browse the repository at this point in the history
Deprecate AuthorName and AuthorEmail in favour of Authors.
Authors is a comma-separated list of string.
There are no restriction on the format of each string, but
we hope that it will follow the NAME <EMAIL> format.
If that is the case, many places use regex to get the
NAME or EMAIL only and replace the old usage.

A side-effect is that emails are optional now.

Close #118, #356
  • Loading branch information
abelsiqueira committed Sep 5, 2024
1 parent ad5c21c commit c46df89
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 44 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning].

## [Unreleased]

Breaking notice:

- `AuthorName` and `AuthorEmail` have been deprecated. Expect them to be removed in the next version. They are replaced by a single question `Authors`, which receives a comma separated list. Additionally, the Code of Conduct used the `AuthorEmail`, and now it has its own question.

### Added

- The keyword argument `quiet` is now used to define verbosity (#379)
Expand All @@ -20,6 +24,7 @@ and this project adheres to [Semantic Versioning].
- New question: `AutoIncludeTests`, that auto-includes all `test-*.jl` files in `runtests.jl` (#261)
- New question: `CodeOfConductContact`, the contact person/entity for the `CODE_OF_CONDUCT.md` file (#426)
- New question: `LicenseCopyrightHolders`, the copyright holders listed in the LICENSE (#427)
- New question: `Authors`, a comma separated list of authors. (#118)

### Changed

Expand All @@ -28,6 +33,10 @@ and this project adheres to [Semantic Versioning].
- Default Indentation changed from 2 to 4 (#403)
- Change lychee configuration to a hidden file `.lychee.toml`

### Deprecated

- `AuthorName` and `AuthorEmail` have been removed.

## [0.9.1] - 2024-07-24

### Changed
Expand Down
2 changes: 1 addition & 1 deletion copier/community.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ CodeOfConductContact:
when: "{{ AddCodeOfConduct }}"
type: str
help: Contact person/entity listed in the CODE_OF_CONDUCT.md file (Will be listed as contact to enforce the code of conduct, if necessary)
default: "{{ AuthorEmail }}"
default: "{{ Authors.split(',')[0] | regex_replace('.*<(.*)>.*', '\\\\1') }}"

AddGitHubTemplates:
when: "{{ AnswerStrategy == 'ask' }}"
Expand Down
14 changes: 11 additions & 3 deletions copier/essential.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,23 @@ PackageOwner:
validator: "{% if PackageOwner | length == 0 %}Can't be empty{% endif %}"

AuthorName:
when: false
type: str
help: Name of the package author (Used to kickstart a few files)
help: (Deprecated in 0.10.0) Name of the package author (Used to kickstart a few files)
validator: "{% if AuthorName | length == 0 %}Can't be empty{% endif %}"

AuthorEmail:
when: false
type: str
help: E-mail of the package author (Used to kickstart a few files)
help: (Deprecated in 0.10.0) E-mail of the package author (Used to kickstart a few files)
validator: "{% if AuthorEmail | length == 0 %}Can't be empty{% endif %}"

Authors:
type: str
help: Package authors separated by commas (We recommend the form AUTHOR <EMAIL>, but this can be ignored)
placeholder: AUTHOR <EMAIL>,AUTHOR <EMAIL>
default: "{% if AuthorName | length > 0 %}{{ AuthorName }} <{{ AuthorEmail }}> and contributors{% endif %}"

JuliaMinVersion:
type: str
help: Minimum Julia version (Used in Project.toml and CI. The suggestion below is the LTS version)
Expand All @@ -48,7 +56,7 @@ License:
LicenseCopyrightHolders:
type: str
help: License Copyright Holders (Added in front of "Copyright (c) " notices, when applicable)
default: "{{ AuthorName }}"
default: "{{ Authors | regex_replace('\\s*([^,]*)\\s*<[^,]*>[^,]*', '\\\\1') | regex_replace('\\s*,\\s*', ', ') | trim }}"
validator: "{% if LicenseCopyrightHolders | length == 0%}Can't be empty{% endif %}"

Indentation:
Expand Down
4 changes: 2 additions & 2 deletions docs/src/10-full-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ This command will look around your project path and try to guess some of the ans
Currently, we guess:

- `PackageName` and `PackageUUID` from the `name` and `uuid` fields in `Project.toml`,
- `AuthorName` and `AuthorEmail` from the `authors` field in `Project.toml`,
- `Authors` from the `authors` field in `Project.toml`,
- `PackageOwner` from the `repo` in `docs/make.jl`,
- `JuliaMinVersion` from the `compat` section in `Project.toml`,
- `Indentation` from the `indent` field in `.JuliaFormatter.toml`.
Expand All @@ -137,7 +137,7 @@ Currently, we guess:
If you don't like the result, or want to override the answers, you can run the `apply` function with additional arguments, for instance:

```julia-repl
julia> data = Dict("AuthorName" => "Bob", "AuthorEmail" => "[email protected]")
julia> data = Dict("Authors" => "Bob <[email protected]>")
julia> BestieTemplate.apply("full/path/to/YourPackage.jl", data)
```

Expand Down
7 changes: 3 additions & 4 deletions src/debug/Data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,21 @@ module Data
using Random: MersenneTwister
using UUIDs: uuid4

const deprecated = Dict()
const deprecated = Dict("AuthorName" => "Bestie Template", "AuthorEmail" => "[email protected]")

const required = merge(
Dict(
"PackageName" => "FakePkg",
"PackageUUID" => string(uuid4(MersenneTwister(123))),
"PackageOwner" => "bestietemplate",
"AuthorName" => "Bestie Template",
"AuthorEmail" => "[email protected]",
),
deprecated,
)

const strategy_minimum = merge(
required,
Dict(
"Authors" => "Bestie Template <[email protected]> and contributors", # Move to required after 0.11
"JuliaMinVersion" => "1.6",
"License" => "MIT",
"LicenseCopyrightHolders" => "Bestie Template",
Expand All @@ -52,7 +51,7 @@ const optional_questions_with_default = Dict(
"AddContributionDocs" => true,
"AddAllcontributors" => true,
"AddCodeOfConduct" => true,
"CodeOfConductContact" => strategy_minimum["AuthorEmail"],
"CodeOfConductContact" => split(strategy_minimum["Authors"], ",")[1],
"AddGitHubTemplates" => true,
)

Expand Down
10 changes: 1 addition & 9 deletions src/guess.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,8 @@ function _read_data_from_existing_path(dst_path)
end
end

# Author capture is limited and does not handle multiple authors. See #118 for more information.
if haskey(toml_data, "authors")
author_regex = r"^(.*) <(.*)>(?: and contributors)?"
m = match(author_regex, toml_data["authors"][1])
if !isnothing(m)
data["AuthorName"] = m[1]
data["AuthorEmail"] = m[2]
else
@debug "authors field don't match regex"
end
data["Authors"] = join(toml_data["authors"], ",")
else
@debug "No authors information"
end
Expand Down
11 changes: 9 additions & 2 deletions template/CITATION.cff.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,12 @@ message: >-
metadata from this file.
type: software
authors:
- given-names: {{ AuthorName }}
email: {{ AuthorEmail }}
{%- for author in Authors.split(',') %}
{%- if author | length > 0 %}
- given-names: {{ author | regex_replace('^\\s*(.*)\\s*<.*>.*$', '\\1') }}
{%- set email = author | regex_replace('.*<(.*)>.*', '\\1') %}
{%- if email | length > 0 %}
email: {{ email }}
{%- endif %}
{%- endif %}
{%- endfor %}
14 changes: 13 additions & 1 deletion template/Project.toml.jinja
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
name = "{{ PackageName }}"
uuid = "{{ PackageUUID }}"
authors = ["{{ AuthorName }} <{{ AuthorEmail }}> and contributors"]
{%- if Authors | length > 0 %}
{%- if Authors.split(',') | length == 1 %}
authors = ["{{ Authors }}"]
{%- else %}
authors = [
{%- for author in Authors.split(',') %}
{%- if author | length > 0 %}
"{{ author }}",
{%- endif %}
{%- endfor %}
]
{%- endif %}
{%- endif %}
version = "0.1.0"

[compat]
Expand Down
2 changes: 1 addition & 1 deletion template/docs/make.jl.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const numbered_pages = [

makedocs(;
modules = [{{ PackageName }}],
authors = "{{ AuthorName }} <{{ AuthorEmail }}> and contributors",
authors = "{{ Authors }}",
repo = "https://github.com/{{ PackageOwner }}/{{ PackageName }}.jl/blob/{commit}{path}#{line}",
sitename = "{{ PackageName }}.jl",
format = Documenter.HTML(; canonical = "https://{{ PackageOwner }}.github.io/{{ PackageName }}.jl"),
Expand Down
26 changes: 5 additions & 21 deletions test/test-bestie-specific-api.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
@testset "Automatic guessing of data" begin
src_data = copy(C.args.bestie.ask)
guessable_answers = Set([
"AuthorEmail",
"AuthorName",
"JuliaMinVersion",
"Indentation",
"PackageName",
"PackageOwner",
"PackageUUID",
])
guessable_answers =
Set(["Authors", "JuliaMinVersion", "Indentation", "PackageName", "PackageOwner", "PackageUUID"])
@testset "Using random data" for _ in 1:10
for (key, value) in src_data
src_data[key] = _random(Val(Symbol(key)), value)
Expand Down Expand Up @@ -60,8 +53,7 @@
@testset "Guessed $key correctly" for (key, value) in data
@test value == src_data[key]
end
missing_keys =
["AuthorEmail", "AuthorName", "JuliaMinVersion", "PackageName", "PackageUUID"]
missing_keys = ["Authors", "JuliaMinVersion", "PackageName", "PackageUUID"]
@test Set(keys(data)) == setdiff(guessable_answers, missing_keys)

@testset "Add empty Project.toml" begin
Expand All @@ -73,14 +65,6 @@
".",
)
end

@testset "Wrong format for authors" begin
open("Project.toml", "w") do io
println(io, "authors = [\"Some author\"]")
end
@test_logs (:debug, "authors field don't match regex") min_level = Logging.Debug match_mode =
:any BestieTemplate._read_data_from_existing_path(".")
end
end
end

Expand Down Expand Up @@ -138,15 +122,15 @@ end
BestieTemplate.apply(
C.template_path,
"NewPkg/",
Dict("AuthorName" => "T. Esther", "PackageOwner" => "test");
Dict("Authors" => "T. Esther", "PackageOwner" => "test");
defaults = true,
overwrite = true,
quiet = true,
vcs_ref = "HEAD",
)
answers = YAML.load_file("NewPkg/.copier-answers.yml")
@test answers["PackageName"] == "NewPkg"
@test answers["AuthorName"] == "T. Esther"
@test answers["Authors"] == "T. Esther"
@test answers["PackageOwner"] == "test"
end

Expand Down

0 comments on commit c46df89

Please sign in to comment.