How to use local go modules with golang with examples

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@howo·
0.000 HBD
How to use local go modules with golang with examples
<img src="https://res.cloudinary.com/cpress/image/upload/w_1280,e_sharpen:60/rp1osul9qflgxvec52fo.jpg" alt="Image result for golang modules&quot;"/>
<p>When coding I like to put everything inside of folders depending on what they do. I almost always got specific directories for utils, parser, etc. So here's a complete guide on how to use local go modules with golang </p>
<p> When I started using go modules I was migrating a project from dep which followed this architecture. I had an utils directory, and another directory which handled all parsing for my data input into structs. But then I ended up needing functions from the utils directory.  I was stuck and couldn't find how to make directories importable everywhere in the project (like dep used to). Because relative imports are a nightmare with go modules (removing the gopath has a toll after all).  </p>
<p>So after quite a bit of fuming and searching all of the web for a solution that is elegant and not something like some crazy relative imports, I found this solution and since I struggled so much to find the solution I figured that I would share it with you all.</p>
<h2>The example project</h2>
<p>Here's our example project directory structure : <br> ├── go.mod<br> ├── hello<br> │&nbsp;&nbsp; ├── go.mod<br> │&nbsp;&nbsp; └── hello.go<br> ├── main.go<br> ├── README.md<br> └── utils<br>     ├── go.mod<br>     └── multigreet.go</p>
<p>You can also see the example code on my github repository here : <a href="https://github.com/drov0/GolangLocalModulesExample">https://github.com/drov0/GolangLocalModulesExample</a></p>
<p>The code is relatively straightforward : I have two directories, <strong>hello</strong> and <strong>utils</strong> that I want to import from the <strong>main.go</strong> file. And when things get a little tricky is that I want to import the <strong>hello</strong> directory inside of the <strong>utils</strong> directory. </p>
<p>The code for the hello.go file that we want to import is this super complicated function :  </p>
<pre class="wp-block-preformatted">package hello

func Hello(name string) string {
   return "hello " + name
}</pre>
<p>The code for the addAndGreet.go  file is a bit more complex : </p>
<pre class="wp-block-preformatted">package utils<br><br>import (<br>   "example.org/hello"<br>   "strconv"<br>)<br><br>func AddAndGreet(name string, a, b int) string {<br>   return hello.Hello(name) + " " + strconv.Itoa(a + b)<br>}<br></pre>
<p>Notice how we are importing <code>"example.org/hello"</code>. </p>
<p>Finally here's the main.go file : </p>
<pre class="wp-block-preformatted">package main<br><br>import (<br>   "example.org/hello"<br>   "example.org/utils"<br>   "fmt"<br>)<br><br>func main() {<br>   fmt.Println(hello.Hello("martin"))<br>   fmt.Println(utils.AddAndGreet("martin", 2, 3))<br>}<br></pre>
<p>Obviously the  modules <code>example.org/hello</code> or <code>example.org/utils </code> do not exist so these imports make zero sense to our compiler so let's help him out a bit  </p>


<h2>Importing local modules in main.go</h2>
<p>So first we simply have to convert all of our directories into go modules. For that we need to add a go.mod at the root of every directories. <br>Then inside of that go.mod give them whatever name that we want as module name. but bear in mind that it has to be an url. In my example I put this:</p>
<p><code>module example.org/hello</code> in the go.mod for the hello directory <br><code>module example.org/utils</code> in the go.mod for the utils directory </p>
<p>The import makes a bit more sense now huh ? but we are not done yet. </p>
<h2>The replace keyword</h2>
<p>This is where the magic happens,  go.mod files have a few keywords that can be very useful, one of them is <strong>replace</strong> what replace does is that it takes a module path (eg : example.org/hello) and replaces it with a direct or relative path.</p>
<p>here's the syntax for the replace keyword : </p>
<pre class="wp-block-preformatted">replace url.com/of/the/module =&gt; /direct/path/to/files</pre>
<p>Note that replace also works with relative paths. </p>
<h2>The main go.mod </h2>
<pre class="wp-block-preformatted">module example.com/localmodexample<br><br>go 1.13<br><br>require (<br>   example.org/hello v0.0.0<br>   example.org/utils v0.0.0<br><br>)<br><br>replace (<br>   example.org/hello =&gt; ./hello<br>   example.org/utils =&gt; ./utils<br>)<br></pre>
<p>Usuall go module dependencies work with versions, so to use local go modules with golang you have to set v0.0.0</p>
<p>Finally after the require, I just tell the compiler that those urls are local and can be found in the same directory under <code>./hello</code> and <code>./utils</code>. The great thing about this main go.mod file is that now even the <strong>utils</strong> module will know where to find the <strong>hello</strong> module because the url have been replaced. </p>
<h2>Conclusion</h2>
<p>And that's all you need to know to use local go modules with golang. Hopefully this will save you all the hours I put into it. Keep in mind that you can find the complete code on my github : <a href="https://github.com/drov0/GolangLocalModulesExample">https://github.com/drov0/GolangLocalModulesExample</a><br><br>I know it's been a while since my last <a href="https://brokencode.io/building-a-time-tracker-using-arduino-and-blockchain-tangletime-part-2/">post</a> but I got quite busy. But now I should be able to make posts more often on this blog. </p>
 <br /> <center><hr/><em>Posted from my blog with <a href='https://wordpress.org/plugins/steempress/'>SteemPress</a> : https://brokencode.io/how-to-use-local-go-modules-with-golang-with-examples/ </em><hr/></center>
👍 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,