<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matt Knight</title>
    <description>The latest articles on DEV Community by Matt Knight (@mattnite).</description>
    <link>https://dev.to/mattnite</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F574532%2Fa6f2513c-9757-426e-98bf-e03893e3f65f.jpeg</url>
      <title>DEV Community: Matt Knight</title>
      <link>https://dev.to/mattnite</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mattnite"/>
    <language>en</language>
    <item>
      <title>Weaning Zig off of git submodules 1: Intro</title>
      <dc:creator>Matt Knight</dc:creator>
      <pubDate>Thu, 11 Feb 2021 02:07:46 +0000</pubDate>
      <link>https://dev.to/mattnite/weaning-zig-off-of-git-submodules-1-3jen</link>
      <guid>https://dev.to/mattnite/weaning-zig-off-of-git-submodules-1-3jen</guid>
      <description>&lt;p&gt;&lt;em&gt;Do you or someone close to you indulge in the use of git submodules? please call the GS hotline at 1-(800)-GIT-9418.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is the first in a series of blog posts dedicated to package management for zig. The main purpose is to spark conversation within the community after starting my own package manager, &lt;a href="https://github.com/mattnite/gyro" rel="noopener noreferrer"&gt;gyro&lt;/a&gt;. I'm not advocating for it and it's design decisions to be incorporated into the official PM, merely using it to explore the solution space.&lt;/p&gt;

&lt;p&gt;Package management is an interesting challenge full of technical and human obstacles. In each of these posts I'd like to mostly focus on one topic at a time, as I write them I'll link them below this paragraph. Despite the title of this series, I actually don't mind git submodules as a developer, but as a human I'd like to minimize the amount of suffering in the world.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Versioning&lt;/li&gt;
&lt;li&gt;Distribution&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Build Dependencies&lt;/li&gt;
&lt;li&gt;UX&lt;/li&gt;
&lt;li&gt;C packaging&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;code&gt;@import()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;The import builtin is how you use code from outside your file. A string literal is given as an argument and this is either a relative path to another file or an arbitrary string configured to represent a package. An important detail here is that the path case cannot reach above the root file, so let's say we have the following filesystem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;map.zig
src/
    main.zig
    bar.zig
    parser/
        http.zig
foo/
    blarg.zig
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your root file was &lt;code&gt;src/main.zig&lt;/code&gt;, it could not import &lt;code&gt;map.zig&lt;/code&gt; or &lt;code&gt;foo/blarg.zig&lt;/code&gt;, but &lt;code&gt;src/parser/http.zig&lt;/code&gt; could import &lt;code&gt;src/bar.zig&lt;/code&gt; by doing &lt;code&gt;@import("../bar.zig")&lt;/code&gt; because these are within the root's directory.&lt;/p&gt;

&lt;p&gt;The special case for package strings that you're familiar with is "std" which the compiler configures for you automatically. Some examples of imports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight zig"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;@import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;            &lt;span class="c"&gt;// absolute classic&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;@import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dir/module.zig"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;// import another file&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;bad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;@import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"../bad.zig"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c"&gt;// not allowed&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;pkg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;@import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my_pkg"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c"&gt;// package import&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The other major detail here is that &lt;code&gt;@import()&lt;/code&gt; returns a type -- I like to visualize&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight zig"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;mine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;@import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my_file.zig"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight zig"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;mine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// contents of my_file.zig:&lt;/span&gt;
    &lt;span class="c"&gt;// pub const Int = usize;&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now you can access &lt;code&gt;Int&lt;/code&gt; via &lt;code&gt;mine.Int&lt;/code&gt;. This is leads to a cool pattern where a file cleanly exports a struct by simply declaring members of a struct  in the root of a file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight zig"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Mine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// contents of MyFile.zig:&lt;/span&gt;
    &lt;span class="c"&gt;// data: []const u8,&lt;/span&gt;
    &lt;span class="c"&gt;// num: usize,&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The convention here is to use CapitalCase for the filename.&lt;/p&gt;

&lt;h1&gt;
  
  
  Packages
&lt;/h1&gt;

&lt;p&gt;Packages are ultimately communicated to the zig compiler as command line arguments, I will leave it to the reader to research &lt;code&gt;--pkg-begin&lt;/code&gt; and &lt;code&gt;--pkg-end&lt;/code&gt; on their own. Instead I'll demonstrate what manual package configuration in &lt;code&gt;build.zig&lt;/code&gt; looks like -- at the end of the day, this work is done for you by the package manager.&lt;/p&gt;

&lt;p&gt;Every package is made up of one or more files, with one of them being the root. All these files are connected through file imports, and any package imports refer to the root file of another package. In the following figure we have package A and B, made up of (&lt;code&gt;src/main.zig&lt;/code&gt;, &lt;code&gt;src/file.zig&lt;/code&gt;) and (&lt;code&gt;root.zig&lt;/code&gt;, &lt;code&gt;src/foo.zig&lt;/code&gt;, &lt;code&gt;src/bar.zig&lt;/code&gt;) respectively, and the files in package A import B. Package imports are bold arrows with a label corresponding to the string used in &lt;code&gt;@import()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5x6o03j6yxe53dqk85el.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5x6o03j6yxe53dqk85el.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we wanted to use package A in a program we wrote, we would have the following in our &lt;code&gt;build.zig&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight zig"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;@import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;build&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Pkg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;build&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Pkg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;pkg_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pkg&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/some/path/to/src/main.zig"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;_&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;Pkg&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Pkg&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"rel/path/to/root.zig"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;exe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addExecutable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my_program"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"src/main.zig"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPackage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pkg_a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So in order to use A, you need to tell it where to find "b", and this is nice because it is trivial to drop a different implementation of package B. The configuration for "b" only counts inside files belonging to package A, we will not be able to import package B in our program, to do that we would need to explicitly configure that relationship with another call to &lt;code&gt;addPackage()&lt;/code&gt;. Each package has its own import namespace and this allows for situations where different packages import the same code using different import strings:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzzu7t60howtgfpl6c7h0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzzu7t60howtgfpl6c7h0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and it allows for different packages to be referenced with the same string:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh2qq6p5v80jnvkk4dabz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh2qq6p5v80jnvkk4dabz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This makes for a simple and consistent medium in which to perform package management, where package resolution, replacement, and upgrading challenges are more about user experience rather than technical feasibility.&lt;/p&gt;

&lt;p&gt;That concludes this tutorial on the import system. The next post I'll make will be on versioning and some of the initial design decisions of gyro.&lt;/p&gt;

</description>
      <category>zig</category>
    </item>
  </channel>
</rss>
