Make a package
Why make a package ?
- Share your code and maintain it.
- Better source files organization.
- Improve your programming practices by making tests.
- Continuous integration.
- Documentation is hosted and generated after every changes.
Configure git
Git configuration is used to set the package author.
git config --global user.name "Pierre Navaro"
git config --global user.email "pierre.navaro@math.cnrs.fr"
git config --global github.user "pnavaro"
Install some useful packages
- Revise.jl: Automatically update function definitions in a running Julia session. This package is mandatory if you want to develop a package. It is better to ensure that every Julia session uses it.
mkdir -p ~/.julia/config/ && echo "using Revise" >> ~/.julia/config/startup.jl
- Documenter.jl: Documentation generator.
- DocumenterTools.jl : Extra tools for setting up Documenter.
- DocStringExtensions.jl: Extensions for Julia’s docsystem.
- JuliaFormatter.jl: code formatter for Julia.
- CompatHelperLocal.jl : Help for
[compat]
entries - Aqua.jl: Auto QUality Assurance for Julia packages.
- JET.jl : code analyzer for Julia.
Create the Julia package Temperature
.0) pkg> generate Temperature
(v1:
Generating project Temperature/Project.toml
Temeperatures/src/Temperature.jl Temeperatures
> cat Temperature/Project.toml
shell= ["Pierre Navaro <pierre.navaro@math.cnrs.fr>"]
authors = "Temperature"
name = "417a5b38-18da-11e9-35ce-9bdc85ad86c9"
uuid = "0.1.0"
version
[deps]
Activate your package
.0) pkg> activate . (v1
Add dependencies
> add DocStringExtensions (Temperature) pkg
The package name is added in the [deps]
section in the Project.toml
file.
A new file named Manifest.toml is also created and allows someone to replicate the exact version of the dependencies that was recorded in the manifest on e.g. another machine. For a package that is to be used as a library, this is not useful.
However, for an “application”, i.e. something at “top level” (say your julia code to do the simulations in a scientific paper) then it is likely useful to be able to replicate that exact state and the Manifest is thus useful to check in.
Add a test
cd Temperature
mkdir test
create file runtests.jl
> cat test/runtests.jl
shellusing Temperature
using Test
@testset "convert Celsius to Fahrenheit" begin
@test fahrenheit(0.0) == 32.0
end
Implement the fahrenheit function in src/Temperature.jl
"""
$(SIGNATURES)
convert temperature in Celsius degrees to Fahrenheit.
"""
fahrenheit(t) = t * 9 / 5 + 32
The macro SIGNATURES
provided by DocStringExtensions
package synchronizes the function signature in the documentation to its implementation.
Verify the test
> test
(Temperature) pkg
Testing Temperature...
Resolving package versionsTest Summary: | Pass Total
Test convert Celsius to Fahrenheit | 1 1
Testing Temperature tests passed
The Test
package must be added to the dependencies…
Check the documentation
> using Temperature
julia
> fahrenheit help?
Exercises :
- Add a new test for
fahrenheit(20)
- Launch tests
- Implement two tests for the inverse function named celsius
- Implement the function
- Launch tests
Documentation
Create your documentation draft with DocumenterTools
> using DocumenterTools
julia> pwd
shell/Users/navaro/JuliaProjects/Temperature
> DocumenterTools.generate("docs")
julia: name of package automatically determined to be `Temperature`.
[ Info: deploying documentation to `~/JuliaProjects/Temperature/docs`
[ Info: Generating .gitignore at /Users/navaro/JuliaProjects/Temperature/docs/.gitignore
[ Info: Generating make.jl at /Users/navaro/JuliaProjects/Temperature/docs/make.jl
[ Info: Generating Project.toml at /Users/navaro/JuliaProjects/Temperature/docs/Project.toml
[ Info: Generating src/index.md at /Users/navaro/JuliaProjects/Temperature/docs/src/index.md [ Info
> cat docs/src/index.md
shell# Temperature.jl
for Temperature.jl
Documentation
## Types and Functions
```@autodocs
Modules = [Temperature]
Order = [:type, :function]
```
> cat docs/make.jl
shell
using Documenter
using Temperature
using Plots
ENV["GKSwstype"] = "100" # Avoid issues with display when generating documentation
makedocs(modules=[Temperature],
= false,
doctest = Documenter.HTML(),
format = "Temperature.jl",
sitename = ["Documentation" => "index.md"])
pages
deploydocs(
= "github.com/pnavaro/Temperature.jl.git"
repo )
Is is possible to add BibTeX citations and references in documentation pages with DocumenterCitations.jl.
Add a repository on Github
https://github.com/pnavaro/Temperature.jl
- Note : the repository name has the “.jl” extension
$ echo "# Temperature.jl" >> README.md
$ git init
Initialized empty Git repository in /Users/navaro/JuliaProjects/Temperature/.git/
$ git add .
$ git commit -m "first commit"
[main (root-commit) 8863c2e] first commit
11 files changed, 287 insertions(+)
create mode 100644 Manifest.toml
create mode 100644 Project.toml
create mode 100644 README.md
create mode 100644 docs/.gitignore
create mode 100644 docs/Project.toml
create mode 100644 docs/make.jl
create mode 100644 docs/src/index.md
create mode 100644 src/Temperature.jl
create mode 100644 test/runtests.jl
$ git remote add origin git@github.com:pnavaro/Temperature.jl.git
$ git push -u origin main
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 8 threads
Compressing objects: 100% (13/13), done.
Writing objects: 100% (17/17), 4.29 KiB | 2.15 MiB/s, done.
Total 17 (delta 0), reused 0 (delta 0)
To github.com:pnavaro/Temperature.jl.git
* [new branch] main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.
Ignore some files
$ cat .gitignore
*.jl.cov
*.jl.*.cov
*.jl.mem
docs/build/
docs/site/
Manifest.toml
Install first version of Example package in your julia installation
(v1.1) pkg> add https://github.com/pnavaro/Temperature.jl.git
Updating registry at `~/.julia/registries/General`
Updating git-repo `https://github.com/JuliaRegistries/General.git`
Cloning git-repo `https://github.com/pnavaro/Temperature.jl.git`
Updating git-repo `https://github.com/pnavaro/Temperature.jl.git`
Resolving package versions...
Updating `~/.julia/environments/v1.1/Project.toml`
[417a5b38] ~ Temperature v0.1.0 [`~/JuliaProjects/Temperature`] ⇒ v0.1.0 #main (https://github.com/pnavaro/Temperature.jl.git)
Updating `~/.julia/environments/v1.1/Manifest.toml`
[417a5b38] ~ Temperature v0.1.0 [`~/JuliaProjects/Temperature`] ⇒ v0.1.0 #main (https://github.com/pnavaro/Temperature.jl.git`
Test it
(v1.1) pkg> test Temperature
Testing Temperature
Test Summary: | Pass Total
Test Fahrenheit function | 1 1
Testing Temperature tests passed
Push the package on github
cd Temperature
echo "# Temperature.jl" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:pnavaro/Temperature.jl.git
git push -u origin main
On Github choose your license
Above the file list, click Create new file.
In the file name field, type LICENSE (with all caps).
- Choose a license template button.
- Click Choose a license template.
- Add a license to your project.
- Don’t create pull request choose “main” branch.
On your computer
git pull origin main
Codecov
Add your repository by going to https://codecov.io/gh
language: julia
os:
- linux
- osx
julia:
- 1.0
- nightly
notifications:
email: true
after_success:
- julia -e 'using Pkg; cd(Pkg.dir("Temperature")); Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())'
jobs:
include:
- stage: "Documentation"
julia: 1.0
os: linux
script:
- julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
- julia --project=docs/ docs/make.jl
name: "HTML"
after_success: skip
Hosting your documentation on Github pages
Launch julia in your package directory.
pkg> add DocumenterTools
pkg> activate .
julia> using DocumenterTools
julia> using Temperature
julia> DocumenterTools.genkeys(Temperature)
Follow the instructions that are printed out
- Add the public ssh key to your settings page for the GitHub repository.
- Don’t forget to check
Allow write access
to allow Documenter to commit the generated documentation to the repo.
Enable GitHub Pages
- On GitHub, navigate to your GitHub Pages site’s repository.
- Under your repository name, click Settings.
- Use the Select source drop-down menu to select main or gh-pages as your GitHub Pages publishing source.
- Click Save.
By default Documenter will create a link called dev
that points to the latest version
https://pnavaro.github.io/Temperature.jl/dev
Badges
It is common practice to make use of “badges” for build status, code coverage and documentation. Adding the following to your package README.md
should be all that is necessary:
- Codecov badge : https://codecov.io/gh/pnavaro/Temperature.jl/settings/badge
[]
[](https://codecov.io/gh/pnavaro/Temperature.jl)
[](https://pnavaro.github.io/Temperature.jl/stable)
[](https://pnavaro.github.io/Temperature.jl/dev)
Register your package
- Set up AttoBot on your repository.
- You need to tag your verson with git (for example v0.1.0)
- Use Github releases.
- Wait a couple of days.
I did not do it for Temperature
Items not covered
- Binary package PackageCompiler.jl
- Mixed language BinDeps.jl
- Create a pdf with Documenter
- Literate.jl : create markdown file and/or jupyter notebook from a julia program. Easy way to create your examples and tutorials.
Bonus
To set your documentation logo, just add a image file named logo.png in docs/src/assets directory.
Its size must be 100 x 100 pixels.
You can modify the julia logo images available on JuliaGraphics
The package Luxor.jl is a good tool to create a logo.
Links
- Pkg.jl
- Automate your Code Quality in Julia
- JuliaTemplateRepo
- Julia Observer
- Simplifying working with Julia packages and dependencies
- Creating a new package in Julia
- Documenter
- Revise.jl Automatically update function definitions in a running Julia session.
- Julia Actions GitHub actions for Julia.
- Example.jl Example Julia package repo.