From 2597e68244afe7ff76024995d549f7bd08ccd349 Mon Sep 17 00:00:00 2001 From: richardreeve Date: Sun, 21 Jul 2024 18:13:03 +0100 Subject: [PATCH 01/10] Fix workflows --- .github/dependabot.yaml | 7 ++ .../{CompatHelper.yml => CompatHelper.yaml} | 7 +- .github/workflows/TagBot.yaml | 31 +++++++++ .github/workflows/TagBot.yml | 15 ----- .github/workflows/metadata.yaml | 38 +++++++++++ .../workflows/{nightly.yml => nightly.yaml} | 17 +++-- .github/workflows/testing.yaml | 66 +++++++++++++++++++ .github/workflows/testing.yml | 50 -------------- 8 files changed, 154 insertions(+), 77 deletions(-) create mode 100644 .github/dependabot.yaml rename .github/workflows/{CompatHelper.yml => CompatHelper.yaml} (85%) create mode 100644 .github/workflows/TagBot.yaml delete mode 100644 .github/workflows/TagBot.yml create mode 100644 .github/workflows/metadata.yaml rename .github/workflows/{nightly.yml => nightly.yaml} (62%) create mode 100644 .github/workflows/testing.yaml delete mode 100644 .github/workflows/testing.yml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..700707c --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yaml similarity index 85% rename from .github/workflows/CompatHelper.yml rename to .github/workflows/CompatHelper.yaml index 2f2eb51..38bb3d7 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yaml @@ -3,7 +3,7 @@ name: CompatHelper on: push: branches: - - main + - dev schedule: - cron: '0 4 * * *' # Daily at 4 AM @@ -19,7 +19,7 @@ jobs: os: - ubuntu-latest steps: - - uses: julia-actions/setup-julia@latest + - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.julia-version }} arch: ${{ matrix.arch }} @@ -28,7 +28,7 @@ jobs: import Pkg name = "CompatHelper" uuid = "aa819f21-2bde-4658-8897-bab36330d9b7" - version = "2" + version = "3" Pkg.add(; name, uuid, version) shell: julia --color=yes {0} - name: "Run CompatHelper" @@ -38,3 +38,4 @@ jobs: shell: julia --color=yes {0} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.github/workflows/TagBot.yaml b/.github/workflows/TagBot.yaml new file mode 100644 index 0000000..0cd3114 --- /dev/null +++ b/.github/workflows/TagBot.yaml @@ -0,0 +1,31 @@ +name: TagBot +on: + issue_comment: + types: + - created + workflow_dispatch: + inputs: + lookback: + default: "3" +permissions: + actions: read + checks: read + contents: write + deployments: read + issues: read + discussions: read + packages: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read +jobs: + TagBot: + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' + runs-on: ubuntu-latest + steps: + - uses: JuliaRegistries/TagBot@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ssh: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml deleted file mode 100644 index 5a00d3a..0000000 --- a/.github/workflows/TagBot.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: TagBot -on: - issue_comment: - types: - - created - workflow_dispatch: - -jobs: - TagBot: - if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' - runs-on: ubuntu-latest - steps: - - uses: JuliaRegistries/TagBot@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/metadata.yaml b/.github/workflows/metadata.yaml new file mode 100644 index 0000000..bb04ef1 --- /dev/null +++ b/.github/workflows/metadata.yaml @@ -0,0 +1,38 @@ +name: Metadata and hygene + +on: + push: + branches: + - dev + tags: + - 'v*' + pull_request: + workflow_dispatch: + +permissions: # needed to allow julia-actions/cache to proactively delete old caches that it has created + actions: write + contents: read + +jobs: + metadata: + name: RSMD - ${{ github.event_name }} + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up julia + uses: julia-actions/setup-julia@v2 + with: + version: '1' + arch: x64 + - name: Cache + uses: julia-actions/cache@v2 + - name: Build package + uses: julia-actions/julia-buildpkg@v1 + - name: Running + uses: julia-actions/julia-runtest@v1 + env: + RSMD_CROSSWALK: TRUE diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yaml similarity index 62% rename from .github/workflows/nightly.yml rename to .github/workflows/nightly.yaml index 16e89d4..bb2a335 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yaml @@ -1,13 +1,10 @@ name: JuliaNightly # Nightly Scheduled Julia Nightly Run + on: - push: - branches: - - main - tags: - - 'v*' schedule: - cron: '0 2 * * 0' # Weekly at 2 AM UTC Sunday + workflow_dispatch: jobs: test: @@ -15,13 +12,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up julia - uses: julia-actions/setup-julia@v1 + uses: julia-actions/setup-julia@v2 with: version: nightly arch: x64 - name: Build package - uses: julia-actions/julia-buildpkg@latest + uses: julia-actions/julia-buildpkg@v1 + with: + ignore-no-cache: true - name: Run tests - uses: julia-actions/julia-runtest@latest + uses: julia-actions/julia-runtest@v1 diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml new file mode 100644 index 0000000..6636e93 --- /dev/null +++ b/.github/workflows/testing.yaml @@ -0,0 +1,66 @@ +name: CI + +on: + push: + branches: + - dev + tags: + - 'v*' + pull_request: + +permissions: # needed to allow julia-actions/cache to proactively delete old caches that it has created + actions: write + contents: read + +jobs: + Diversity-tests: + name: Julia ${{ matrix.julia-version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + timeout-minutes: 60 + runs-on: ${{ matrix.os }} + continue-on-error: ${{ matrix.experimental }} + strategy: + matrix: + julia-version: + - '1.6' + - '1.8' + - '1' + os: + - ubuntu-latest + - macOS-latest + - windows-latest + R-version: + - 'release' + arch: + - x64 + - arm64 + experimental: + - false + exclude: + - os: macOS-latest + arch: x64 + - os: ubuntu-latest + arch: arm64 + - os: windows-latest + arch: arm64 + fail-fast: false + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up julia + uses: julia-actions/setup-julia@v2 + with: + version: ${{ matrix.julia-version }} + arch: ${{ matrix.arch }} + - name: Cache + uses: julia-actions/cache@v2 + - name: Build package + uses: julia-actions/julia-buildpkg@v1 + - name: Running + uses: julia-actions/julia-runtest@v1 + - name: Process coverage + uses: julia-actions/julia-processcoverage@v1 + - name: Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml deleted file mode 100644 index dff91f5..0000000 --- a/.github/workflows/testing.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: CI - -on: - push: - branches: - - main - tags: - - 'v*' - pull_request: - -jobs: - EcoBase-tests: - runs-on: ${{ matrix.os }} - continue-on-error: ${{ matrix.experimental }} - strategy: - matrix: - julia-version: - - '1' - os: - - ubuntu-latest - - macOS-latest - - windows-latest - R-version: - - 'release' - arch: - - x64 - experimental: - - false - fail-fast: false - steps: - - name: Checkout code - uses: actions/checkout@v2 - - name: Set up julia - uses: julia-actions/setup-julia@v1 - with: - version: ${{ matrix.julia-version }} - arch: ${{ matrix.arch }} - - name: Build package - uses: julia-actions/julia-buildpkg@master - - name: Running - uses: julia-actions/julia-runtest@master - - name: Process coverage - uses: julia-actions/julia-processcoverage@v1 - - name: Coveralls - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - path-to-lcov: ./lcov.info - - name: Codecov - uses: codecov/codecov-action@v1 From 9c41207a4320b2749f0af8b62cd384d0aa08f7ca Mon Sep 17 00:00:00 2001 From: richardreeve Date: Sun, 21 Jul 2024 18:15:40 +0100 Subject: [PATCH 02/10] Add in metadata code --- .JuliaFormatter.toml | 10 ++++++++++ .gitignore | 1 + Project.toml | 36 ++++++++++++++++++++++++++++++++---- docs/Project.toml | 8 ++++++++ docs/metadata.jl | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 .JuliaFormatter.toml create mode 100644 docs/Project.toml create mode 100644 docs/metadata.jl diff --git a/.JuliaFormatter.toml b/.JuliaFormatter.toml new file mode 100644 index 0000000..d9955b4 --- /dev/null +++ b/.JuliaFormatter.toml @@ -0,0 +1,10 @@ +style = "sciml" +margin = 80 +remove_extra_newlines = true +always_use_return = true +trailing_comma = false +join_lines_based_on_source = true +yas_style_nesting = true +always_for_in = true +annotate_untyped_fields_with_any = true +normalize_line_endings = "unix" diff --git a/.gitignore b/.gitignore index c35353a..df2fefe 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.jl.mem .DS_Store Manifest.toml +.vscode/settings.json diff --git a/Project.toml b/Project.toml index 24bad1d..a9d78c2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,24 +1,52 @@ name = "EcoBase" uuid = "a58aae7d-b440-5a11-b283-399458f99aac" -keywords = ["macroecology", "ecology", "biology", "geography"] license = "MIT" +authors = ["Michael Borregaard", "Richard Reeve ", "Kevin Bonham "] +version = "0.1.7" +keywords = ["macroecology", "ecology", "biology", "geography", "julia", "EcoJulia"] desc = "Base package with abstract types for ecology" -authors = ["mkborregaard ", "Kevin Bonham "] -version = "0.1.6" [deps] RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" [compat] Diversity = "0.5" +Git = "1" +JuliaFormatter = "1" +Logging = "1" +Pkg = "1" +Random = "1" RecipesBase = "0.7, 0.8, 0.9, 1" +ResearchSoftwareMetadata = "0.1.1" SpatialEcology = "0.9" julia = "1" +[[author_details]] +name = "Michael Borregaard" +orcid = "0000-0002-8146-8435" + + [[author_details.affiliation]] + ror = "035b05819" +[[author_details]] +name = "Richard Reeve" +orcid = "0000-0003-2589-8091" + + [[author_details.affiliation]] + ror = "00vtgdb53" +[[author_details]] +name = "Kevin Bonham" +email = "kbonham@wellesley.edu" + [extras] Diversity = "d3d5718d-52de-57ab-b67a-eca7fd6175a4" +Git = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2" +JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899" +Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +ResearchSoftwareMetadata = "58378933-4625-47fa-851e-05ee27d397bd" SpatialEcology = "348f2d5d-71a3-5ad4-b565-8af070f99681" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["SpatialEcology", "Diversity", "Test"] +test = ["SpatialEcology", "Diversity", "Git", "JuliaFormatter", "Logging", "Pkg", "Random", "ResearchSoftwareMetadata", "Test"] diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..510100f --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,8 @@ +[deps] +DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +EcoBase = "a58aae7d-b440-5a11-b283-399458f99aac" +JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899" +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +ResearchSoftwareMetadata = "58378933-4625-47fa-851e-05ee27d397bd" diff --git a/docs/metadata.jl b/docs/metadata.jl new file mode 100644 index 0000000..e0e6d56 --- /dev/null +++ b/docs/metadata.jl @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: MIT + +using Pkg + +# Update EcoBase folder packages +Pkg.activate(".") +Pkg.update() + +# Update examples folder packages +if isdir("examples") + if isfile("examples/Project.toml") + Pkg.activate("examples") + Pkg.update() + "EcoBase" ∈ [p.name for p in values(Pkg.dependencies())] && + Pkg.rm("EcoBase") + Pkg.develop("EcoBase") + end +end + +# Update docs folder packages +Pkg.activate("docs") +Pkg.update() +"EcoBase" ∈ [p.name for p in values(Pkg.dependencies())] && + Pkg.rm("EcoBase") +Pkg.develop("EcoBase") + +# Reformat files in package +using JuliaFormatter +using EcoBase +format(EcoBase) + +# Carry out crosswalk for metadata +using ResearchSoftwareMetadata +ResearchSoftwareMetadata.crosswalk() From 6cafc616145d8643d9114b29413d049846f5b877 Mon Sep 17 00:00:00 2001 From: richardreeve Date: Sun, 21 Jul 2024 18:16:05 +0100 Subject: [PATCH 03/10] Clean code --- src/DataTypes.jl | 4 ++- src/EcoBase.jl | 8 ++++- src/Interface.jl | 88 +++++++++++++++++++++++++++++++--------------- src/PlotRecipes.jl | 18 +++++----- 4 files changed, 78 insertions(+), 40 deletions(-) diff --git a/src/DataTypes.jl b/src/DataTypes.jl index aa7f531..25f46b3 100644 --- a/src/DataTypes.jl +++ b/src/DataTypes.jl @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: MIT """ AbstractThings @@ -36,7 +37,8 @@ a subtype of AbstractLocationData if they have spatial data. Other metadata in the AbstractPlaces subtype should be in the AbstractPlaces subtype. """ -abstract type AbstractPlaces{LocationDataType <: Union{Nothing, AbstractLocationData}} end +abstract type AbstractPlaces{LocationDataType <: + Union{Nothing, AbstractLocationData}} end """ AbstractPoints <: AbstractLocationData diff --git a/src/EcoBase.jl b/src/EcoBase.jl index e3063e1..cb7e75e 100644 --- a/src/EcoBase.jl +++ b/src/EcoBase.jl @@ -1,8 +1,13 @@ +# SPDX-License-Identifier: MIT + module EcoBase import Base: show, view import RecipesBase +# Path into package +path(path...; dir::String = "test") = joinpath(@__DIR__, "..", dir, path...) + include("DataTypes.jl") include("Interface.jl") include("PlotRecipes.jl") @@ -10,7 +15,8 @@ include("PlotRecipes.jl") export nthings, nplaces, occupancy, richness, nrecords, placenames, thingnames export occurring, noccurring, occupied, noccupied, occurrences export placeoccurrences, thingoccurrences, cooccurring, places, things -export asindices, indices, coordinates, xcells, ycells, cells, xmin, xmax, ymin, ymax +export asindices, indices, coordinates, xcells, ycells, cells, xmin, xmax, ymin, + ymax export xrange, yrange, xcellsize, ycellsize, cellsize, getcoords end # module diff --git a/src/Interface.jl b/src/Interface.jl index b200d7a..aef56cf 100644 --- a/src/Interface.jl +++ b/src/Interface.jl @@ -1,11 +1,28 @@ +# SPDX-License-Identifier: MIT + asindices(x::Integer) = x -asindices(x::AbstractArray{T}) where T <: Union{Missing, Integer} = x -asindices(x::AbstractArray{Union{Missing, Bool}}) = findall(y->!ismissing(y) && y, x) -asindices(x::AbstractArray{T}) where T <: Bool = findall(x) +asindices(x::AbstractArray{T}) where {T <: Union{Missing, Integer}} = x +function asindices(x::AbstractArray{Union{Missing, Bool}}) + return findall(y -> !ismissing(y) && y, x) +end +asindices(x::AbstractArray{T}) where {T <: Bool} = findall(x) asindices(x, y) = asindices(x) -asindices(x::AbstractArray{T}, y::AbstractArray{T}) where T <: Union{Missing, AbstractString} = [el for el in indexin(x, y) if el !== nothing] -asindices(x::AbstractArray{T}, y::AbstractArray{<:AbstractString}) where T <: Union{Missing, Symbol} = asindices(string.(x), y) -asindices(x::T, y::AbstractArray) where T <: Union{Missing, Symbol, AbstractString} = first(asindices([x], y)) +function asindices(x::AbstractArray{T}, + y::AbstractArray{T}) where {T <: + Union{Missing, AbstractString}} + return [el for el in indexin(x, y) if el !== nothing] +end +function asindices(x::AbstractArray{T}, + y::AbstractArray{<:AbstractString}) where {T <: + Union{Missing, + Symbol}} + return asindices(string.(x), y) +end +function asindices(x::T, + y::AbstractArray) where {T <: Union{Missing, Symbol, + AbstractString}} + return first(asindices([x], y)) +end # Functions - most have to be implemented with the concrete type occurrences(asm::AbstractAssemblage)::AbstractMatrix = error("function not defined for $(typeof(asm))") @@ -19,7 +36,6 @@ placekind(asm::AbstractAssemblage) = "place" thingkindplural(asm::AbstractAssemblage) = "$(thingkind(asm))s" placekindplural(asm::AbstractAssemblage) = "$(placekind(asm))s" - nplaces(plc::AbstractPlaces)::Integer = error("function not defined for $(typeof(plc))") nplaces(plc::AbstractAssemblage) = nplaces(places(plc)) placenames(plc::AbstractPlaces)::AbstractVector{<:String} = error("function not defined for $(typeof(plc))") @@ -37,11 +53,15 @@ colsum(x) = sum(x, dims = 1) rowsum(x) = sum(x, dims = 2) occurring(asm::AbstractAssemblage) = occurring(occurrences(asm)) -occurring(asm::AbstractAssemblage, idx) = occurring(occurrences(asm), asindices(idx, placenames(asm))) occurring(a::AbstractMatrix) = nzrows(a) +function occurring(asm::AbstractAssemblage, idx) + return occurring(occurrences(asm), asindices(idx, placenames(asm))) +end occupied(asm::AbstractAssemblage) = occupied(occurrences(asm)) -occupied(asm::AbstractAssemblage, idx) = occupied(occurrences(asm), asindices(idx, thingnames(asm))) +function occupied(asm::AbstractAssemblage, idx) + return occupied(occurrences(asm), asindices(idx, thingnames(asm))) +end occupied(a::AbstractMatrix) = nzcols(a) occupied(a::AbstractMatrix, idx) = findall(!iszero, a[idx, :]) @@ -54,9 +74,13 @@ noccupied(x) = length(occupied(x)) noccurring(x, idx) = length(occurring(x, idx)) noccupied(x, idx) = length(occupied(x, idx)) -thingoccurrences(asm::AbstractAssemblage, idx) = thingoccurrences(occurrences(asm), asindices(idx, thingnames(asm))) +function thingoccurrences(asm::AbstractAssemblage, idx) + return thingoccurrences(occurrences(asm), asindices(idx, thingnames(asm))) +end thingoccurrences(mat::AbstractMatrix, idx) = view(mat, idx, :) -placeoccurrences(asm::AbstractAssemblage, idx) = placeoccurrences(occurrences(asm), asindices(idx, placenames(asm))) +function placeoccurrences(asm::AbstractAssemblage, idx) + return placeoccurrences(occurrences(asm), asindices(idx, placenames(asm))) +end placeoccurrences(mat::AbstractMatrix, idx) = view(mat, :, idx) # make certain that the view implementation also takes thing or place names richness(asm::AbstractAssemblage) = richness(occurrences(asm)) @@ -65,7 +89,7 @@ richness(a::AbstractMatrix) = collect(vec(mapslices(nnz, a, dims = 1))) occupancy(asm::AbstractAssemblage) = occupancy(occurrences(asm)) occupancy(a::AbstractMatrix{Bool}) = collect(vec(rowsum(a))) -occupancy(a::AbstractMatrix) = collect(vec(mapslices(nnz, a, dims=2))) +occupancy(a::AbstractMatrix) = collect(vec(mapslices(nnz, a, dims = 2))) nrecords(asm::AbstractAssemblage) = nrecords(occurrences(asm)) nrecords(a::AbstractMatrix) = nnz(a) @@ -73,32 +97,32 @@ nrecords(a::AbstractMatrix) = nnz(a) cooccurring(asm, inds...) = cooccurring(asm, [inds...]) function cooccurring(asm, inds::AbstractVector) sub = view(asm, species = inds) - richness(sub) .== nthings(sub) + return richness(sub) .== nthings(sub) end function createsummaryline(vec::AbstractVector{<:AbstractString}) - linefunc(vec) = mapreduce(x -> x * ", ", *, vec[1:(end-1)]) * vec[end] + linefunc(vec) = mapreduce(x -> x * ", ", *, vec[1:(end - 1)]) * vec[end] length(vec) == 1 && return vec[1] length(vec) < 6 && return linefunc(vec) - linefunc(vec[1:3]) * "..." * linefunc(vec[(end-1):end]) + return linefunc(vec[1:3]) * "..." * linefunc(vec[(end - 1):end]) end -function show(io::IO, asm::T) where T <: AbstractAssemblage +function show(io::IO, asm::T) where {T <: AbstractAssemblage} tn = createsummaryline(thingnames(asm)) pn = createsummaryline(placenames(asm)) thing = titlecase(thingkind(asm)) things = thingkindplural(asm) place = titlecase(placekind(asm)) places = placekindplural(asm) - println(io, - """$T with $(nthings(asm)) $things in $(nplaces(asm)) $places + return println(io, + """$T with $(nthings(asm)) $things in $(nplaces(asm)) $places - $thing names: - $(tn) + $thing names: + $(tn) - $place names: - $(pn) - """) + $place names: + $(pn) + """) end nplaces(asm::AbstractAssemblage, args...) = nplaces(places(asm), args...) @@ -106,15 +130,17 @@ placenames(asm::AbstractAssemblage, args...) = placenames(places(asm), args...) nthings(asm::AbstractAssemblage, args...) = nthings(things(asm), args...) thingnames(asm::AbstractAssemblage, args...) = thingnames(things(asm), args...) - # TODO: # accessing cache # Methods for AbstractPlaces getcoords(plc::AbstractPlaces{Nothing}) = plc # Pure places generate their own fake location data -getcoords(plc::AbstractPlaces{<: AbstractLocationData}) = - error("function not defined for $(typeof(plc))") -coordinates(plc::AbstractPlaces) = error("function not defined for $(typeof(plc))") +function getcoords(plc::AbstractPlaces{<:AbstractLocationData}) + return error("function not defined for $(typeof(plc))") +end +function coordinates(plc::AbstractPlaces) + return error("function not defined for $(typeof(plc))") +end # Methods for AbstractGrid xmin(grd::AbstractGrid) = error("function not defined for $(typeof(grd))") @@ -131,5 +157,9 @@ xmax(grd) = xmin(grd) + xcellsize(grd) * (xcells(grd) - 1) ymax(grd) = ymin(grd) + ycellsize(grd) * (ycells(grd) - 1) indices(grd::AbstractGrid) = error("function not defined for $(typeof(grd))") -indices(grd::AbstractGrid, idx) = error("function not defined for $(typeof(grd))") -coordinates(grd::AbstractGrid) = error("function not defined for $(typeof(grd))") +function indices(grd::AbstractGrid, idx) + return error("function not defined for $(typeof(grd))") +end +function coordinates(grd::AbstractGrid) + return error("function not defined for $(typeof(grd))") +end diff --git a/src/PlotRecipes.jl b/src/PlotRecipes.jl index 56de9bd..192e099 100644 --- a/src/PlotRecipes.jl +++ b/src/PlotRecipes.jl @@ -1,18 +1,18 @@ - +# SPDX-License-Identifier: MIT function convert_to_image(var::AbstractVector, grd::AbstractGrid) x = Matrix{Float64}(undef, reverse(cells(grd))...) fill!(x, NaN) - xind, yind = indices(grd, 1), indices(grd,2) #since matrices are drawn from upper left corner + xind, yind = indices(grd, 1), indices(grd, 2) #since matrices are drawn from upper left corner [x[yind[i], xind[i]] = val for (i, val) in enumerate(var)] - x + return x end RecipesBase.@recipe function f(var::AbstractVector, grd::AbstractGrid) seriestype := :heatmap aspect_ratio --> :equal grid --> false - xrange(grd), yrange(grd), convert_to_image(var, grd) + return xrange(grd), yrange(grd), convert_to_image(var, grd) end # RecipesBase.@recipe function f(sit::SiteFields) # not sure what SiteFields are @@ -27,22 +27,22 @@ RecipesBase.@recipe function f(var::AbstractVector, pnt::AbstractPoints) legend --> false colorbar --> true cd = coordinates(pnt) - cd[:,1], cd[:,2] + return cd[:, 1], cd[:, 2] end RecipesBase.@recipe function f(asm::AbstractAssemblage; showempty = false) var = richness(asm) if !showempty var = [Float64(v) for v in var] - (var[var.==0] .= NaN) + (var[var .== 0] .= NaN) end - var, getcoords(places(asm)) + return var, getcoords(places(asm)) end RecipesBase.@recipe function f(var::AbstractVector, asm::AbstractAssemblage) - var, getcoords(places(asm)) + return var, getcoords(places(asm)) end RecipesBase.@recipe function f(g::Function, asm::AbstractAssemblage) - g(asm), getcoords(places(asm)) + return g(asm), getcoords(places(asm)) end From 7ea697067249e4a1aa0cfe02006e07405b01953f Mon Sep 17 00:00:00 2001 From: richardreeve Date: Sun, 21 Jul 2024 18:16:21 +0100 Subject: [PATCH 04/10] Add in testing --- test/clean_JuliaFormatter.jl | 42 ++++++ test/clean_ResearchSoftwareMetadata.jl | 44 ++++++ test/runtests.jl | 184 ++++++++++++++++++++----- test/test_Interface.jl | 12 +- 4 files changed, 242 insertions(+), 40 deletions(-) create mode 100644 test/clean_JuliaFormatter.jl create mode 100644 test/clean_ResearchSoftwareMetadata.jl diff --git a/test/clean_JuliaFormatter.jl b/test/clean_JuliaFormatter.jl new file mode 100644 index 0000000..b350161 --- /dev/null +++ b/test/clean_JuliaFormatter.jl @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: MIT + +module CleanJuliaFormatter +using Test +using EcoBase +using Git +using Logging +using Pkg +using JuliaFormatter + +function is_repo_clean(repo_path; ignore_untracked = true) + # Get the status of the repository + statuses = readlines(`$(Git.git()) status -s $repo_path`) + + if ignore_untracked + # Repo must be clean except for untracked files + statuses = filter((!) ∘ contains("??"), statuses) + end + + is_clean = isempty(statuses) + + # If not clean then report on dirty files + is_clean || @error "\n" * join(statuses, "\n") + + return is_clean +end + +# Metadata crosswalk testing only works on Julia v1.8 and after due to Project.toml changes +# Also does not currently work on Windows runners on GitHub due to file writing issues +if VERSION ≥ VersionNumber("1.8.0") && + (!haskey(ENV, "RUNNER_OS") || ENV["RUNNER_OS"] ≠ "Windows") + @testset "JuliaFormatter" begin + git_dir = readchomp(`$(Git.git()) rev-parse --show-toplevel`) + @test_nowarn format(EcoBase) + @test is_repo_clean(git_dir) + end +else + @test_broken VERSION ≥ VersionNumber("1.8.0") && + (!haskey(ENV, "RUNNER_OS") || ENV["RUNNER_OS"] ≠ "Windows") +end + +end diff --git a/test/clean_ResearchSoftwareMetadata.jl b/test/clean_ResearchSoftwareMetadata.jl new file mode 100644 index 0000000..2d51443 --- /dev/null +++ b/test/clean_ResearchSoftwareMetadata.jl @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: MIT + +module CleanRSMD +using Test +using EcoBase +using Git +using Logging +using Pkg +using ResearchSoftwareMetadata + +function is_repo_clean(repo_path; ignore_untracked = true) + # Get the status of the repository + statuses = readlines(`$(Git.git()) status -s $repo_path`) + + if ignore_untracked + # Repo must be clean except for untracked files + statuses = filter((!) ∘ contains("??"), statuses) + end + + is_clean = isempty(statuses) + + # If not clean then report on dirty files + is_clean || @error "\n" * join(statuses, "\n") + + return is_clean +end + +# Metadata crosswalk testing only works on Julia v1.8 and after due to Project.toml changes +# Also does not currently work on Windows runners on GitHub due to file writing issues +if VERSION ≥ VersionNumber("1.8.0") && + (!haskey(ENV, "RUNNER_OS") || ENV["RUNNER_OS"] ≠ "Windows") + @testset "RSMD" begin + git_dir = readchomp(`$(Git.git()) rev-parse --show-toplevel`) + @test isnothing(ResearchSoftwareMetadata.crosswalk()) + global_logger(SimpleLogger(stderr, Logging.Warn)) + @test_nowarn ResearchSoftwareMetadata.crosswalk() + @test is_repo_clean(git_dir) + end +else + @test_broken VERSION ≥ VersionNumber("1.8.0") && + (!haskey(ENV, "RUNNER_OS") || ENV["RUNNER_OS"] ≠ "Windows") +end + +end diff --git a/test/runtests.jl b/test/runtests.jl index bebe740..b61d857 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,50 +1,162 @@ +# SPDX-License-Identifier: MIT + +using Random using Test +using EcoBase +using Pkg -# Identify files in test/ that are testing matching files in src/ -# - src/Source.jl will be matched by test/test_Source.jl +rsmd = get(ENV, "RSMD_CROSSWALK", "FALSE") -filebase = String[] -for (root, dirs, files) in walkdir("../src") - append!(filebase, - map(file -> replace(file, r"(.*).jl" => s"\1"), - filter(file -> occursin(r".*\.jl", file), files))) -end +if rsmd == "FALSE" + # Normal testing + + # Identify files in test/ that are testing matching files in src/ + # - src/Source.jl will be matched by test/test_Source.jl + filebase = String[] + for (root, dirs, files) in walkdir("../src") + append!(filebase, + map(file -> replace(file, r"(.*).jl" => s"\1"), + filter(file -> occursin(r".*\.jl", file), files))) + end -testbase = map(file -> replace(file, r"test_(.*).jl" => s"\1"), - filter(str -> occursin(r"^test_.*\.jl$", str), readdir())) + testbase = map(file -> replace(file, r"test_(.*).jl" => s"\1"), + filter(str -> occursin(r"^test_.*\.jl$", str), readdir())) -@testset "EcoBase.jl" begin - println() - @info "Running tests for files:" - for t in testbase - println(" = $t.jl") + # Identify tests with no matching file + superfluous = filter(f -> f ∉ filebase, testbase) + if length(superfluous) > 0 + println() + @info "Potentially superfluous tests:" + for f in superfluous + println(" + $f.jl") + end + println() end - println() - @info "Running tests..." - @testset for t in testbase - fn = "test_$t.jl" - println(" * Testing $t.jl ...") - include(fn) + # Identify files with no matching test + notest = filter(f -> f ∉ testbase, filebase) + if length(notest) > 0 + println() + @info "Potentially missing tests:" + for f in notest + println(" - $f.jl") + end + println() + end + + # Identify files in test/ that are testing matching files in ext/ + # - ext/SourceExt.jl will be matched by test/ext_SourceExt.jl + filebase = String[] + for (root, dirs, files) in walkdir("../ext") + append!(filebase, + map(file -> replace(file, r"(.*).jl" => s"\1"), + filter(file -> occursin(r".*\.jl", file), files))) + end + + extbase = map(file -> replace(file, r"ext_(.*).jl" => s"\1"), + filter(str -> occursin(r"^ext_.*\.jl$", str), readdir())) + + # Identify tests with no matching file + superfluous = filter(f -> f ∉ filebase, extbase) + if length(superfluous) > 0 + println() + @info "Potentially superfluous extension tests:" + for f in superfluous + println(" + $f.jl") + end + println() + end + + # Identify files with no matching test + notest = filter(f -> f ∉ extbase, filebase) + if length(notest) > 0 + println() + @info "Potentially missing extension tests:" + for f in notest + println(" - $f.jl") + end + println() end -end -# Identify tests with no matching file -superfluous = filter(f -> f ∉ filebase, testbase) -if length(superfluous) > 0 - println() - @info "Potentially superfluous tests:" - for f in superfluous - println(" + $f.jl") + # Seed RNG to make tests reproducible + Random.seed!(1234) + + @testset "EcoBase.jl" begin + @test isfile(EcoBase.path("runtests.jl")) + println() + @info "Running tests for files:" + for t in testbase + println(" = $t.jl") + end + println() + + @info "Running tests..." + @testset for t in testbase + fn = "test_$t.jl" + println(" * Testing $t.jl ...") + include(fn) + end + + println() + @info "Running tests for extensions:" + for t in extbase + println(" = $t.jl") + end + println() + + @info "Running extension tests..." + @testset for t in extbase + fn = "ext_$t.jl" + println(" * Testing $t.jl extension...") + include(fn) + end + end + + # Identify files that are cross-validating results against other packages + # test/pkg_Package.jl should validate results against the Package package + + pkgbase = map(file -> replace(file, r"pkg_(.*).jl$" => s"\1"), + filter(str -> occursin(r"^pkg_.*\.jl$", str), + readdir())) + + if length(pkgbase) > 0 + @info "Cross validation packages:" + @testset begin + for p in pkgbase + println(" = $p") + end + println() + + @testset for p in pkgbase + fn = "pkg_$p.jl" + println(" * Validating $p.jl ...") + include(fn) + end + end end end -# Identify files with no matching test -notest = filter(f -> f ∉ testbase, filebase) -if length(notest) > 0 - println() - @info "Potentially missing tests:" - for f in notest - println(" - $f.jl") +if rsmd == "TRUE" || !haskey(ENV, "RUNNER_OS") # Crosswalk runner or local testing + # Test RSMD crosswalk and other hygene issues + + # Identify files that are checking package hygene + cleanbase = map(file -> replace(file, r"clean_(.*).jl$" => s"\1"), + filter(str -> occursin(r"^clean_.*\.jl$", str), + readdir())) + + if length(cleanbase) > 0 + @info "Crosswalk and clean testing:" + @testset begin + for c in cleanbase + println(" = $c") + end + println() + + @testset for c in cleanbase + fn = "clean_$c.jl" + println(" * Verifying $c.jl ...") + include(fn) + end + end end end diff --git a/test/test_Interface.jl b/test/test_Interface.jl index ddd368d..74b32cb 100644 --- a/test/test_Interface.jl +++ b/test/test_Interface.jl @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: MIT + module TestInterface using Test @@ -21,8 +23,10 @@ using EcoBase @test all(EcoBase.thingnames(mc) .== species) @test all(EcoBase.placenames(mc) .== communities) @test all(EcoBase.occurrences(mc) .≈ manyweights) - @test all(EcoBase.richness(mc) .== repeat([numspecies], inner=numcommunities)) - @test all(EcoBase.occupancy(mc) .== repeat([numcommunities], inner=numspecies)) + @test all(EcoBase.richness(mc) .== + repeat([numspecies], inner = numcommunities)) + @test all(EcoBase.occupancy(mc) .== + repeat([numcommunities], inner = numspecies)) fewerweights = deepcopy(manyweights) fewerweights[1, 1] = 0 fewerweights /= sum(fewerweights) @@ -51,8 +55,8 @@ end @test all(thingnames(mc) .== species) @test all(placenames(mc) .== communities) @test all(occurrences(mc) .≈ manyweights) - @test all(richness(mc) .== repeat([numspecies], inner=numcommunities)) - @test all(occupancy(mc) .== repeat([numcommunities], inner=numspecies)) + @test all(richness(mc) .== repeat([numspecies], inner = numcommunities)) + @test all(occupancy(mc) .== repeat([numcommunities], inner = numspecies)) fewerweights = deepcopy(manyweights) fewerweights[1, 1] = 0 fewerweights /= sum(fewerweights) From 2b486db924f6cf39d907bd9b8548e9967191a02d Mon Sep 17 00:00:00 2001 From: richardreeve Date: Sun, 21 Jul 2024 18:16:34 +0100 Subject: [PATCH 05/10] Fix metadata --- .zenodo.json | 27 +++++++++++++--------- LICENSE | 20 ++++------------ codemeta.json | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 codemeta.json diff --git a/.zenodo.json b/.zenodo.json index a4f6677..2789efa 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,30 +1,35 @@ { - "title": "EcoBase.jl - A package implementing an abstract interface to data types used in ecological analyses", - "description": "This package implements an abstract interface to data types used in ecological analyses in Julia", + "title": "EcoBase.jl", "upload_type": "software", "creators": [ { - "affiliation": "GLOBE Institute, University of Copenhagen", - "name": "Borregaard, Michael Krabbe", - "orcid": "0000-0002-8146-8435" + "name": "Reeve, Richard", + "orcid": "0000-0003-2589-8091", + "affiliation": "University of Glasgow", + "ror": "00vtgdb53" }, { - "affiliation": "University of Glasgow", - "name": "Reeve, Richard", - "orcid": "0000-0003-2589-8091" + "name": "Borregaard, Michael", + "orcid": "0000-0002-8146-8435", + "affiliation": "University of Copenhagen", + "ror": "035b05819" } ], "access_right": "open", - "license": "mit-license", + "license": "MIT", "related_identifiers": [ { "scheme": "url", "identifier": "https://github.com/EcoJulia/EcoBase.jl", - "relation": "isIdenticalTo" + "relation": "isOriginalFormOf" } ], "keywords": [ + "EcoJulia", + "biology", + "ecology", + "geography", "julia", - "ecology" + "macroecology" ] } diff --git a/LICENSE b/LICENSE index 8d888f7..aca8d78 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,9 @@ MIT License -Copyright (c) 2018-2021: Michael K. Borregaard, Richard Reeve and EcoJulia +Copyright (c) 2018-2024 Michael Borregaard, Richard Reeve and Kevin Bonham -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/codemeta.json b/codemeta.json new file mode 100644 index 0000000..f71806e --- /dev/null +++ b/codemeta.json @@ -0,0 +1,64 @@ +{ + "@context": "https://w3id.org/codemeta/3.0", + "type": "SoftwareSourceCode", + "applicationCategory": "ecology", + "programmingLanguage": "julia", + "developmentStatus": "active", + "codeRepository": "https://github.com/EcoJulia/EcoBase.jl", + "name": "EcoBase.jl", + "issueTracker": "https://github.com/EcoJulia/EcoBase.jl/issues", + "readme": "https://github.com/EcoJulia/EcoBase.jl/blob/main/README.md", + "buildInstructions": "https://github.com/EcoJulia/EcoBase.jl/blob/main/README.md", + "dateCreated": "2018-01-30", + "operatingSystem": [ + "Linux", + "Windows", + "macOS" + ], + "version": "v0.1.7", + "dateModified": "2024-07-21", + "datePublished": "2018-09-20", + "downloadUrl": "https://github.com/EcoJulia/EcoBase.jl/archive/refs/tags/v0.1.7.tar.gz", + "license": "https://spdx.org/licenses/MIT", + "author": [ + { + "type": "Person", + "givenName": "Richard", + "familyName": "Reeve", + "email": "richard.reeve@glasgow.ac.uk", + "id": "https://orcid.org/0000-0003-2589-8091", + "affiliation": [ + { + "type": "Organization", + "name": "University of Glasgow", + "identifier": "https://ror.org/00vtgdb53" + } + ] + }, + { + "type": "Person", + "givenName": "Michael", + "familyName": "Borregaard", + "id": "https://orcid.org/0000-0002-8146-8435", + "affiliation": [ + { + "type": "Organization", + "name": "University of Copenhagen", + "identifier": "https://ror.org/035b05819" + } + ] + } + ], + "continuousIntegration": "https://github.com/EcoJulia/EcoBase.jl/actions/workflows/testing.yaml", + "codemeta:contIntegration": { + "id": "https://github.com/EcoJulia/EcoBase.jl/actions/workflows/testing.yaml" + }, + "keywords": [ + "EcoJulia", + "biology", + "ecology", + "geography", + "julia", + "macroecology" + ] +} From 69a71c7e9bd3983f501eb9307e447aadbbaa8ac2 Mon Sep 17 00:00:00 2001 From: richardreeve Date: Sun, 21 Jul 2024 21:10:03 +0100 Subject: [PATCH 06/10] arm64 vs x64 testing --- .github/workflows/testing.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 6636e93..d67aded 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -17,7 +17,7 @@ jobs: name: Julia ${{ matrix.julia-version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} timeout-minutes: 60 runs-on: ${{ matrix.os }} - continue-on-error: ${{ matrix.experimental }} + continue-on-error: false strategy: matrix: julia-version: @@ -26,17 +26,19 @@ jobs: - '1' os: - ubuntu-latest - - macOS-latest + - macos-latest - windows-latest - R-version: - - 'release' arch: - x64 - arm64 - experimental: - - false exclude: - os: macOS-latest + julia-version: + - '1.6' + - '1.8' + arch: arm64 + - os: macOS-latest + julia-version: '1' arch: x64 - os: ubuntu-latest arch: arm64 From 63c3c4e1b6d9ffe166f98b526b7cd2d7e09fb7a2 Mon Sep 17 00:00:00 2001 From: richardreeve Date: Sun, 21 Jul 2024 21:26:08 +0100 Subject: [PATCH 07/10] Clear unnecessary testing --- .github/workflows/testing.yaml | 2 +- test/runtests.jl | 48 ---------------------------------- 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index d67aded..d796997 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -26,7 +26,7 @@ jobs: - '1' os: - ubuntu-latest - - macos-latest + - macOS-latest - windows-latest arch: - x64 diff --git a/test/runtests.jl b/test/runtests.jl index b61d857..8f678b2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -44,40 +44,6 @@ if rsmd == "FALSE" println() end - # Identify files in test/ that are testing matching files in ext/ - # - ext/SourceExt.jl will be matched by test/ext_SourceExt.jl - filebase = String[] - for (root, dirs, files) in walkdir("../ext") - append!(filebase, - map(file -> replace(file, r"(.*).jl" => s"\1"), - filter(file -> occursin(r".*\.jl", file), files))) - end - - extbase = map(file -> replace(file, r"ext_(.*).jl" => s"\1"), - filter(str -> occursin(r"^ext_.*\.jl$", str), readdir())) - - # Identify tests with no matching file - superfluous = filter(f -> f ∉ filebase, extbase) - if length(superfluous) > 0 - println() - @info "Potentially superfluous extension tests:" - for f in superfluous - println(" + $f.jl") - end - println() - end - - # Identify files with no matching test - notest = filter(f -> f ∉ extbase, filebase) - if length(notest) > 0 - println() - @info "Potentially missing extension tests:" - for f in notest - println(" - $f.jl") - end - println() - end - # Seed RNG to make tests reproducible Random.seed!(1234) @@ -96,20 +62,6 @@ if rsmd == "FALSE" println(" * Testing $t.jl ...") include(fn) end - - println() - @info "Running tests for extensions:" - for t in extbase - println(" = $t.jl") - end - println() - - @info "Running extension tests..." - @testset for t in extbase - fn = "ext_$t.jl" - println(" * Testing $t.jl extension...") - include(fn) - end end # Identify files that are cross-validating results against other packages From 52342365e376890b2bfe738c7693b45dcd919d6c Mon Sep 17 00:00:00 2001 From: richardreeve Date: Sun, 21 Jul 2024 21:29:44 +0100 Subject: [PATCH 08/10] Fix testing exclusions --- .github/workflows/testing.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index d796997..5ee0a2e 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -33,9 +33,10 @@ jobs: - arm64 exclude: - os: macOS-latest - julia-version: - - '1.6' - - '1.8' + julia-version: '1.6' + arch: arm64 + - os: macOS-latest + julia-version: '1.8' arch: arm64 - os: macOS-latest julia-version: '1' From 50b86e99b942a8f3aa225d3dbb46947667b58ddc Mon Sep 17 00:00:00 2001 From: richardreeve Date: Sun, 21 Jul 2024 21:35:33 +0100 Subject: [PATCH 09/10] Correct branch to test --- .github/workflows/CompatHelper.yaml | 2 +- .github/workflows/metadata.yaml | 2 +- .github/workflows/testing.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CompatHelper.yaml b/.github/workflows/CompatHelper.yaml index 38bb3d7..5053ff7 100644 --- a/.github/workflows/CompatHelper.yaml +++ b/.github/workflows/CompatHelper.yaml @@ -3,7 +3,7 @@ name: CompatHelper on: push: branches: - - dev + - main schedule: - cron: '0 4 * * *' # Daily at 4 AM diff --git a/.github/workflows/metadata.yaml b/.github/workflows/metadata.yaml index bb04ef1..ffb064e 100644 --- a/.github/workflows/metadata.yaml +++ b/.github/workflows/metadata.yaml @@ -3,7 +3,7 @@ name: Metadata and hygene on: push: branches: - - dev + - main tags: - 'v*' pull_request: diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 5ee0a2e..03a28ba 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -3,7 +3,7 @@ name: CI on: push: branches: - - dev + - main tags: - 'v*' pull_request: From a30cfd906cee386e9300896adb23c80b56ba9655 Mon Sep 17 00:00:00 2001 From: richardreeve Date: Mon, 22 Jul 2024 19:50:05 +0100 Subject: [PATCH 10/10] Fixes to Kevin's details --- .zenodo.json | 14 ++++++++++---- Project.toml | 5 ++++- codemeta.json | 26 ++++++++++++++++++++------ src/Interface.jl | 17 +++++++++-------- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index 2789efa..e269ea5 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -2,6 +2,12 @@ "title": "EcoBase.jl", "upload_type": "software", "creators": [ + { + "name": "Borregaard, Michael", + "orcid": "0000-0002-8146-8435", + "affiliation": "University of Copenhagen", + "ror": "035b05819" + }, { "name": "Reeve, Richard", "orcid": "0000-0003-2589-8091", @@ -9,10 +15,10 @@ "ror": "00vtgdb53" }, { - "name": "Borregaard, Michael", - "orcid": "0000-0002-8146-8435", - "affiliation": "University of Copenhagen", - "ror": "035b05819" + "name": "Bonham, Kevin", + "orcid": "0000-0003-3200-7533", + "affiliation": "Wellesley College", + "ror": "01srpnj69" } ], "access_right": "open", diff --git a/Project.toml b/Project.toml index a9d78c2..e9ade11 100644 --- a/Project.toml +++ b/Project.toml @@ -35,7 +35,10 @@ orcid = "0000-0003-2589-8091" ror = "00vtgdb53" [[author_details]] name = "Kevin Bonham" -email = "kbonham@wellesley.edu" +orcid = "0000-0003-3200-7533" + + [[author_details.affiliation]] + ror = "01srpnj69" [extras] Diversity = "d3d5718d-52de-57ab-b67a-eca7fd6175a4" diff --git a/codemeta.json b/codemeta.json index f71806e..580814f 100644 --- a/codemeta.json +++ b/codemeta.json @@ -16,11 +16,24 @@ "macOS" ], "version": "v0.1.7", - "dateModified": "2024-07-21", + "dateModified": "2024-07-22", "datePublished": "2018-09-20", "downloadUrl": "https://github.com/EcoJulia/EcoBase.jl/archive/refs/tags/v0.1.7.tar.gz", "license": "https://spdx.org/licenses/MIT", "author": [ + { + "type": "Person", + "givenName": "Michael", + "familyName": "Borregaard", + "id": "https://orcid.org/0000-0002-8146-8435", + "affiliation": [ + { + "type": "Organization", + "name": "University of Copenhagen", + "identifier": "https://ror.org/035b05819" + } + ] + }, { "type": "Person", "givenName": "Richard", @@ -37,14 +50,15 @@ }, { "type": "Person", - "givenName": "Michael", - "familyName": "Borregaard", - "id": "https://orcid.org/0000-0002-8146-8435", + "givenName": "Kevin", + "familyName": "Bonham", + "email": "kbonham@wellesley.edu", + "id": "https://orcid.org/0000-0003-3200-7533", "affiliation": [ { "type": "Organization", - "name": "University of Copenhagen", - "identifier": "https://ror.org/035b05819" + "name": "Wellesley College", + "identifier": "https://ror.org/01srpnj69" } ] } diff --git a/src/Interface.jl b/src/Interface.jl index aef56cf..e6b99d9 100644 --- a/src/Interface.jl +++ b/src/Interface.jl @@ -53,10 +53,10 @@ colsum(x) = sum(x, dims = 1) rowsum(x) = sum(x, dims = 2) occurring(asm::AbstractAssemblage) = occurring(occurrences(asm)) -occurring(a::AbstractMatrix) = nzrows(a) function occurring(asm::AbstractAssemblage, idx) return occurring(occurrences(asm), asindices(idx, placenames(asm))) end +occurring(a::AbstractMatrix) = nzrows(a) occupied(asm::AbstractAssemblage) = occupied(occurrences(asm)) function occupied(asm::AbstractAssemblage, idx) @@ -114,15 +114,16 @@ function show(io::IO, asm::T) where {T <: AbstractAssemblage} things = thingkindplural(asm) place = titlecase(placekind(asm)) places = placekindplural(asm) - return println(io, - """$T with $(nthings(asm)) $things in $(nplaces(asm)) $places + println(io, + """$T with $(nthings(asm)) $things in $(nplaces(asm)) $places - $thing names: - $(tn) + $thing names: + $(tn) - $place names: - $(pn) - """) + $place names: + $(pn) + """) + return nothing end nplaces(asm::AbstractAssemblage, args...) = nplaces(places(asm), args...)