1# Zigmod Tutorial
2
3This guide will go over the various common workflows done while using Zigmod as well as how its design goals fit into them.
4
5## Initialize a new project
6To get started you'll want to navigate to a new folder and run these commands.
7
8```
9git init
10zigmod init
11```
12
13Zigmod's init wizard will ask you if the current project is an application or a library and setup some initial properties in your `zigmod.yml`. However, if you do plan to have a project that is both a library to be used in other Zig projects and an application itself, don't fret. For Zigmod is able to support both of thses configurations simultaneously.
14
15The wizard will also ask if you'd like it setup any additional metadata files such as `.gitignore` or `LICENSE` for you.
16
17> Ref: See [`zigmod init`](./commands/init.md) for more info.
18
19---
20## Understanding `zigmod.yml`
21
22Running [`zigmod init`](./commands/init.md) will ask if you want to create an application or a library. Based on you answer the resulting `zigmod.yml` file have two types.
23
24### `zigmod.yml` for an application (`id` is omitted)
25
26```yaml
27name: my-package
28license: None
29description: None
30root_dependencies:
31 - src: git https://github.com/jecolon/ziglyph
32```
33
34In this case you can use `@import("ziglyph")` to import the package and use it.
35
36### `zigmod.yml` for a library (`id` is omitted)
37
38```yaml
39name: my-package
40main: src/lib.zig
41license: None
42description: None
43dependencies:
44 - src: git https://github.com/jecolon/ziglyph
45```
46
47Here I assume that you initialized your project with `zig init-exe` or `zig init-lib`, so in your `build.zig` the respective `addExecutable()` or `addStaticLibrary()` call points to `src/main.zig`.
48
49In this case you can `@import("ziglyph")` in `src/lib.zig`, but not in `src/main.zig`. However you can `@import("my-package")` in `src/main.zig`.
50
51> Note: using `zig init-exe` or `zig init-lib` for creating a project does not mean that you have to use `zigmod init` in application or library mode. Creating a `zigmod.yml` file with proper `name` and `main` only makes your package importable by other projects. This is usually not needed with applications, but quite useful in case of libraries; hence the name.
52
53### Zig and Zigmod package handling explained
54
55Zig packages can only `@import` **direct** children. The include tree is something like this:
56
57```
58root
59 A
60 C
61 B
62 D
63 E
64```
65
66`root` can `@import` `A`, `B` and `D`, but `E` can be imported only from `D`. `B` can not import anything. (Everybody can import relative files, this limitation is only for packages.)
67
68In the library `zigmod.yml` example from above, the tree looks like this:
69
70```
71root (src/main.zig)
72 my-package (src/lib.zig)
73 ziglyph (separate package)
74```
75
76`root` is always set in `build.zig` using `addExecutable()` or `addStaticLibrary()` calls.
77
78It is very important to understand, that `my-package` is _below_ `root`, as `name/main` in `zigmod.yml` will create a separate package (it will not be chained to `root`).
79
80If you want to use the dependencies from `root`, then make sure that your `zigmod.yml` lists them under `root_dependencies` instead of `dependencies`.
81
82Note: Using `root_dependencies` and `dependencies` is not mutually exclusive, you can take advantage of using both like Zigmod itself does. Using `dependencies` requires a proper `main` field in your `zigmod.yml`.
83
84## Running `zigmod fetch`
85This command will inspect your `zigmod.yml` and download any new dependencies as well as pulling updates for any ones already download. It will recursively do this for your entire tree until it is full constructed which will culminate in the generation of two output files: `deps.zig` and `zigmod.lock`.
86
87`deps.zig` we will use in the next step integrating with the [Zig Build System](https://ziglang.org/documentation/master/#Zig-Build-System). [Learn more](./deps.zig.md).
88
89`zigmod.lock` is a way to enable [Reproducible builds](https://reproducible-builds.org/) and often used in CI environments. [Learn more](./commands/ci.md).
90
91Add `--no-update` if you do want it to fetch remote updates and only regenerate `deps.zig`.
92
93Alternatively, if you want to download updates exactly as defined by the lockfile, use [`zigmod ci`](./commands/ci.md) instead of `zigmod fetch`.
94
95> Ref: See [`zigmod fetch`](commands/fetch.md) reference for more info.
96
97---
98## Integrating with `build.zig`
99```diff
100 const std = @import("std");
101+const deps = @import("./deps.zig");
102
103 pub fn build(b: *std.build.Builder) void {
104 const target = b.standardTargetOptions(.{});
105
106 const mode = b.standardReleaseOptions();
107
108 const exe = b.addExecutable("hello", "src/main.zig");
109 exe.setTarget(target);
110 exe.setBuildMode(mode);
111+ deps.addAllTo(exe);
112 exe.install();
113```
114
115> Note: If you would like to use the external dependencies in tests, do not forget to add `deps.addAllTo(main_tests)` after the `addTest()` call.
116
117---
118## Adding a dependency
119The core of expandability, it is possible to add dependencies to your project. How exactly, depends on where you're sourcing the information from.
120
121- ZPM
122 - https://zig.pm/ is another supported package index. You may add packages from ZPM with `zigmod zpm add <package>`.
123
124- Other/Git
125 - Zigmod supports adding any Git repository as a dependency. This is done by manually editing your `zigmod.yml` and adding a line under either the `dependencies` or `dev_dependencies` keys. For example, adding a line with this contents would add `apple_pie` to your project: ` - src: git https://github.com/Luukdegram/apple_pie`. The URL field may be any valid Git url that you would pass to `git clone`.
126
127- Other/System Library
128 - System libraries are similar to Git dependencies, but instead of `git <url>` it is `system_lib <name>`.
129
130- Other/Framework
131 - Frameworks are similar to system libraries but are specific to Darwin (macOS, iOS, etc) and are defined with `framework <name>`.
132
133- Other/HTTP
134 - Http tarballs are also allowed and follow a similar pattern as Git dependencies but use the `http` type. One thing to note is that it is recomended to add a hash verification after your tarball URL so that zigmod may assert whether or not it has been downloaded already to prevent unnecessary trips to the network. Hash verification versions are placed after the URL and in the form `type-string` such as `sha256-8ff0b79fd9118af7a760f1f6a98cac3e69daed325c8f9f0a581ecb62f797fd64`. They may also be placed in their own `version` key instead of `src`. The available hash algorithms are `blake3`, `sha256`, `sha512`.
135
136- Other/Mercurial
137 - Mercurial follows the same rules as Git dependencies and uses the `hg` Dep type.
138
139---
140## Using build-time dependencies in `build.zig`
141Dependencies that are added to `dev_dependencies` will additionally be exposed in `deps.zig` generation under the `imports` namesapce. https://github.com/Snektron/vulkan-zig is a common example of a package that can be used with Zigmod as a build-time dependency.
142
143```zig
144const deps = @import("./deps.zig");
145const vkgen = deps.imports.vulkan_zig;
146
147pub fn build(b: *Builder) void {
148
149 const exe = b.addExecutable("my-executable", "src/main.zig");
150
151 const gen = vkgen.VkGenerateStep.init(b, "path/to/vk.xml", "vk.zig");
152
153 exe.addPackage(gen.package);
154}
155```
156
157---
158## Contributing to dependency upstream
159When using Git dependencies, Zigmod streamlines the process of contributing back fixes and improvements to your upstream. This is due to the fact that Zigmod will preserve the `.git` folder when cloning so that you may work with it.
160
161Suppose we have the package https://github.com/octocat/zig-hello.
162
163Zigmod will `git clone` its contents to `.zigmod/deps/git/github.com/octocat/zig-hello`. If we find a bug or want to contribute a new feature we may navigate to this directory, edit any files we choose and make commits.
164
165Then fork the repository on `github.com` or wherever it is hosted and add a local remote so that you have something to push to. `git remote add fork https://github.com/you/zig-hello`.
166
167Then push your local changes with `git push fork master` and create your pull request.
168
169---
170## Using Zigmod in Github Actions
171```yml
172- uses: nektro/actions-setup-zigmod
173```
174
175This will allow your Github Action task to use the various Zigmod commands. `zigmod ci` is recommended for this use case as it is similar to `zigmod fetch` but will fetch the versions only listed in your `zigmod.lock`.
176
177---
178## Auditing your project's licenses
179This can come in handy for users and organizations alike. The `zigmod license` command will show you a list of the licenses involved in a project (deeply) and present them nicely grouping similar licenses together and providing a link to the license test for any projects that use a valid SPDX license identifier.
180
181Given the project https://github.com/kristoff-it/bork, at the time of writing that output would look like the following:
182
183![image](https://user-images.githubusercontent.com/5464072/130309694-180da454-553d-4136-a7ac-0f4f3f5ecf3d.png)
184
185> Ref: See [`zigmod license`](commands/license_.md) reference for more info.
186
187---
188## Verifying dependency integrity
189
190> Ref: See [`zigmod sum`](commands/sum.md) reference for more info.
191
192---
193## Installing online programs to your local machine
194Adding `~/.zigmod/bin` to your `$PATH` enables you to install Zig-written command line utilities to your machine with Zigmod.
195
196> Ref: See [`zigmod install`](commands/install.md) reference for more info.