<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us"><generator uri="https://gohugo.io/" version="0.101.0">Hugo</generator><title type="html">golang on A Scripter's Notes</title><subtitle type="html">Emacs, scripting and anything text oriented.</subtitle><link href="https://scripter.co/tags/golang/" rel="alternate" type="text/html" title="HTML"/><link href="https://scripter.co/tags/golang/index.xml" rel="alternate" type="application/rss+xml" title="RSS"/><link href="https://scripter.co/tags/golang/atom.xml" rel="self" type="application/atom+xml" title="Atom"/><link href="https://scripter.co/tags/golang/jf2feed.json" rel="alternate" type="application/jf2feed+json" title="jf2feed"/><updated>2026-04-22T08:24:58-04:00</updated><author><name>Kaushal Modi</name><email>kaushal.modi@gmail.com</email></author><id>https://scripter.co/tags/golang/</id><entry><title type="html">Cleaning up ${GOPATH}/pkg/</title><link href="https://scripter.co/cleaning-up-gopath-pkg/?utm_source=atom_feed" rel="alternate" type="text/html"/><link href="https://scripter.co/view-github-pull-requests-in-magit/?utm_source=atom_feed" rel="related" type="text/html" title="View GitHub Pull Requests in Magit"/><link href="https://scripter.co/gujarati-fonts-in-emacs/?utm_source=atom_feed" rel="related" type="text/html" title="Gujarati fonts in Emacs"/><link href="https://scripter.co/emacs-lisp-advice-combinators/?utm_source=atom_feed" rel="related" type="text/html" title="Emacs Lisp: Advice Combinators"/><link href="https://scripter.co/org-show-only-post-subtree-headings/?utm_source=atom_feed" rel="related" type="text/html" title="Org: Show only Post subtree headings"/><link href="https://scripter.co/firefox-always-open-a-new-tab-after-current/?utm_source=atom_feed" rel="related" type="text/html" title="Firefox: Always open a New Tab after Current"/><id>https://scripter.co/cleaning-up-gopath-pkg/</id><author><name>Kaushal Modi</name></author><published>2022-06-25T10:48:00-04:00</published><updated>2022-06-25T10:48:00-04:00</updated><content type="html"><![CDATA[<blockquote>Use <code>go clean -modcache</code> to clean up all the old auto-downloaded Go
modules in <code>${GOPATH}/pkg/</code>. That&rsquo;s all you need to know. Rest of the
post gives just the history of how I got there.</blockquote><div class="ox-hugo-toc toc">
<div class="heading">Table of Contents</div>
<ul>
<li><a href="#the-gopath-directory">The <code>$GOPATH</code> directory</a></li>
<li><a href="#the-disk-space-issue">The disk space issue</a></li>
<li><a href="#write-protected-gopath-pkg">Write-protected <code>${GOPATH}/pkg/</code></a></li>
<li><a href="#cleaning-up-modcache">Cleaning up &ldquo;modcache&rdquo;</a></li>
<li><a href="#wrapping-up">Wrapping up</a></li>
<li><a href="#references">References</a></li>
</ul>
</div>
<!--endtoc-->
<p>As I mentioned in the post description above, the solution to clean up
the auto-populated <code>${GOPATH}/pkg/</code> is to run <code>go clean -modcache</code>. While the solution is simple, it wasn&rsquo;t easy for me to
discover, and so I am writing this short piece to make it a bit more
discoverable for others like me.</p>

<h2 id="the-gopath-directory">The <code>$GOPATH</code> directory&nbsp;<a class="headline-hash no-text-decoration" href="#the-gopath-directory">#</a></h2>


<p>The <code>GOPATH</code> environment variable lists places to look for Go code.</p>
<p>If you haven&rsquo;t set this variable and if the <code>${HOME}/go/</code> directory
isn&rsquo;t used to contain the Go distribution, <code>$GOPATH</code> defaults to that
path.</p>
<p>When you run <code>go get</code> to install any Go package,</p>
<ul>
<li><code>${GOPATH}/pkg/</code> gets populated with all the Go module dependencies,</li>
<li>.. and all package&rsquo;s executables if any get installed to <code>${GOPATH}/bin/</code>.</li>
</ul>
<div class="note">
<p>I think that if the user has set the <code>$GOMODCACHE</code> environment
variable, that directory would get populated with Go module downloads
instead. But for my use, I am sticking with only the <code>$GOPATH</code> for
simplicity.</p>
</div>
<p>To confirm the value of <code>GOPATH</code> used by Go, see <code class="code-inline language-shell">go env <span class="p">|</span> rg GOPATH</code>.</p>

<h2 id="the-disk-space-issue">The disk space issue&nbsp;<a class="headline-hash no-text-decoration" href="#the-disk-space-issue">#</a></h2>


<p>I have been happily installing and building Go apps like Hugo using
<code>go get</code> or <code>go build</code>, and all these installations would end up in
the <code>$GOPATH</code>. But over time, I noticed that the disk space used by
<code>${GOPATH}/pkg/</code> just kept on creeping up.</p>
<p>Today I happened to notice that this directory was taking up roughly
<strong>4 GB</strong> of my disk space! I started analyzing why it was taking up so
much space using my favorite tool for this purpose &ndash; <a href="https://dev.yorhel.nl/ncdu">ncdu</a>.</p>
<p>Here&rsquo;s a snapshot showing disk usage by one of the sub-directories
under <code>${GOPATH}/pkg/</code>, which shows the problem &mdash; Over time, I had
accumulated multiple versions of multiple packages!</p>
<p><a id="figure--go-pkg-disk-usage"></a></p>



<figure>
    
        <img src="https://scripter.co/cleaning-up-gopath-pkg/go-pkg-disk-usage.png" alt="Figure 1: Snapshot of ncdu showing disk usage for a ${GOPATH}/pkg/ directory"/> <figcaption>
                <p>
                    <span class="figure-number">Figure 1: </span>Snapshot of <em>ncdu</em> showing disk usage for a <code>${GOPATH}/pkg/</code> directory
                    
                        
                        </p>
                
            </figcaption></figure>


<h2 id="write-protected-gopath-pkg">Write-protected <code>${GOPATH}/pkg/</code>&nbsp;<a class="headline-hash no-text-decoration" href="#write-protected-gopath-pkg">#</a></h2>


<p>I identified the problem. And I knew that I just needed to delete all
the old packages.</p>
<div class="verse">
<p>        But Go wouldn&rsquo;t allow deleting those <code>pkg/</code> directories!<br /></p>
</div>
<p>I had been searching a solution to this on and off, but didn&rsquo;t have
much success, mainly attributed to the short and generic name of the
&ldquo;Go&rdquo; language, and the fact that I didn&rsquo;t know what the
<code>${GOPATH}/pkg/</code> directory was called.</p>

<h2 id="cleaning-up-modcache">Cleaning up &ldquo;modcache&rdquo;&nbsp;<a class="headline-hash no-text-decoration" href="#cleaning-up-modcache">#</a></h2>


<p>Today, I finally had success when I searched for this magic phrase:
<em>golang &ldquo;cannot remove&rdquo; &ldquo;pkg/mod&rdquo;</em> .. and <a href="https://github.com/golang/go/issues/27161#issuecomment-415213240">Golang Issues # 27161</a> was
the first search result!</p>
<p>The solution was so simple, but so difficult to look for ..</p>
<p><a id="code-snippet--go-clean-modcache"></a></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">go clean -modcache
</span></span></code></pre></div><div class="src-block-caption">
  <span class="src-block-number"><a href="#code-snippet--go-clean-modcache">Code Snippet 1</a>:</span>
  Command to delete contents in <code>${GOPATH}/pkg/</code> or the Go <i>modcache</i>
</div>
<p>From that issue, I also learned that the <code>${GOPATH}/pkg/</code> directory is
the default &ldquo;modcache&rdquo; or the cache directory for holding all the
installed Go modules.</p>

<h2 id="wrapping-up">Wrapping up&nbsp;<a class="headline-hash no-text-decoration" href="#wrapping-up">#</a></h2>


<p>Knowing that the stuff I was trying to delete is called <em>modcache</em>,
this of course works ..</p>
<p><a id="code-snippet--go-help-clean"></a></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">go <span class="nb">help</span> clean <span class="p">|</span> rg modcache -A <span class="m">2</span>
</span></span></code></pre></div><div class="src-block-caption">
  <span class="src-block-number"><a href="#code-snippet--go-help-clean">Code Snippet 2</a>:</span>
  Getting help with cleaning up the <i>modcache</i> from <code>go help</code>
</div>
<p>The issue referenced above gets resolved when a <a href="https://github.com/golang/go/issues/27161#issuecomment-625899357"><code>-modcacherw</code> switch
gets added</a> to the <code>go build</code> command. I see that switch when I run
<code>go help build</code>. <em>But that switch is not available for <code>go get</code>?
.. because I don&rsquo;t see it when I run <code>go help get</code>.</em></p>
<p>I don&rsquo;t understand why Go decided to make this so complicated by
taking away the <em>write</em> access from the user who installed the Go
package!</p>
<div class="verse">
<p>        At least <code>go clean -modcache</code> accomplishes what I want .. <em>sigh</em><br /></p>
</div>

<h2 id="references">References&nbsp;<a class="headline-hash no-text-decoration" href="#references">#</a></h2>


<ul>
<li><a href="https://pkg.go.dev/cmd/go#hdr-GOPATH_environment_variable"><code>go</code> Documentation &ndash; <code>GOPATH</code> environment variable</a></li>
<li><a href="https://pkg.go.dev/cmd/go#hdr-Remove_object_files_and_cached_files"><code>go</code> Documentation &ndash; <code>go help clean</code></a></li>
<li><a href="https://github.com/golang/go/wiki/SettingGOPATH">Go Wiki &ndash; Setting <code>GOPATH</code></a></li>
<li><a href="https://github.com/golang/go/issues/27161">Golang Issue # 27161</a></li>
</ul>
]]></content><category scheme="https://scripter.co/categories/programming" term="programming" label="programming"/><category scheme="https://scripter.co/tags/golang" term="golang" label="golang"/><category scheme="https://scripter.co/tags/100daystooffload" term="100daystooffload" label="100DaysToOffload"/></entry><entry><title type="html">Time formatting in Go</title><link href="https://scripter.co/time-formatting-in-go/?utm_source=atom_feed" rel="alternate" type="text/html"/><link href="https://scripter.co/follow-up-golang-quirk-number-strings-starting-with-0-are-octals/?utm_source=atom_feed" rel="related" type="text/html" title='  Follow-up: Golang Quirk: Number-strings starting with "0" are Octals   '/><link href="https://scripter.co/golang-quirk-number-strings-starting-with-0-are-octals/?utm_source=atom_feed" rel="related" type="text/html" title='  Golang Quirk: Number-strings starting with "0" are Octals   '/><link href="https://scripter.co/convert-seconds-to-human-time/?utm_source=atom_feed" rel="related" type="text/html" title="Your car will be ready in 8000 seconds"/><link href="https://scripter.co/installing-go-toolchain/?utm_source=atom_feed" rel="related" type="text/html" title="Installing go toolchain"/><id>https://scripter.co/time-formatting-in-go/</id><author><name>Kaushal Modi</name></author><published>2018-06-12T12:21:00-04:00</published><updated>2018-06-12T12:21:00-04:00</updated><content type="html"><![CDATA[<blockquote>A little cheat sheet to help remember the Go time formatting syntax.</blockquote><div class="ox-hugo-toc toc">
<div class="heading">Table of Contents</div>
<ul>
<li><a href="#time-dot-format-syntax"><code>Time.Format</code> Syntax</a></li>
<li><a href="#hugo-s-dateformat">Hugo&rsquo;s <code>dateFormat</code></a>
<ul>
<li><a href="#ordinal-dates">Ordinal dates</a></li>
</ul>
</li>
<li><a href="#examples">Examples</a></li>
<li><a href="#references">References</a></li>
</ul>
</div>
<!--endtoc-->
<p>Today on Hugo Discourse, I came across the &ndash; <em>Why &ldquo;2006&rdquo;?</em> &ndash; question
regarding the use of <code>{{ now.Format &quot;2006&quot; }}</code> in Hugo template. That
template simply prints the current year i.e. the time when that
template was rendered by Hugo.</p>
<p>As I was <a href="https://discourse.gohugo.io/t/how-do-i-display-the-current-year/1174/12?u=kaushalmodi">answering that</a>, I thought that this was a good time to
document this for myself too.. and thus this post.</p>

<h2 id="time-dot-format-syntax"><code>Time.Format</code> Syntax&nbsp;<a class="headline-hash no-text-decoration" href="#time-dot-format-syntax">#</a></h2>


<p>Hugo uses the <a href="https://golang.org/pkg/time/#Time.Format">Go <code>Time.Format</code></a> <em>method</em><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> for formatting date and
time strings. But that format specification uses a strange syntax &mdash;
You need to associate 1, 2, 3, 4, 5, 6, 7 with date elements as
follows:</p>
<p><a id="table--go-time-format-syntax"></a></p>
<div class="table-caption">
  <span class="table-number"><a href="#table--go-time-format-syntax">Table 1</a>:</span>
  Cryptic dates used for Go <code>Time.Format</code>
</div>
<table>
<thead>
<tr>
<th>Number</th>
<th>Field Strings</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>01 (<em>with optional leading zero</em>), 1, Jan, January</td>
<td>month</td>
</tr>
<tr>
<td>2</td>
<td>02 (<em>with optional leading zero</em>), 2, Mon, Monday</td>
<td>day</td>
</tr>
<tr>
<td>3</td>
<td>03 (<em>with optional leading zero</em>), 3, 15</td>
<td>hour</td>
</tr>
<tr>
<td>4</td>
<td>04 (<em>with optional leading zero</em>), 4</td>
<td>minute</td>
</tr>
<tr>
<td>5</td>
<td>05 (<em>with optional leading zero</em>), 5</td>
<td>seconds</td>
</tr>
<tr>
<td>6</td>
<td>06, 2006</td>
<td>year</td>
</tr>
<tr>
<td>-7</td>
<td>-0700, -07:00, -07, MST</td>
<td>timezone</td>
</tr>
<tr>
<td>n/a</td>
<td>PM (<strong>not AM</strong>)</td>
<td>AM or PM (<em>uppercase</em>)</td>
</tr>
<tr>
<td>n/a</td>
<td>pm (<strong>not am</strong>)</td>
<td>am or pm (<em>lowercase</em>)</td>
</tr>
<tr>
<td>n/a</td>
<td><strong>anything else</strong></td>
<td><em>shows up as it is</em></td>
</tr>
</tbody>
</table>
<p>You can visualize a formatting string <code>&quot;Jan 2 15:04:05 2006 MST&quot;</code> as
below:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Jan 2 15:04:05 2006 MST
</span></span><span class="line"><span class="cl">  1 2  3  4  5    6  -7
</span></span></code></pre></div>
<h2 id="hugo-s-dateformat">Hugo&rsquo;s <code>dateFormat</code>&nbsp;<a class="headline-hash no-text-decoration" href="#hugo-s-dateformat">#</a></h2>


<p>The <code>dateFormat</code> accepts a date/time format using the same syntax.</p>
<p>Here is the signature of that function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">dateFormat &#34;&lt;FORMAT_STRING&gt;&#34; &#34;&lt;DATE_RFC3339&gt;&#34;
</span></span></code></pre></div><ul>
<li>The <code>&lt;FORMAT_STRING&gt;</code> uses one or more date/time fields as shown in
the &ldquo;Field Strings&rdquo; column in <a href="#table--go-time-format-syntax">Table 1</a>. Few
examples:
<ul>
<li><em>&ldquo;Jan 2 15:04:05 2006 MST&rdquo;</em></li>
<li><em>&ldquo;2006-01-02&rdquo;</em></li>
<li><em>&ldquo;Jan 2, Mon&rdquo;</em></li>
<li><em>&ldquo;It&rsquo;s 3 O&rsquo;clock&rdquo;</em></li>
</ul>
</li>
<li>The <code>&lt;DATE_RFC3339&gt;</code> is a date string compatible with <a href="https://tools.ietf.org/html/rfc3339#section-5.8">RFC3339</a>. Few
example valid date strings:
<ul>
<li><em>&ldquo;2017-07-31&rdquo;</em></li>
<li><em>&ldquo;2017-07-31T17:05:38&rdquo;</em></li>
<li><em>&ldquo;2017-07-31T17:05:38Z&rdquo;</em></li>
<li><em>&ldquo;2017-07-31T17:05:38+04:00&rdquo;</em></li>
<li><em>&ldquo;2017-07-31T17:05:38-04:00&rdquo;</em></li>
</ul>
</li>
</ul>

<h3 id="ordinal-dates">Ordinal dates&nbsp;<a class="headline-hash no-text-decoration" href="#ordinal-dates">#</a></h3>


<p>In addition, <a href="https://gohugo.io/functions/humanize/"><code>humanize</code></a> can be used to generate <em>ordinal</em> date, like
&ldquo;1st&rdquo;, &ldquo;2nd&rdquo;, &ldquo;3rd&rdquo;, ..</p>

<h2 id="examples">Examples&nbsp;<a class="headline-hash no-text-decoration" href="#examples">#</a></h2>



The time string <i>"2018-06-13T11:30:00-04:00"</i>
(RFC3339 format) can be output in different formats:

<br />
<br />

<table>
    <tr><th>Go Formatting string</th>
        <th>Output</th>
    </tr>
    
        
        <tr><td><code>"Jan 2 15:04:05 2006 MST"</code></td><td><code>"Jun 13 11:30:00 2018 EDT"</code></td></tr>
    
        
        <tr><td><code>"2006-01-02 03:04pm Monday"</code></td><td><code>"2018-06-13 11:30am Wednesday"</code></td></tr>
    
        
        <tr><td><code>"Jan 2, Mon"</code></td><td><code>"Jun 13, Wed"</code></td></tr>
    
        
        <tr><td><code>"It's 3 O'clock"</code></td><td><code>"It's 11 O'clock"</code></td></tr>
    
</table>

Below shows examples of printing ordinal dates using a combination of
<code>((dateFormat "2" $dt) | humanize)</code> and <code>(dateFormat "of
January" $dt)</code>:

<br />
<br />

<table>
    <tr><th>Date (<code>$dt</code>)</th>
        <th>Output</th>
    </tr>
    
        
        <tr><td>2018-06-01</td><td><code>"1st of June"</code></td></tr>
    
        
        <tr><td>2018-06-02</td><td><code>"2nd of June"</code></td></tr>
    
        
        <tr><td>2018-06-03</td><td><code>"3rd of June"</code></td></tr>
    
        
        <tr><td>2018-06-04</td><td><code>"4th of June"</code></td></tr>
    
        
        <tr><td>2018-06-10</td><td><code>"10th of June"</code></td></tr>
    
</table>


<h2 id="references">References&nbsp;<a class="headline-hash no-text-decoration" href="#references">#</a></h2>


<ul>
<li>gohugohq.com &ndash; <a href="https://gohugohq.com/howto/hugo-dateformat/">Hugo dateFormat</a></li>
<li>Hugo documentation &ndash; <a href="https://gohugo.io/functions/dateformat/"><code>dateFormat</code></a></li>
<li><a href="https://github.com/bdotdub/fuckinggodateformat">f***inggodateformat</a></li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I am not a Go dev.. let me know if the correct term for that is
a &ldquo;function&rdquo; or a &ldquo;method&rdquo; in Go 😄. <strong>Update</strong> <span class="timestamp-wrapper"><span class="timestamp">&lt;2018-11-08 Thu&gt;</span></span>:
Thanks to <em>Mendy</em> in comments, I have now fixed referencing
<code>Time.Format</code> as a <strong>method</strong>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content><category scheme="https://scripter.co/categories/hugo" term="hugo" label="hugo"/><category scheme="https://scripter.co/tags/time" term="time" label="time"/><category scheme="https://scripter.co/tags/format" term="format" label="format"/><category scheme="https://scripter.co/tags/golang" term="golang" label="golang"/></entry><entry><title type="html">Follow-up: Golang Quirk: Number-strings starting with "0" are Octals</title><link href="https://scripter.co/follow-up-golang-quirk-number-strings-starting-with-0-are-octals/?utm_source=atom_feed" rel="alternate" type="text/html"/><link href="https://scripter.co/golang-quirk-number-strings-starting-with-0-are-octals/?utm_source=atom_feed" rel="related" type="text/html" title='  Golang Quirk: Number-strings starting with "0" are Octals   '/><link href="https://scripter.co/installing-go-toolchain/?utm_source=atom_feed" rel="related" type="text/html" title="Installing go toolchain"/><id>https://scripter.co/follow-up-golang-quirk-number-strings-starting-with-0-are-octals/</id><author><name>Kaushal Modi</name></author><published>2018-04-23T23:39:00-04:00</published><updated>2018-04-23T23:39:00-04:00</updated><content type="html"><![CDATA[<blockquote>Follow-up post to my earlier post on octals in Golang &ndash; Feedback to
reactions that varied from ridicule to helpfulness to empathy.</blockquote><p>First of all&mdash;I get it. Golang is not the <strong>only</strong> language that has
this odd behavior related to <em>octals</em>. But following the foot-steps of
ancestor languages in this particular aspect does not mean that Golang
is doing the Right Thing(TM).</p>
<p>I got many interesting comments at:</p>
<ul>
<li><a href="https://www.reddit.com/r/programmingcirclejerk/comments/8dasl5/what_is_octal_s/">A thread on <em>r/programmingcirclejerk</em></a></li>
<li><a href="https://www.reddit.com/r/golang/comments/8d9d5n/golang_quirk_numberstrings_starting_with_0_are/">A thread on <em>r/golang</em></a></li>
<li><a href="https://news.ycombinator.com/item?id=16871683">HN thread</a></li>
<li>And on the <a href="/golang-quirk-number-strings-starting-with-0-are-octals/">original post</a> itself.</li>
</ul>
<p>Here are some highlights.</p>
<dl>
<dt><a href="https://news.ycombinator.com/user?id=zcdopizocioics"><strong>zcdopizocioics</strong></a> from Hacker News</dt>
<dd>The <code>strconv</code> function simply acts in
the same manner as the language does, see
<a href="https://play.golang.org/p/rg0VwhCDVB_C">https://play.golang.org/p/rg0VwhCDVB_C</a>. The idea for <code>strconv</code>
originates in c (see atoi etc), and c also has 0-octal
notation. Go is simply mimicing c in this regard.
<p><strong>My reply</strong> &ndash; <em>I just wished the octals needed a stricter prefix
like &ldquo;0o&rdquo; as they are not very common compared to decimal and hex
(in my experience at least).</em></p>
</dd>
<dt><a href="https://news.ycombinator.com/user?id=karmakaze"><strong>karmakaze</strong></a> from Hacker News</dt>
<dd>A better solution is to always provide the
base (e.g. 10) rather than using 0 if you don&rsquo;t want special
interpretation of &lsquo;0x&rsquo; and &lsquo;0&rsquo; prefixes. That should be in
Hugo. The problem is not with the golang library which was well
documented and always worked as such. By placing any blame on the
golang library, there&rsquo;s less incentive to fix Hugo.
<p><strong>My reply</strong> &ndash; <em>That&rsquo;s a valid point. I have <a href="https://github.com/gohugoio/hugo/issues/4628#issuecomment-382595019">made that suggestion</a> to
the Hugo devs. Someone on Reddit also suggested using
<code>strconv.Atoi()</code> instead of <code>ParseInt()</code>. I have added to the
suggestion too.</em></p>
</dd>
<dt><a href="https://www.reddit.com/user/shekelharmony"><strong>/u/shekelharmony</strong></a> from Reddit</dt>
<dd>This isn&rsquo;t really a quirk of Go - the
documentation says exactly how <code>strconv.ParseInt()</code> works, and
you would only get that behavior by intentionally setting the
second argument to 0. If you&rsquo;re always working with decimals, you
might use <code>strconv.Atoi()</code> instead since it only takes one
argument. You could say it&rsquo;s a quirk of Hugo though, since it
sounds like they don&rsquo;t have a function for parsing decimals at
all.
<p><strong>My reply</strong> &ndash; <em>.. I&rsquo;ll definitely forward your suggestion with the
Hugo dev team.</em> (I then do that, which I linked above.)</p>
</dd>
<dt><a href="https://www.reddit.com/user/FascinatedBox"><strong>/u/FascinatedBox</strong></a> from Reddit</dt>
<dd>Java and C both have this and it&rsquo;s
incredibly stupid. Every once in a while some noob thinks that
leading zeroes don&rsquo;t matter (they shouldn&rsquo;t). So they write a
number like 0123 and it doesn&rsquo;t come out to 123 but there is
nothing you can look up to figure out why. There&rsquo;s no function
you&rsquo;re calling to say &ldquo;okay, why is function X doing this
transformation?&rdquo; It&rsquo;s really not hard to have some sort of a
prefix. We have a prefix for binary numbers when languages have
that. We have one for hex. Why not octal. My language uses <code>0c</code>
to denote octal so that people don&rsquo;t accidentally fall into this
trap. I added that in precisely because I saw someone in a
programming class get burned by accidental octal. I knew what the
problem was right away, because I&rsquo;m a PL nerd. But a lot of
people don&rsquo;t want octal, and they certainly aren&rsquo;t expecting it.
<p><strong>My reply</strong> &ndash; <em>Thank you. Exactly my point.. We have prefixes for
binary and hexadecimal. So I find it odd that octal is given a
special treatment by it not needing a prefix! And Golang was
created in 2009; it shouldn&rsquo;t have blindly ported that from
C. And who IS writing octal literals today, so furiously, in so
much abundance, that they cannot afford using a normal prefix
like <code>0o</code>? Kudos to Python for obsoleting the <code>0</code> octal prefix in
lieu of <code>0o</code> in Python 3.</em></p>
</dd>
<dt><a href="https://www.reddit.com/user/stone_henge"><strong>/u/stone_henge</strong></a> from Reddit</dt>
<dd>poor guy, he just goes on and on about it
forever, no way for anyone to step in in the middle of it and
point out to him that he&rsquo;s being dumb.
<p><strong>My reply</strong> &ndash; <em>Yup. Poor, dumb, me.</em></p>
</dd>
<dt><a href="https://www.reddit.com/user/Noughmad"><strong>/u/Noughmad</strong></a> from Reddit</dt>
<dd>The handling of octal numbers in C is
stupid, I have been bitten by it especially when trying to align
multiple numbers with a different number of digits. There should
be some non-digit identifier (and not O because it looks to much
like 0 in a fixed-width font) used for specifying octal numbers,
like x for hexadecimal and now b for binary. But once again, C
gets a pass because it was made over 40 years ago. Go doesn&rsquo;t
have this excuse.
<p><strong>My reply</strong> &ndash; <em>Thank you. Exactly.</em></p>
</dd>
<dt><a href="https://www.reddit.com/user/pingpong"><strong>/u/pingpong</strong></a> from Reddit</dt>
<dd>Relevant golang bugs, where people try to
fix octal: <a href="https://github.com/golang/go/issues/22671">golang issue #22671</a>, <a href="https://github.com/golang/go/issues/151">golang issue #151</a>, <a href="https://github.com/golang/go/issues/12711">golang issue
#12711</a>.
<p><strong>My reply</strong> &ndash; <em>Great! So I am not alone.</em></p>
</dd>
</dl>
<hr>
<p>You can enjoy more of such comments by visiting the Reddit thread
linked above.</p>
<p>I would though welcome constructive comments below, or if you prefer,
at one of those reddit/HN threads linked above.</p>

<h2 id="conclusion">Conclusion&nbsp;<a class="headline-hash no-text-decoration" href="#conclusion">#</a></h2>


<p>Golang is a modern language born in 2009. It could have fixed this by
requiring a more logical prefix like <code>0o</code> for Octals. <em>Or can it
still?</em></p>
<p>At least I hope that parsing of numbers in front-matter in Hugo gets
fixed as it&rsquo;s unlikely for folks to use octal numbers there.</p>
]]></content><category scheme="https://scripter.co/categories/hugo" term="hugo" label="hugo"/><category scheme="https://scripter.co/categories/replies" term="replies" label="replies"/><category scheme="https://scripter.co/series/golang-octals" term="golang-octals" label="Golang Octals"/><category scheme="https://scripter.co/tags/golang" term="golang" label="golang"/><category scheme="https://scripter.co/tags/octal" term="octal" label="octal"/><category scheme="https://scripter.co/tags/quirk" term="quirk" label="quirk"/></entry><entry><title type="html">Golang Quirk: Number-strings starting with "0" are Octals</title><link href="https://scripter.co/golang-quirk-number-strings-starting-with-0-are-octals/?utm_source=atom_feed" rel="alternate" type="text/html"/><link href="https://scripter.co/notes/string-fns-nim-vs-python/?utm_source=atom_feed" rel="related" type="text/html" title="String Functions: Nim vs Python"/><link href="https://scripter.co/installing-go-toolchain/?utm_source=atom_feed" rel="related" type="text/html" title="Installing go toolchain"/><id>https://scripter.co/golang-quirk-number-strings-starting-with-0-are-octals/</id><author><name>Kaushal Modi</name></author><published>2018-04-18T16:29:00-04:00</published><updated>2018-04-18T16:29:00-04:00</updated><content type="html"><![CDATA[<blockquote>Someone in the Golang team thought that it would be a good idea to
consider all numbers (represented as strings) starting with &ldquo;0&rdquo; as
Octals.. so &ldquo;010&rdquo; is actually 8.. Really?</blockquote><div class="ox-hugo-toc toc">
<div class="heading">Table of Contents</div>
<ul>
<li><a href="#problem">Problem</a></li>
<li><a href="#cause">Cause</a></li>
<li><a href="#workaround">Workaround</a></li>
<li><a href="#resurgence">Resurgence</a></li>
<li><a href="#debug">Debug</a></li>
<li><a href="#next-steps">Next Steps?</a></li>
</ul>
</div>
<!--endtoc-->
<p>The aim of this post is to make a Golang quirk more of a common
knowledge, with an ulterior motive to eventually get it fixed
upstream, somehow..</p>
<div class="note">
<p><strong>Disclaimer</strong>: I don&rsquo;t code in Go lang. So I could very well be wrong
in saying <em>problem with Golang</em> vs <em>problem with specifically
<code>strconv</code> package</em>.</p>
</div>
<p>From my perspective, I see <code>strconv</code> as an internal Go package that
any (most of?) Go coder would use to do <em>string → int</em> conversions. If
so, I don&rsquo;t grasp the rationale behind why the <code>strconv</code> developers
would make this strange decision.. strange because in <em>normal</em>
languages like Python, <code>int(&quot;010&quot;)</code> returns <code>10</code>.</p>

<h2 id="problem">Problem&nbsp;<a class="headline-hash no-text-decoration" href="#problem">#</a></h2>


<p>I learned about this issue for the first time from <a href="https://discourse.gohugo.io/t/unable-to-cast-09-of-type-string-to-int/9614/6?u=kaushalmodi">this Hugo Discourse
thread</a>. The synopsis is that someone is retrieving US city zip-codes
from a Hugo front-matter variable, and then using some conditional
logic based on the last 2 digits.</p>
<p>So the code was:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="c">&lt;!-- Value of .Params.cityZipCode is &#34;75009&#34; --&gt;</span>
</span></span><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">(</span><span class="nx">int</span><span class="w"> </span><span class="o">(</span><span class="nx">last</span><span class="w"> </span><span class="nx">2</span><span class="w"> </span><span class="na">.Params.cityZipCode</span><span class="o">))</span><span class="w"> </span><span class="k">eq</span><span class="w"> </span><span class="nx">1</span><span class="w"> </span><span class="cp">}}</span>er<span class="cp">{{</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="cp">}}</span>e<span class="cp">{{</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="cp">}}</span>
</span></span></code></pre></div><p>The logic is simple.. Get the last two characters of
<code>.Params.cityZipCode</code>, which would be <code>&quot;09&quot;</code>, convert that string to a
number (<code>int</code>), and check if it is <code>1</code>.</p>
<p>But <em>of-course</em> that didn&rsquo;t work:</p>
<blockquote>
<p>unable to cast &ldquo;09&rdquo; of type string to int</p>
</blockquote>

<h2 id="cause">Cause&nbsp;<a class="headline-hash no-text-decoration" href="#cause">#</a></h2>


<p>Later, as I learn, that&rsquo;s because of the <a href="https://golang.org/pkg/strconv/#ParseInt"><code>ParseInt</code> function from the
<code>strconv</code></a> package. There it says (emphasis mine):</p>
<blockquote>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">ParseInt</span><span class="p">(</span><span class="nx">s</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">base</span> <span class="kt">int</span><span class="p">,</span> <span class="nx">bitSize</span> <span class="kt">int</span><span class="p">)</span> <span class="p">(</span><span class="nx">i</span> <span class="kt">int64</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span>
</span></span></code></pre></div><p><code>ParseInt</code> interprets a string <code>s</code> in the given <code>base</code> (0, 2 to 36)
and <code>bit</code> size (0 to 64) and returns the corresponding value <code>i</code>.</p>
<p>If <code>base == 0</code>, the <code>base</code> is implied by the string&rsquo;s prefix: base 16
for <code>&quot;0x&quot;</code>, <strong>base 8 for <code>&quot;0&quot;</code></strong>, and base 10 otherwise. For bases 1,
below 0 or above 36 an error is returned.</p>
</blockquote>
<div class="verse">
<p>    Again.. What was the Golang team thinking?!<br /></p>
</div>

<h2 id="workaround">Workaround&nbsp;<a class="headline-hash no-text-decoration" href="#workaround">#</a></h2>


<p>This led me to update the <a href="https://gohugo.io/functions/int/"><code>int</code> function</a> documentation for Hugo with
an ugly workaround:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go-html-template" data-lang="go-html-template"><span class="line"><span class="cl"><span class="cp">{{</span><span class="w"> </span><span class="nx">int</span><span class="w"> </span><span class="o">(</span><span class="s">&#34;00987&#34;</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nx">strings</span><span class="na">.TrimLeft</span><span class="w"> </span><span class="s">&#34;0&#34;</span><span class="o">)</span><span class="w"> </span><span class="cp">}}</span>
</span></span></code></pre></div>
<h2 id="resurgence">Resurgence&nbsp;<a class="headline-hash no-text-decoration" href="#resurgence">#</a></h2>


<p>This problem of <em>number-strings beginning with &ldquo;0&rdquo; considered as
octals</em> resurfaced recently in Hugo issue #<a href="https://github.com/gohugoio/hugo/issues/4628">4628</a>.</p>
<p>Though, the reported error did not make it evident that that was the
problem:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">INFO 2018/04/15 18:49:36 found taxonomies: map[string]string{&#34;category&#34;:&#34;categories&#34;, &#34;manufacturerletter&#34;:&#34;manufacturerletters&#34;, &#34;manufacturer&#34;:&#34;manufacturers&#34;, &#34;featured&#34;:&#34;featured&#34;, &#34;tag&#34;:&#34;tags&#34;}
</span></span><span class="line"><span class="cl">panic: interface conversion: interface {} is float64, not int
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">goroutine 50 [running]:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">github.com/gohugoio/hugo/hugolib.(*Site).assembleTaxonomies(0xc4204ce2c0)
</span></span><span class="line"><span class="cl">	/go/src/github.com/gohugoio/hugo/hugolib/site.go:1545 +0xee2
</span></span></code></pre></div><p>The issue reporter had 1500+ content files, and one or more of those
files caused this uncaught exception (<em>which is a separate issue, and
is planned to be fixed in Hugo</em>) to happen. So I had to spend quite
some time doing &ldquo;forensic debug&rdquo;<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> to understand what caused that
<em>&ldquo;interface conversion: interface {} is float64, not int&rdquo;</em>.</p>

<h2 id="debug">Debug&nbsp;<a class="headline-hash no-text-decoration" href="#debug">#</a></h2>


<ul>
<li>
<p>The exception was thrown at <a href="https://github.com/gohugoio/hugo/blob/74520d2cfd39bb4428182e26c57afa9df83ce7b5/hugolib/site.go#L1545">this line</a> (highlighted below):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="k">for</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">p</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">s</span><span class="p">.</span><span class="nx">Pages</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">vals</span> <span class="o">:=</span> <span class="nx">p</span><span class="p">.</span><span class="nf">getParam</span><span class="p">(</span><span class="nx">plural</span><span class="p">,</span> <span class="p">!</span><span class="nx">s</span><span class="p">.</span><span class="nx">Info</span><span class="p">.</span><span class="nx">preserveTaxonomyNames</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nx">weight</span> <span class="o">:=</span> <span class="nx">p</span><span class="p">.</span><span class="nf">getParamToLower</span><span class="p">(</span><span class="nx">plural</span> <span class="o">+</span> <span class="s">&#34;_weight&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="nx">weight</span> <span class="o">==</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">weight</span> <span class="p">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="nx">vals</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="nx">v</span><span class="p">,</span> <span class="nx">ok</span> <span class="o">:=</span> <span class="nx">vals</span><span class="p">.([]</span><span class="kt">string</span><span class="p">);</span> <span class="nx">ok</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">for</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">idx</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">v</span> <span class="p">{</span>
</span></span><span class="line hl"><span class="cl">                <span class="nx">x</span> <span class="o">:=</span> <span class="nx">WeightedPage</span><span class="p">{</span><span class="nx">weight</span><span class="p">.(</span><span class="kt">int</span><span class="p">),</span> <span class="nx">p</span><span class="p">}</span>
</span></span></code></pre></div></li>
<li>
<p>So it was evident that one of the taxonomy weight
(<code>manufacturers_weight</code> in this case) values wasn&rsquo;t getting casted
to <code>int</code>.</p>
</li>
<li>
<p>So I grepped for anything <em>non-int</em> in those values, like <code>.</code>, <code>,</code>,
<code>e</code> or <code>E</code>, but found nothing.</p>
</li>
<li>
<p>Then doing <code>rg ':\s[0-9]{7,}(\.[0-9]+)*$'</code> in the content files, I
saw that there were 4 files that had oddly high weight values like
4611000, and wondered if that was somehow the problem. But that
wasn&rsquo;t it either.</p>
</li>
<li>
<p>When I deleted <strong>all</strong> the <code>manufacturers_weight</code> lines in those 1500+
files, the error went away.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">find . -name <span class="s2">&#34;*.md&#34;</span> -print0 <span class="p">|</span> xargs -0 sed -i <span class="s1">&#39;/manufacturers_weight:.*/d&#39;</span>
</span></span></code></pre></div></li>
<li>
<p>So then I restored all of those deleted lines, and started deleting
them again, this time in progression ..</p>
<ul>
<li>First deleting all the lines with values with 7 or more
digits.. <em>Error still present</em>.</li>
<li>Then deleting all lines with values with 6 digits.. <em>Error still present</em>.</li>
<li>.. <em>Error still present</em>.</li>
<li>Finally when I deleted all lines with values with 4 digits, the
error went away!</li>
<li>But by now, I had modified about 700 files in this process!</li>
</ul>
</li>
<li>
<p>I had almost given up on debugging this further, when I decided to
give the <code>git diff</code> one last glance.. and I found the pattern..</p>
<div class="verse">
<p>    .. the <em>freaking</em> leading 0&rsquo;s in some of those <code>manufacturers_weight</code> values!<br /></p>
</div>
</li>
</ul>
<p>I had a strong gut feeling that those zeros <strong>were</strong> the problem. So I
once again restored the deleted lines in all the content files,
typed out the below<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> with confidence ..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">find . -name <span class="s2">&#34;*.md&#34;</span> -exec grep -P <span class="s1">&#39;manufacturers_weight: 0[0-9]+&#39;</span> -l <span class="o">{}</span> <span class="se">\;</span> -exec sed -r -i <span class="s1">&#39;s/(manufacturers_weight: )0([0-9]+)/\1\2/&#39;</span> <span class="o">{}</span> <span class="se">\;</span>
</span></span></code></pre></div><div class="verse">
<p>    .. and that error was of course gone! 🎉<br /></p>
</div>
<p>This ended up with just 16 modified files with a diff like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-diff" data-lang="diff"><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">modified   content/movements/b/buren/buren-04.en.md
</span></span><span class="line"><span class="cl"><span class="gu">@@ -12,7 +12,7 @@ image: &#34;Buren_04.jpg&#34;
</span></span></span><span class="line"><span class="cl"><span class="gu"></span> movementlistkey: &#34;buren&#34;
</span></span><span class="line"><span class="cl"> caliberkey: &#34;04&#34;
</span></span><span class="line"><span class="cl"> manufacturers: [&#34;buren&#34;]
</span></span><span class="line"><span class="cl"><span class="gd">-manufacturers_weight: 04
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+manufacturers_weight: 4
</span></span></span><span class="line"><span class="cl"><span class="gi"></span> categories: [&#34;movements&#34;,&#34;movements_b&#34;,&#34;movements_b_buren_en&#34;]
</span></span><span class="line"><span class="cl"> widgets:
</span></span><span class="line"><span class="cl">   relatedmovements: true
</span></span><span class="line"><span class="cl">modified   content/movements/c/citizen/citizen-0153.de.md
</span></span><span class="line"><span class="cl"><span class="gu">@@ -12,7 +12,7 @@ image: &#34;Citizen_0153.jpg&#34;
</span></span></span><span class="line"><span class="cl"><span class="gu"></span> movementlistkey: &#34;citizen&#34;
</span></span><span class="line"><span class="cl"> caliberkey: &#34;0153&#34;
</span></span><span class="line"><span class="cl"> manufacturers: [&#34;citizen&#34;]
</span></span><span class="line"><span class="cl"><span class="gd">-manufacturers_weight: 0153
</span></span></span><span class="line"><span class="cl"><span class="gd"></span><span class="gi">+manufacturers_weight: 153
</span></span></span><span class="line"><span class="cl"><span class="gi"></span> categories: [&#34;movements&#34;,&#34;movements_c&#34;,&#34;movements_c_citizen&#34;]
</span></span><span class="line"><span class="cl"> widgets:
</span></span><span class="line"><span class="cl">   relatedmovements: true
</span></span><span class="line"><span class="cl">...
</span></span></code></pre></div><p>So that provided that issue originator a workaround so that they can
at least get their site built.</p>
<p>But I hope that this <em>0-leading octal</em> absurdity gets fixed at the
root level &mdash; People should once again say with confidence, as they
learned as kids, that &ldquo;010&rdquo; is the same thing as &ldquo;10&rdquo;.</p>

<h2 id="next-steps">Next Steps?&nbsp;<a class="headline-hash no-text-decoration" href="#next-steps">#</a></h2>


<ul>
<li>
<p>Hugo fixes this issue (<a href="https://github.com/gohugoio/hugo/issues/4628">4628</a>) on its end by not making this exception
go uncaught, and instead let the user know that they magically added
a non-<code>int</code>-castable <em>octal</em> value in their content in X file on Y
line.</p>
</li>
<li>
<p>The Golang team gives some serious thought to this <del>stupid</del> <em>(sorry
about that)</em> annoying decision:</p>
<blockquote>
<p>If <code>base == 0</code>, the <code>base</code> is implied by the string&rsquo;s prefix: base 16
for <code>&quot;0x&quot;</code>, <strong>base 8 for <code>&quot;0&quot;</code></strong> ..</p>
</blockquote>
</li>
</ul>
<div class="center"><b>§</b></div>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I call this &ldquo;forensic debug&rdquo; because I don&rsquo;t know Go, and how
and where to add debug statements within the <code>hugo</code> source code. So my
approach was to figure out which content file/line caused that error.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>That command finds all the <code>.md</code> files in the current
directory, returns a list of file names wherein the
<code>manufactureres_weight</code> value begins with <code>0</code> using <code>grep</code>, and then
surgically remove the leading zeros just in those short-listed files
using <code>sed</code>.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content><category scheme="https://scripter.co/categories/hugo" term="hugo" label="hugo"/><category scheme="https://scripter.co/series/golang-octals" term="golang-octals" label="Golang Octals"/><category scheme="https://scripter.co/tags/golang" term="golang" label="golang"/><category scheme="https://scripter.co/tags/octal" term="octal" label="octal"/><category scheme="https://scripter.co/tags/quirk" term="quirk" label="quirk"/><category scheme="https://scripter.co/tags/strconv" term="strconv" label="strconv"/><category scheme="https://scripter.co/tags/zero" term="zero" label="zero"/><category scheme="https://scripter.co/tags/string" term="string" label="string"/><category scheme="https://scripter.co/tags/sed" term="sed" label="sed"/><category scheme="https://scripter.co/tags/find" term="find" label="find"/><category scheme="https://scripter.co/tags/grep" term="grep" label="grep"/><category scheme="https://scripter.co/tags/go-template" term="go-template" label="go-template"/></entry><entry><title type="html">Installing go toolchain</title><link href="https://scripter.co/installing-go-toolchain/?utm_source=atom_feed" rel="alternate" type="text/html"/><id>https://scripter.co/installing-go-toolchain/</id><author><name>Kaushal Modi</name></author><published>2017-02-24T01:33:47-05:00</published><updated>2018-05-17T00:00:00-04:00</updated><content type="html"><![CDATA[<blockquote>&ldquo;Installing&rdquo; <code>go</code> is simply extracting its release archive, putting it
somewhere in you <code>$HOME</code> and pointing <code>GOROOT</code> and <code>PATH</code> env vars to
it.</blockquote><div class="ox-hugo-toc toc">
<div class="heading">Table of Contents</div>
<ul>
<li><a href="#installing-go">Installing <code>go</code></a></li>
<li><a href="#updating-go">Updating <code>go</code></a></li>
</ul>
</div>
<!--endtoc-->
<p>There are <strong>two</strong> reasons why I suggest installing <code>go</code> to anyone,
whether they are Go developers, or not (like me).</p>
<ol>
<li>You can then build amazing utilities like <a href="https://github.com/peco/peco">peco</a>, <a href="https://github.com/gohugoio/hugo">hugo</a> and <a href="https://github.com/variadico/noti">noti</a>.</li>
<li><strong>It&rsquo;s easy!</strong></li>
</ol>

<h2 id="installing-go">Installing <code>go</code>&nbsp;<a class="headline-hash no-text-decoration" href="#installing-go">#</a></h2>


<p>Below instructions are for installing <code>go</code> on a 64-bit GNU/Linux
machine, and using <code>tcsh</code> shell. But similar steps should work for any
other OS and shell.</p>
<ol>
<li>Download the <em>tar.gz</em> for the latest <em>linux-amd64</em> binaries from
<a href="https://golang.org/dl/">https://golang.org/dl/</a>.</li>
<li>Extract it to some place in your <code>$HOME</code>. I extract it to
<code>${HOME}/go/</code><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</li>
<li>Create a directory where you would want to install the <code>go</code>
packages.
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">mkdir -p ~/go.apps
</span></span></code></pre></div></li>
<li>Set the following environment variables<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>, and also save them to
your shell config:
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tcsh" data-lang="tcsh"><span class="line"><span class="cl"><span class="nb">setenv </span>GOROOT <span class="k">${</span><span class="nv">HOME</span><span class="k">}</span>/go <span class="c"># go root</span>
</span></span><span class="line"><span class="cl"><span class="nb">setenv </span>GOPATH <span class="k">${</span><span class="nv">HOME</span><span class="k">}</span>/go.apps <span class="c"># for go applications</span>
</span></span></code></pre></div></li>
<li>Add the <code>${GOROOT}/bin</code> and <code>${GOPATH}/bin</code> directories to your
<code>$PATH</code>.</li>
</ol>
<p>Now you can install any <code>go</code> application!</p>
<p>For instance, <code>noti</code> is a nice little utility that triggers an alert
(desktop popup, <em>Pushbullet</em> notification, etc.) when a process
finishes.  From its <a href="https://github.com/variadico/noti#installation">installation notes</a>, you just run the below to
install it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">go get -u github.com/variadico/noti/cmd/noti
</span></span></code></pre></div><p>Apart from the <code>go</code> applications I suggested here, <em>go</em> out and explore
more &ndash; <code>go get</code> them 😁</p>

<h2 id="updating-go">Updating <code>go</code>&nbsp;<a class="headline-hash no-text-decoration" href="#updating-go">#</a></h2>


<ol>
<li>Delete the existing <code>$GOROOT</code> directory (<strong>not <code>GOPATH</code>!</strong>)
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">rm -rf ~/go   <span class="c1"># as that is my GOROOT</span>
</span></span></code></pre></div></li>
<li>Download the <em>tar.gz</em> for the latest <em>linux-amd64</em> binaries.</li>
<li>Extract it to the same <code>$GOROOT</code> (<code>~/go</code> in my case).</li>
</ol>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I prefer to not add the version number to my <code>go</code> installation
folder. That way, when I want to update it, I simply <code>rm -rf</code> it and
put in the new version.. and I don&rsquo;t need to update <code>GOROOT</code> or
<code>PATH</code>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>You can refer to these official <code>go</code> references [ <a href="https://golang.org/doc/install#tarball">1</a> ], [ <a href="https://golang.org/doc/install#testing">2</a> ] for
further information on these variables.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content><category scheme="https://scripter.co/categories/unix" term="unix" label="unix"/><category scheme="https://scripter.co/tags/toolchain" term="toolchain" label="toolchain"/><category scheme="https://scripter.co/tags/golang" term="golang" label="golang"/></entry></feed>