<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>GitHub on bramp.net</title>
    <link>https://blog.bramp.net/</link>
    <description>Recent content in GitHub on bramp.net</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-GB</language>
    <lastBuildDate>Mon, 02 Oct 2017 07:48:23 -0700</lastBuildDate>
    <atom:link href="https://blog.bramp.net/tags/github/" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Vanity Go Import Paths</title>
      <link>https://blog.bramp.net/post/2017/10/02/vanity-go-import-paths/</link>
      <pubDate>Mon, 02 Oct 2017 07:48:23 -0700</pubDate>
      
      <guid>https://blog.bramp.net/post/2017/10/02/vanity-go-import-paths/</guid>
      <description><p>When using third-party packages in Go, they are imported by a path that represents
how to download that package from the Internet. For example, to use the
popular structured logging library, <a href="https://github.com/sirupsen/logrus">Logrus</a>, it would imported at the top of the Go program like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="s">&#34;github.com/sirupsen/logrus&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>When <code>go get</code> is then executed, it fetches the Logrus source code from GitHub
and places the code in the <code>$GOPATH/src</code> directory. Take a look for yourself:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ tree <span class="nv">$GOPATH</span>/src
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">├── github.com
</span></span><span class="line"><span class="cl">│   ├── Sirupsen
</span></span><span class="line"><span class="cl">│   │   └── logrus
</span></span><span class="line"><span class="cl">...
</span></span></code></pre></div><p>An astute reader may wonder, how exactly does <code>go get</code> know that <code>github.com/sirupsen/logrus</code> is a Git repository, and that it can be fetched via the git protocol from that URL. The <code>go get</code> binary could have some smarts in it, that knows about GitHub, and does the right thing. But that seems inflexible, and problematic if new sites want to be supported. Instead the Go developers built a layer of indirection that allows the <code>go get</code> tool to discover the correct source repo.</p>
<p>As outlined in the <a href="https://golang.org/cmd/go/#hdr-Remote_import_paths">Remote Import Paths</a> docs,  the <code>go get</code> binary will make a normal HTTP request to <code>https://github.com/sirupsen/logrus</code> (falling back to http if needed) and look at the returned HTML for a <code>&lt;meta name=&quot;go-import&quot;</code> tag. This meta tag, can then redirect the <code>go get</code> binary to the correct source code repository for the package.</p>
<p>This meta tag can been seen with <code>curl</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ curl https://github.com/sirupsen/logrus <span class="p">|</span> grep meta <span class="p">|</span> grep go-import
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">meta</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;go-import&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">content</span><span class="o">=</span><span class="s">&#34;github.com/sirupsen/logrus git https://github.com/sirupsen/logrus.git&#34;</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>That tag says, the package rooted at <code>github.com/sirupsen/logrus</code> can be fetched with git, at the
URL <code>https://github.com/sirupsen/logrus.git</code>. The meta tag can express other source control systems, e.g Mercurial, Bazaar, Subversion.</p>
<p>GitHub is a very convenient place to host source code, but the GitHub URL is generic. Instead it is possible to use the <code>&lt;meta&gt;</code> tag to create vanity domains to host projects. For example, the package hosted at <a href="https://github.com/bramp/goredirects">github.com/bramp/goredirects</a> could instead be imported as <code>bramp.net/goredirects</code>. All that is needed is a static HTML page at <code>bramp.net/goredirects</code>, containing the following <code>&lt;meta&gt;</code> tag pointing at GitHub.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">meta</span> <span class="na">name</span><span class="o">=</span><span class="s">go-import</span>
</span></span><span class="line"><span class="cl">  <span class="na">content</span><span class="o">=</span><span class="s">&#34;bramp.net/goredirects git https://github.com/bramp/goredirects.git&#34;</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Incase a user attempted to visit that page directly with their web browser, it is worthwhile
placing more information about the project on the page, or simply making the page redirect.</p>
<p>To help make these redirect pages, I wrote a simple go tool, <a href="https://github.com/bramp/goredirects"><code>goredirects</code></a>, that inspects all local repositories under a vanity domain directory in the local <code>$GOPATH/src/</code> and outputs static HTML pages that can be hosted on that domain.</p>
<p>For example, create your new project on GitHub, but check out the project under <code>$GOPATH/src/example.com/project</code>. Then run the tool:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ go install bramp.net/goredirects
</span></span><span class="line"><span class="cl">$ goredirects example.com outputdir
</span></span></code></pre></div><p>The directory <code>outputdir</code> will now contain multiple directories and html files, one for each project under <code>$GOPATH/src/example.com</code>. These HTML files contain the appropriate goimports meta tag to redirect the download of source code from the vanity name, to GitHub. Just upload these files to your website, voilà you are done. Examples of these vanity redirect files can be found on bramp.net, e.g <a href="https://bramp.net/goredirects/index.html">bramp.net/goredirects/index.html</a>. This tool even works for packages with sub-packages under the main root.</p>
<p>Finally, it is possible to ensure that if someone finds your project via GitHub, that <code>go get</code> will always place it under your vanity domain. This be can be achieved with an <a href="https://golang.org/cmd/go/#hdr-Import_path_checking">import comment</a>. Within the source code, ensure that at least one of the files in your page has a comment like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">project</span><span class="w"> </span><span class="c1">// import &#34;example.com/project&#34;</span><span class="w">
</span></span></span></code></pre></div><p>Then <code>go get</code> will enforce the correct/vanity URL to use, instead of the true location.</p>
<p>More helpful links on the topic:</p>
<ul>
<li><a href="https://golang.org/cmd/go/#hdr-Import_path_checking">golang.org/cmd/go/#hdr-Import_path_checking</a></li>
<li><a href="https://golang.org/cmd/go/#hdr-Remote_import_paths">golang.org/cmd/go/#hdr-Remote_import_paths</a></li>
<li><a href="https://golang.org/doc/go1.4#canonicalimports">golang.org/doc/go1.4#canonicalimports</a></li>
<li><a href="https://godoc.org/golang.org/x/tools/cmd/fiximports">godoc.org/golang.org/x/tools/cmd/fiximports</a></li>
<li><a href="https://texlution.com/post/golang-canonical-import-paths/">texlution.com/post/golang-canonical-import-paths/</a></li>
</ul>
</description>
    </item>
    
    <item>
      <title>Peano Curves</title>
      <link>https://blog.bramp.net/post/2016/08/08/peano-curves/</link>
      <pubDate>Mon, 08 Aug 2016 21:35:35 -0700</pubDate>
      
      <guid>https://blog.bramp.net/post/2016/08/08/peano-curves/</guid>
      <description><p>My latest addition to the <a href="https://github.com/bramp/hilbert">hilbert go library</a>, <a href="https://en.wikipedia.org/wiki/Peano_curve">Peano Curves</a>. The original space-filing curve, similar to the Hilbert curve, but a little more complex.</p>
<figure><img src="/post/2016/08/08/peano-curves/peano_animation.gif"><figcaption>
      <h4>Animation of Peano curve with N in the range 1..5</h4>
    </figcaption>
</figure>

</description>
    </item>
    
    <item>
      <title>Introducing Prob.js</title>
      <link>https://blog.bramp.net/post/2016/08/08/introducing-prob.js/</link>
      <pubDate>Mon, 08 Aug 2016 21:33:33 -0700</pubDate>
      
      <guid>https://blog.bramp.net/post/2016/08/08/introducing-prob.js/</guid>
      <description><h2 id="generate-random-numbers-from-different-probability-distributions">Generate random numbers from different probability distributions</h2>
<p>There are multiple libraries for generating random numbers from a uniform, and sometimes normal distributions. However,
I needed code to generate them from a expontential or lognormal distribution. I had written code to do this ~10 years ago
in Java, but I needed a more modern Javascript solution.</p>
<p>Introducing <a href="https://github.com/bramp/prob.js">Prob.js</a>, a javascript library to generate random numbers from different probability distributions. Avaiable via both bower and NPM, prob.js can generate random numbers from the following distrubtions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">Prob</span><span class="p">.</span><span class="nx">uniform</span><span class="p">(</span><span class="nx">min</span><span class="p">,</span> <span class="nx">max</span><span class="p">)</span> <span class="c1">// Uniform distribution in range [min, max).
</span></span></span><span class="line"><span class="cl"><span class="nx">Prob</span><span class="p">.</span><span class="nx">normal</span><span class="p">(</span><span class="nx">μ</span><span class="p">,</span> <span class="nx">σ</span><span class="p">)</span>      <span class="c1">// Normal distribution with mean and standard deviation.
</span></span></span><span class="line"><span class="cl"><span class="nx">Prob</span><span class="p">.</span><span class="nx">exponential</span><span class="p">(</span><span class="nx">λ</span><span class="p">)</span>    <span class="c1">// Exponential distribution with lambda.
</span></span></span><span class="line"><span class="cl"><span class="nx">Prob</span><span class="p">.</span><span class="nx">lognormal</span><span class="p">(</span><span class="nx">μ</span><span class="p">,</span> <span class="nx">σ</span><span class="p">)</span>   <span class="c1">// Log-normal distribution defined as ln(normal(μ, σ)).
</span></span></span><span class="line"><span class="cl"><span class="nx">Prob</span><span class="p">.</span><span class="nx">poisson</span><span class="p">(</span><span class="nx">λ</span><span class="p">)</span>        <span class="c1">// Poisson distribution returning integers &gt;= 0.
</span></span></span><span class="line"><span class="cl"><span class="nx">Prob</span><span class="p">.</span><span class="nx">zipf</span><span class="p">(</span><span class="nx">s</span><span class="p">,</span> <span class="nx">N</span><span class="p">)</span>        <span class="c1">// Zipf&#39;s distribution returning integers in range [1, N].
</span></span></span><span class="line"><span class="cl"><span class="nx">After</span> <span class="nx">generating</span> <span class="nx">a</span> <span class="nx">distribution</span><span class="p">,</span> <span class="nx">the</span> <span class="nx">following</span> <span class="nx">methods</span> <span class="nx">are</span> <span class="nx">available</span><span class="o">:</span>
</span></span></code></pre></div><p>With a very simple to use API:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">r</span> <span class="o">=</span> <span class="nx">Prob</span><span class="p">.</span><span class="nx">exponential</span><span class="p">(</span><span class="mf">1.0</span><span class="p">);</span> <span class="c1">// Create a distribution.
</span></span></span><span class="line"><span class="cl"><span class="nx">r</span><span class="p">()</span>        <span class="c1">// Generates a number within the distribution.
</span></span></span><span class="line"><span class="cl"><span class="nx">r</span><span class="p">(</span><span class="nx">src</span><span class="p">)</span>     <span class="c1">// Generates a number using a `src` of random numbers. (See note below.)
</span></span></span><span class="line"><span class="cl"><span class="nx">r</span><span class="p">.</span><span class="nx">Min</span>      <span class="c1">// The min random number which could be returned by `r()` (inclusive).
</span></span></span><span class="line"><span class="cl"><span class="nx">r</span><span class="p">.</span><span class="nx">Max</span>      <span class="c1">// The max random number which could be returned by `r()` (exclusive).
</span></span></span><span class="line"><span class="cl"><span class="nx">r</span><span class="p">.</span><span class="nx">Mean</span>     <span class="c1">// The expected mean for this distribution.
</span></span></span><span class="line"><span class="cl"><span class="nx">r</span><span class="p">.</span><span class="nx">Variance</span> <span class="c1">// The expected variance for this distribution.
</span></span></span></code></pre></div><p>I created a <a href="https://bramp.github.io/prob.js/">quick demo site</a> that generates 1 million random numbers from each distribution in the browser, and plots the PDF as it goes. Same samples:</p>
<p><figure><img src="/post/2016/08/08/introducing-prob.js/normal.png"><figcaption>
      <h4>Normal (μ = 0, σ = 1.0)</h4>
    </figcaption>
</figure>

<figure><img src="/post/2016/08/08/introducing-prob.js/lognormal.png"><figcaption>
      <h4>Log-normal (μ = 0, σ = 1.0)</h4>
    </figcaption>
</figure>

<figure><img src="/post/2016/08/08/introducing-prob.js/zipf.png"><figcaption>
      <h4>Zipf (s = 1, N = 100)</h4>
    </figcaption>
</figure>
</p>
</description>
    </item>
    
    <item>
      <title>Turn on HTTPS for all GitHub Pages</title>
      <link>https://blog.bramp.net/post/2016/06/08/turn-on-github-io-ssl/</link>
      <pubDate>Wed, 08 Jun 2016 19:37:47 -0700</pubDate>
      
      <guid>https://blog.bramp.net/post/2016/06/08/turn-on-github-io-ssl/</guid>
      <description><p>GitHub just <a href="https://github.com/blog/2186-https-for-github-pages">announced</a> that all github.io sites can enforce the use of HTTPS. Previously GitHub supported HTTPS on these sites, but you couldn&rsquo;t force users to use HTTPS other than using a <a href="https://gist.github.com/konklone/9968713">javascript redirect hack</a>, or putting a CDN infront of GitHub. Now by checking a single box you can force users to the secure version:</p>
<p><img src="checkbox.png" alt="Enforce HTTPS Checkbox"></img></p>
<p>Sadly I have far too many repositories, and I don&rsquo;t recall which one uses pages. I figured it would be easy to hit <a href="https://developer.github.com/v3/">GitHub&rsquo;s API</a> and enabled this. The API doesn&rsquo;t directly support enabling HTTPS, so instead I wrote a quick script to list all repos with GitHub pages:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="ch">#!/usr/bin/env python</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Prints a list of all owned repositories with pages.</span>
</span></span><span class="line"><span class="cl"><span class="c1"># by Andrew Brampton 2016 https://bramp.net</span>
</span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="s1">&#39;token XXXXX&#39;</span><span class="p">}</span> <span class="c1"># Replace XXXX with a token from https://github.com/settings/tokens</span>
</span></span><span class="line"><span class="cl"><span class="n">params</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;type&#39;</span><span class="p">:</span> <span class="s1">&#39;owner&#39;</span><span class="p">,</span> <span class="s1">&#39;page&#39;</span><span class="p">:</span> <span class="mi">1</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">	<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;https://api.github.com/user/repos&#39;</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="n">repos</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span> <span class="ow">not</span> <span class="n">repos</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">		<span class="k">break</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">for</span> <span class="n">repo</span> <span class="ow">in</span> <span class="n">repos</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">		<span class="k">if</span> <span class="n">repo</span><span class="p">[</span><span class="s1">&#39;has_pages&#39;</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">			<span class="nb">print</span> <span class="s2">&#34;</span><span class="si">%32s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">/settings&#34;</span> <span class="o">%</span><span class="p">(</span><span class="n">repo</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">],</span> <span class="n">repo</span><span class="p">[</span><span class="s1">&#39;html_url&#39;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="n">params</span><span class="p">[</span><span class="s1">&#39;page&#39;</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
</span></span></code></pre></div><p>Download <a href="turn-on-github-ssl.py">turn-on-github-ssl.py</a></p>
<p>This print out something like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ ./turn-on-github-ssl.py
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                blog https://github.com/bramp/blog/settings
</span></span><span class="line"><span class="cl">  ffmpeg-cli-wrapper https://github.com/bramp/ffmpeg-cli-wrapper/settings
</span></span><span class="line"><span class="cl">js-sequence-diagrams https://github.com/bramp/js-sequence-diagrams/settings
</span></span><span class="line"><span class="cl">           js-sudoku https://github.com/bramp/js-sudoku/settings
</span></span><span class="line"><span class="cl">        nodewii-talk https://github.com/bramp/nodewii-talk/settings
</span></span><span class="line"><span class="cl">             prob.js https://github.com/bramp/prob.js/settings
</span></span><span class="line"><span class="cl">                <span class="nb">test</span> https://github.com/bramp/test/settings
</span></span><span class="line"><span class="cl">              unsafe https://github.com/bramp/unsafe/settings
</span></span><span class="line"><span class="cl">...
</span></span></code></pre></div><p>Now click on each URL, and just check the box.</p>
</description>
    </item>
    
    <item>
      <title>Most starred project this week, and second most forked.</title>
      <link>https://blog.bramp.net/post/2013/03/25/most-starred-project-this-week/</link>
      <pubDate>Mon, 25 Mar 2013 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2013/03/25/most-starred-project-this-week/</guid>
      <description><p>After getting my <a href="https://bramp.github.io/js-sequence-diagrams/">js-sequence-diagrams</a> project onto <a href="https://news.ycombinator.com/item?id=5432110">Hacker News</a>, the popularity has gone viral.</p>
<div class="text-center">
    <a href="https://github.com/languages/JavaScript">
		<img src="github-most-starred.png" alt="github-most-starred" width="619" height="678" />
	</a>
</div>
</description>
    </item>
    
  </channel>
</rss>
