Introduction
One of the most frustrating experiences with Julia is that many tutorials you find online don’t work any more because the language has changed so much. Creating a new package is one of the most fundamental tasks to a language, but it took me quite a while to figure that out. In the end, I managed to submit Getopt to Julia’s central registry. It implements a Python-like getopt in 70 lines, much shorter than ArgParse.jl.
This blog post explains what I have learned in this process. Here, a line starting with “sh>” indicates a shell command line, “julia>” denotes the Julia REPL and “pkg>” denotes the pkg mode, which can be entered by typing “]” in REPL.
Creating a package
To create a package repository, you may:
sh> julia -e 'using Pkg; Pkg.generate("Foo")' # or in the pkg mode sh> mv Foo Foo.jl sh> cd Foo.jl
The first command line creates a “Foo” directory, a “Foo/src/Foo.jl” file and a “Project.toml” file. We renamed this directory to “Foo.jl” because this is the convention. In the “Foo.jl” directory, you can add dependencies with
(v1.0) pkg> activate . # enter virtual environment (Foo) pkg> add Test # module for unit tests sh> rm Manifest.toml # we don't need this sh> echo 'julia 1.0' > REQUIRE # but we need this sh> mkdir -p test && touch test/runtests.jl # tests go here
This updates the “[deps]” section of “Project.toml”. You probably need the “Test” package because apparently without it, you can’t run tests for your new package. Now, you can edit “Foo.jl/src/Foo.jl” to write the actual library code. Remember to read the documentation on Modules.
Deploying the package
You can’t import “Foo” yet because your new package is not added to your local registry. In the “Foo.jl” directory, you have to run the following first
(v1.0) pkg> dev .
It is always a good idea to write tests. To do that, edit “test/runtests.jl” following the tutorial on Unit Test. My Getopt.jl test is here. It is not a good example but may give you a basic idea. Tests can be run with
(v1.0) pkg> test Foo
Registering the package
After you push “Foo.jl” to github, others can install your package with
sh> julia -e 'using Pkg; Pkg.add("https://github.com/your/Foo.jl")'
They can’t install with the package name because it is not in Julia’s central registry yet. To register your package, you’d better use attobot, a GitHub App that automatically sends pull requests to METADATA.jl. For a new package, it asks you to wait for three days. Someone else (I guess a human) will merge the PR, which will be automatically synchronized to the Julia registry after several hours. At this point, the world will be able to install your package with
sh> julia -e 'using Pkg; Pkg.add("Foo")'
Your package won’t be found in the Julia package list because that page is outdated. Julia doesn’t have built-in package search. The best place to discover packages seems Julia Observer. It has issues, too. For example, it doesn’t tell you which Julia versions a package supports. It is very slow.
Concluding remarks
Getopt is the first package I developed in Julia. The workflow described here might not be optimal. I will update this post once I learn a better solution.
It is possible to set test-specific dependencies, and not having to make `Test` a package dependency if `Test` isn’t needed for anything other than testing the package. Documentation can be found [here](https://julialang.github.io/Pkg.jl/v1.0/index.html#Test-specific-dependencies-1).