{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Notes on Starting a New, Modular Analysis (Project) in Julia\n", "\n", "The `cookiecutter` equivalent for Julia is `PkgTemplates` ([github link](https://github.com/invenia/PkgTemplates.jl)), but you can do a ton with the base `Pkg` library. As someone who really like `kedro` for python ([kedro docs](https://kedro.readthedocs.io/en/stable/)), I really want to know the best methods of creating a modular, reproducible analysis using Julia. \n", "\n", "Here's the steps I need to understand:\n", "\n", "* Navigating folders\n", "* Create a barebones project structure\n", "* Create a new environment for your project\n", "* Importing local modules" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a New Environment for Your Project\n", "\n", "Surprisingly, the best documentation for setting up your project exists in the `Pkg` [Getting Started With Environments documentation](https://pkgdocs.julialang.org/v1/getting-started/#Getting-Started-with-Environments) itself. \n", "\n", "Instead of creating new environments from the command line with `conda`, `venv`, `pyenv`, `poetry`, etc etc you can do it through the Julia REPL or calling the `Pkg` library within your script." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Key Terms:\n", "\n", "* `Pkg.status()` : See what environment you're using\n", "* `Pkg.activate()` : Activate environment\n", "* `Pkg.generate()` : Generates \n", "* `Pkg.instantiate()` : \n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[32m\u001b[1m Status\u001b[22m\u001b[39m `~/.julia/environments/v1.6/Project.toml`\n", " \u001b[90m [336ed68f] \u001b[39mCSV v0.9.11\n", " \u001b[90m [8f4d0f93] \u001b[39mConda v1.5.2\n", " \u001b[90m [a93c6f00] \u001b[39mDataFrames v1.2.2\n", " \u001b[90m [1313f7d8] \u001b[39mDataFramesMeta v0.10.0\n", " \u001b[90m [c91e804a] \u001b[39mGadfly v1.3.4\n", " \u001b[90m [cd3eb016] \u001b[39mHTTP v0.9.17\n", " \u001b[90m [7073ff75] \u001b[39mIJulia v1.23.2\n", " \u001b[90m [91a5bcdd] \u001b[39mPlots v1.24.2\n", " \u001b[90m [c3e4b0f8] \u001b[39mPluto v0.17.2\n", " \u001b[90m [438e738f] \u001b[39mPyCall v1.92.5\n", " \u001b[90m [6f49c342] \u001b[39mRCall v0.13.12\n", " \u001b[90m [ce6b1742] \u001b[39mRDatasets v0.7.6\n", " \u001b[90m [fdbf4ff8] \u001b[39mXLSX v0.7.8\n" ] } ], "source": [ "using Pkg;\n", "Pkg.status()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Navigating the directory structure with functions\n", "\n", "* `pwd` - prints the current working directory\n", "* `readdir` - just like `ls` in bash, lists files in the current directory\n", "* `mkdir` - makes a new directory\n", "* `rm(path, recursive=true)` - recursively remove a directory " ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2-element Vector{String}:\n", " \".ipynb_checkpoints\"\n", " \"A Julia Workflow.ipynb\"" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "readdir()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generate a new project structure with `Pkg.generate`\n", "\n", "Julia gives us a barebones package generator with `generate` that will make a `Project.toml` config file and a `src` directory with a 'hello world' julia file in it. " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\u001b[32m\u001b[1m Generating\u001b[22m\u001b[39m project my_package:\n", " my_package/Project.toml\n", " my_package/src/my_package.jl\n" ] }, { "data": { "text/plain": [ "Dict{String, Base.UUID} with 1 entry:\n", " \"my_package\" => UUID(\"a2f78104-38a4-4b74-bda0-0fd91114a85c\")" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Pkg.generate(\"my_package\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See the directory structure of `my_package`:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2-element Vector{String}:\n", " \"Project.toml\"\n", " \"src\"" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "readdir(\"my_package\")" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1-element Vector{String}:\n", " \"my_package.jl\"" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "readdir(\"my_package/src\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Activate the new package after creating the strawman using `Pkg.generate`:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\u001b[32m\u001b[1m Activating\u001b[22m\u001b[39m environment at `~/Desktop/jul_test/workflow/my_package/Project.toml`\n" ] } ], "source": [ "Pkg.activate(\"my_package\")\n", "Pkg.status()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also open a REPL using your project by navigating to the `my_package` directory and calling something like:\n", "\n", "```bash\n", "# bash\n", "julia --project=. # the '.' says to open julia using the environment in the current directory\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And finally, if you open a jupyter notebook in the `my_package` directory, it should use the directory's Julia environment by default." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading someone else's project\n", "\n", "Loading someone else's project after you've activated it, use `instantiate`:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n", "\u001b[32m ✓ \u001b[39mmy_package\n", " 1 dependency successfully precompiled in 1 seconds\n" ] } ], "source": [ "Pkg.instantiate()" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[36m\u001b[1m Project\u001b[22m\u001b[39m my_package v0.1.0\n", "\u001b[32m\u001b[1m Status\u001b[22m\u001b[39m `~/Desktop/jul_test/workflow/my_package/Project.toml` (empty project)\n" ] } ], "source": [ "Pkg.status()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Import your package" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "using my_package" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And call the single function in the package" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello World!" ] } ], "source": [ "my_package.greet()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Recap: Key functions in `Pkg`\n", "\n", "* `generate` : Create a new, barebones julia package structure\n", "* `activate` : Activates a julia environment (or creates one if it doesn't already exist)\n", "* `instantiate` : Install the package and required dependencies" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Bonus: Delete the directory" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "rm(\"my_package\", recursive=true)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2-element Vector{String}:\n", " \".ipynb_checkpoints\"\n", " \"A Julia Workflow.ipynb\"" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "readdir()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.7.0", "language": "julia", "name": "julia-1.7" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.7.0" } }, "nbformat": 4, "nbformat_minor": 4 }