diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5ace460..700707c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "github-actions" - directory: "/" + directory: "/" # Location of package manifests schedule: interval: "weekly" diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..80859d3 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,45 @@ +name: CI +on: + push: + branches: + - main + tags: ['*'] + pull_request: + workflow_dispatch: +concurrency: + # Skip intermediate builds: always. + # Cancel intermediate builds: only if it is a pull request build. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + permissions: # needed to allow julia-actions/cache to proactively delete old caches that it has created + actions: write + contents: read + strategy: + fail-fast: false + matrix: + version: + - '1.10' + - '1.6' + os: + - ubuntu-latest + arch: + - x64 + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: julia-actions/cache@v1 + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml new file mode 100644 index 0000000..cba9134 --- /dev/null +++ b/.github/workflows/CompatHelper.yml @@ -0,0 +1,16 @@ +name: CompatHelper +on: + schedule: + - cron: 0 0 * * * + workflow_dispatch: +jobs: + CompatHelper: + runs-on: ubuntu-latest + steps: + - name: Pkg.add("CompatHelper") + run: julia -e 'using Pkg; Pkg.add("CompatHelper")' + - name: CompatHelper.main() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} + run: julia -e 'using CompatHelper; CompatHelper.main()' diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml new file mode 100644 index 0000000..0cd3114 --- /dev/null +++ b/.github/workflows/TagBot.yml @@ -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/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 2ffbad3..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: CI - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - - test: - runs-on: ${{ matrix.os }} - strategy: - matrix: - version: ['1', 'nightly'] - arch: [x64, x86] - os: [ubuntu-latest, windows-latest, macOS-latest] - exclude: - # MacOS not available on x86 - - os: macOS-latest - arch: x86 - steps: - - uses: actions/checkout@v4 - - uses: julia-actions/setup-julia@v1 - with: - version: ${{ matrix.version }} - arch: ${{ matrix.arch }} - - uses: julia-actions/julia-buildpkg@v1 - - uses: julia-actions/julia-runtest@v1 - - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v3 - with: - files: lcov.info diff --git a/Project.toml b/Project.toml index d3b9a52..c1678fe 100644 --- a/Project.toml +++ b/Project.toml @@ -3,5 +3,20 @@ uuid = "13e0c4e3-fd7a-51bf-9e22-ec7679f18909" authors = ["Daniel Matz "] version = "0.2.0" +[deps] +Requires = "ae029012-a4dd-5104-9daa-d747884805df" + +[weakdeps] +Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" +Requires = "ae029012-a4dd-5104-9daa-d747884805df" + +[extras] +Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[extensions] +UnitfulExt = ["Unitful"] + [compat] -julia = "1" +Unitful = "1" +julia = "1.2" +Requires = "1" diff --git a/README.md b/README.md index b65bbd1..70efaa8 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ geometric altitude `z`, where `z` has units of m. The atmospheric state object that is returned has the following accessors: - `altitude`, which returns the altitude in m -- `density`, which returns the density in units of kg/m² +- `density`, which returns the density in units of kg/m³ - `pressure`, which returns the pressure in units of Pa - `temperature`, which returns the temperature in units of K - `speed_of_sound`, which returns the speed of sound in units of m/s diff --git a/ext/UnitfulExt.jl b/ext/UnitfulExt.jl new file mode 100644 index 0000000..3286a3d --- /dev/null +++ b/ext/UnitfulExt.jl @@ -0,0 +1,34 @@ +module UnitfulExt + +import COESA: + COESA, + atmosphere, + altitude, + mean_molecular_weight, + temperature, + pressure, + density, + speed_of_sound, + dynamic_viscosity + +isdefined(Base, :get_extension) ? (using Unitful) : (using ..Unitful) + +struct UnitfulState + state::COESA.State +end + +altitude(s::UnitfulState) = altitude(s.state) * u"m" +mean_molecular_weight(s::UnitfulState) = mean_molecular_weight(s.state) * u"kg/kmol" +temperature(s::UnitfulState) = temperature(s.state) * u"K" +pressure(s::UnitfulState) = pressure(s.state) * u"Pa" +density(s::UnitfulState) = density(s.state) * u"kg/m^3" +speed_of_sound(s::UnitfulState) = speed_of_sound(s.state) * u"m/s" +dynamic_viscosity(s::UnitfulState) = dynamic_viscosity(s.state) * u"N*s/m^2" + +function atmosphere(Z::Quantity) + Z′ = ustrip(u"m", Z) + state = atmosphere(Z′) + UnitfulState(state) +end + +end diff --git a/src/COESA.jl b/src/COESA.jl index 98c59bb..39c115f 100644 --- a/src/COESA.jl +++ b/src/COESA.jl @@ -1,5 +1,16 @@ module COESA +# Support package extensions on Julia < 1.9 +if !isdefined(Base, :get_extension) + using Requires +end + +@static if !isdefined(Base, :get_extension) + function __init__() + @require Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" include("../ext/UnitfulExt.jl") + end +end + export atmosphere, altitude, diff --git a/test/Project.toml b/test/Project.toml index 737dfda..1368296 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -2,3 +2,4 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" diff --git a/test/runtests.jl b/test/runtests.jl index 67b8c62..c4bcbfe 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,10 @@ using COESA using Test -using Aqua -using JET +import Aqua +import JET +using Unitful + +quantity_type(T, units) = Quantity{T, dimension(units), typeof(units)} M0 = COESA.M0 @@ -239,12 +242,26 @@ M0 = COESA.M0 @test_throws ErrorException dynamic_viscosity(atmos) end + @testset "Unitful Extension" begin + atmos = atmosphere(0u"m") + @test altitude(atmos) == 0u"m" + @test round(quantity_type(Float64, u"kg/kmol"), mean_molecular_weight(atmos), sigdigits = 5) == 28.964u"kg/kmol" + @test round(quantity_type(Float64, u"K"), temperature(atmos), sigdigits = 6) == 288.150u"K" + @test round(quantity_type(Float64, u"Pa"), pressure(atmos), sigdigits = 6) == 101325u"Pa" + @test round(quantity_type(Float64, u"kg/m^3"), density(atmos), sigdigits = 5) == 1.2250u"kg/m^3" + @test round(quantity_type(Float64, u"m/s"), speed_of_sound(atmos), sigdigits = 5) == 340.29u"m/s" + @test round(quantity_type(Float64, u"N*s/m^2"), dynamic_viscosity(atmos), sigdigits = 5) == 1.7894e-5u"N*s/m^2" + end + @testset "Code Quality" begin @testset "Aqua" begin - Aqua.test_all(COESA, project_extras = false) + Aqua.test_all(COESA) end @testset "JET" begin - test_package("COESA") + # JET doesn't export `test_package` for older versions + if isdefined(JET, :test_package) + JET.test_package("COESA") + end end end