From 0f359855e2d00ae2addc27666b8727a60dfb1aff Mon Sep 17 00:00:00 2001 From: Rohan Verma Date: Thu, 7 Nov 2019 01:00:31 +0530 Subject: [PATCH 1/6] blog: Containerized development workflow using remote gopls server --- .drone.yml | 28 ++++- content/blog/2019-08-04.md | 2 +- .../2019-10-25-paisavasool-hackinout-2019.md | 2 +- content/blog/2019-11-05-docker-gopls.md | 103 ++++++++++++++++++ 4 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 content/blog/2019-11-05-docker-gopls.md diff --git a/.drone.yml b/.drone.yml index 927907f..4096f96 100644 --- a/.drone.yml +++ b/.drone.yml @@ -2,11 +2,9 @@ kind: pipeline type: docker name: default -trigger: - branch: - - master + steps: - - name: ssh commands + - name: ssh commands for rohanverma.net image: appleboy/drone-ssh settings: host: 159.89.175.2 @@ -15,6 +13,9 @@ steps: key: from_secret: ssh_key script_stop: true + trigger: + branch: + - master script: - cd /home/rhnvrm/apps/rohanverma.net - git fetch origin @@ -22,3 +23,22 @@ steps: - cd /home/rhnvrm/proxy - docker-compose build rohanvermanet - docker-compose up -d rohanvermanet + - name: ssh commands for next.rohanverma.net + image: appleboy/drone-ssh + settings: + host: 159.89.175.2 + username: deploy + port: 22 + key: + from_secret: ssh_key + script_stop: true + trigger: + branch: + - develop + script: + - cd /home/rhnvrm/apps/rohanverma.net + - git fetch origin + - git checkout origin/develop + - cd /home/rhnvrm/proxy + - docker-compose build nextrohanvermanet + - docker-compose up -d nextrohanvermanet \ No newline at end of file diff --git a/content/blog/2019-08-04.md b/content/blog/2019-08-04.md index 1a2db1e..826f72b 100644 --- a/content/blog/2019-08-04.md +++ b/content/blog/2019-08-04.md @@ -5,7 +5,7 @@ date = "2019-06-26T07:30:00+00:00" draft = true tags = ["books"] title = "Deep Work by Cal Newport - A summary" -type = "" +type = "post" url = "blog/2019/06/26/deep-work-a-summary" +++ diff --git a/content/blog/2019-10-25-paisavasool-hackinout-2019.md b/content/blog/2019-10-25-paisavasool-hackinout-2019.md index 2ca5975..ecfc21f 100644 --- a/content/blog/2019-10-25-paisavasool-hackinout-2019.md +++ b/content/blog/2019-10-25-paisavasool-hackinout-2019.md @@ -90,5 +90,5 @@ We figured out that: - The user can check the state and see all his transactions from our app. ## Future -- The [Sahamati framework](http://www.sahamati.org/) in the future will allow users to share their bank transaction ledger details with apps directly in a standardized format via Aggregators. +- The [Sahamati framework](https://sahamati.org.in/) in the future will allow users to share their bank transaction ledger details with apps directly in a standardized format via Aggregators. - UPI roadmap has split requests planned for the future. \ No newline at end of file diff --git a/content/blog/2019-11-05-docker-gopls.md b/content/blog/2019-11-05-docker-gopls.md new file mode 100644 index 0000000..c1a6754 --- /dev/null +++ b/content/blog/2019-11-05-docker-gopls.md @@ -0,0 +1,103 @@ ++++ +title = "Containerized development workflow using remote gopls server" +date = 2019-11-05T15:30:03+05:30 +draft = false +categories = ["golang"] +type = "post" +url = "blog/2019/11/05/containerized-dev-using-remote-gopls" +author = "Rohan Verma" ++++ + +If your CGO development toolchain depends on external dependencies such +as system libraries, or you want to develop on an older version of +go while having a different version on your host, you can use a docker container and mount the source from your host machine and build the project inside the +container. This can enable us to have a consistent development environment across +various developers and their host systems without having to modify system +libraries. + +This article is a follow up to my previous article on [using containers +to develop on archaic projects](/blog/2019/08/04/docker-containers-to-build-archaic-projects/) +that require specific system libraries. Last time I discussed how to create a +container having all the dependencies and dev tools installed and use them to +operate on the host file system. Taking this a step forward, +the biggest roadblock that arises with this approach is that our host machine +now loses the ability to run gotools on our source code. That means your editor +cannot run any of the tools you depend on to write, lint, or format your go +source code. + +To overcome this, we can use the experimental [remote lsp server](https://godoc.org/golang.org/x/tools/internal/lsp/cmd#Application) +feature available in gopls. [gopls](https://github.com/golang/tools/tree/master/gopls) (pronounced: "go please") is the official language server for the Go language. +With this mode, the gopls running on the host +forwards all the commands to the gopls in our container. This way the host system +does not need to have any of the dependencies installed and can then use the +container gopls server to modify the source in the editor of the host. + +Let us look at the Dockerfile for this system. + +```Dockerfile +FROM ubuntu:xenial AS builder +RUN apt-get update +# Install system dependencies that we might need +RUN apt-get install -y gcc g++ + +# Install Depencies like Go and Swig in our container. +WORKDIR /tmp +# Install Go +RUN wget https://dl.google.com/go/go1.12.9.linux-amd64.tar.gz +RUN tar -C /usr/local -xzf go1.12.9.linux-amd64.tar.gz +# Install Swig +RUN wget http://prdownloads.sourceforge.net/swig/swig-4.0.1.tar.gz +RUN tar -zxvf swig-4.0.1.tar.gz +RUN cd /tmp/swig-4.0.1 && ./configure && make && make install + +# Create user +RUN useradd -m -r -u 1000 myuser +RUN groupmod -g 1000 myuser + +# Replicate/fake the host system tree +RUN mkdir -p /home/myuser/code/go/myhostdir/myproject +RUN chown -R myuser:myuser /home/myuser/code/go/myhostdir/myproject +USER myuser + +WORKDIR /home/myuser/code/go/myhostdir/myproject + +RUN GO111MODULE=on go get golang.org/x/tools/gopls@latest +CMD gopls -listen=":7050" +``` + +Firstly, we install all the dependencies and then create +a user which will have access to the source code. + +Then we have to replicate the +host path in the container and set that as our work directory. This is a quirk +of gopls, if there is a mismatch in the path, the host will communicate the +wrong path to the server running in the container and will be unable to find it +inside the container. + +Finally, we install gopls in the container and then start it in the container +with the `-listen=":7050"` flag. + + +Now we can expose this port to our host machine. + +```bash +docker run -d --name "myproject" -u `id -u` -p 7050:7050 \ + -v /home/myuser/code/go/myhostdir/myproject:/home/myuser/code/go/myhostdir/ \ + myproject myproject:latest +``` + +Notice, that we also mount the host source in the container with the same path, +the reason is explained above. + +We must now add the following flag to your editor config along with any other +flags we use for the language server to connect to the remote gopls server. + +```bash +gopls -remote "localhost:7050" +``` + +After adding this flag, you will now be able to edit your source with all the +added benefits that come with a language server. + +Since this is an experimental feature, it might break (a lot). Do let me know +in the comments if this was helpful for you. \ No newline at end of file From 064a2e5d524bd05add0a05d8555053ff2279df8e Mon Sep 17 00:00:00 2001 From: Rohan Verma Date: Thu, 7 Nov 2019 01:03:39 +0530 Subject: [PATCH 2/6] fix: only trigger on correct branch --- .drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index 4096f96..9a14c48 100644 --- a/.drone.yml +++ b/.drone.yml @@ -13,7 +13,7 @@ steps: key: from_secret: ssh_key script_stop: true - trigger: + when: branch: - master script: @@ -32,7 +32,7 @@ steps: key: from_secret: ssh_key script_stop: true - trigger: + when: branch: - develop script: From 3e24e08d896cda048ced624e5dad9a632f57655a Mon Sep 17 00:00:00 2001 From: Rohan Verma Date: Thu, 7 Nov 2019 01:07:46 +0530 Subject: [PATCH 3/6] fix: move when outside into step --- .drone.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.drone.yml b/.drone.yml index 9a14c48..5d88b39 100644 --- a/.drone.yml +++ b/.drone.yml @@ -6,6 +6,9 @@ name: default steps: - name: ssh commands for rohanverma.net image: appleboy/drone-ssh + when: + branch: + - master settings: host: 159.89.175.2 username: deploy @@ -13,9 +16,6 @@ steps: key: from_secret: ssh_key script_stop: true - when: - branch: - - master script: - cd /home/rhnvrm/apps/rohanverma.net - git fetch origin @@ -25,6 +25,9 @@ steps: - docker-compose up -d rohanvermanet - name: ssh commands for next.rohanverma.net image: appleboy/drone-ssh + when: + branch: + - develop settings: host: 159.89.175.2 username: deploy @@ -32,9 +35,6 @@ steps: key: from_secret: ssh_key script_stop: true - when: - branch: - - develop script: - cd /home/rhnvrm/apps/rohanverma.net - git fetch origin From dba5baceb25dd60bd63c720dce158e02e7e24eff Mon Sep 17 00:00:00 2001 From: Rohan Verma Date: Thu, 7 Nov 2019 01:09:59 +0530 Subject: [PATCH 4/6] fix: folder for next.rohanverma.net --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 5d88b39..651b629 100644 --- a/.drone.yml +++ b/.drone.yml @@ -36,7 +36,7 @@ steps: from_secret: ssh_key script_stop: true script: - - cd /home/rhnvrm/apps/rohanverma.net + - cd /home/rhnvrm/apps/next.rohanverma.net - git fetch origin - git checkout origin/develop - cd /home/rhnvrm/proxy From c55cef95098d9dcb6682359dd58a1b9cfc7a429f Mon Sep 17 00:00:00 2001 From: Rohan Verma Date: Thu, 7 Nov 2019 01:24:43 +0530 Subject: [PATCH 5/6] fix: bundle darkmode --- content/static/js/darkmode.mjs | 2 ++ layouts/partials/body/scripts.html | 2 +- layouts/partials/head/custom.html | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 content/static/js/darkmode.mjs diff --git a/content/static/js/darkmode.mjs b/content/static/js/darkmode.mjs new file mode 100644 index 0000000..2de0f18 --- /dev/null +++ b/content/static/js/darkmode.mjs @@ -0,0 +1,2 @@ +// @license © 2019 Google LLC. Licensed under the Apache License, Version 2.0. +const e=document;const i=localStorage;const t="prefers-color-scheme";const s="media";const o="light";const a="dark";const n="no-preference";const r=`(${t}:${a})`;const h=`(${t}:${o}),(${t}:${n})`;const l="link[rel=stylesheet]";const c="remember";const d="legend";const b="toggle";const m="switch";const g="appearance";const u="permanent";const p="mode";const k="colorschemechange";const f="permanentcolorscheme";const v="all";const $="not all";const L="dark-mode-toggle";const x="https://googlechromelabs.github.io/dark-mode-toggle/demo/";const y=(e,i,t=i)=>{Object.defineProperty(e,t,{enumerable:true,get(){const e=this.getAttribute(i);return e===null?"":e},set(e){this.setAttribute(i,e)}})};const w=(e,i,t=i)=>{Object.defineProperty(e,t,{enumerable:true,get(){return this.hasAttribute(i)},set(e){if(e){this.setAttribute(i,"")}else{this.removeAttribute(i)}}})};const C=e.createElement("template");C.innerHTML=`
`;export class DarkModeToggle extends HTMLElement{static get observedAttributes(){return[p,g,u,d,o,a,c]}constructor(){super();y(this,p);y(this,g);y(this,d);y(this,o);y(this,a);y(this,c);w(this,u);this.i=null;this.t=null;e.addEventListener(k,e=>{this.mode=e.detail.colorScheme;this.s();this.o()});e.addEventListener(f,e=>{this.permanent=e.detail.permanent;this.h.checked=this.permanent});this.l()}l(){const c=this.attachShadow({mode:"closed"});c.appendChild(C.content.cloneNode(true));this.i=e.querySelectorAll(`${l}[${s}*=${t}][${s}*="${a}"]`);this.t=e.querySelectorAll(`${l}[${s}*=${t}][${s}*="${o}"],${l}[${s}*=${t}][${s}*="${n}"]`);this.m=c.querySelector("#lightRadio");this.g=c.querySelector("#lightLabel");this.u=c.querySelector("#darkRadio");this.p=c.querySelector("#darkLabel");this.k=c.querySelector("#darkCheckbox");this.v=c.querySelector("#checkboxLabel");this.$=c.querySelector("legend");this.L=c.querySelector("aside");this.h=c.querySelector("#permanentCheckbox");this.C=c.querySelector("#permanentLabel");const d=matchMedia(r).media!==$;if(d){matchMedia(r).addListener(({matches:e})=>{this.mode=e?a:o;this.M(k,{colorScheme:this.mode})})}const m=i.getItem(L);if(m&&[a,o].includes(m)){this.mode=m;this.h.checked=true;this.permanent=true}else if(d){this.mode=matchMedia(h).matches?o:a}if(!this.mode){this.mode=o}if(this.permanent&&!m){i.setItem(L,this.mode)}if(!this.appearance){this.appearance=b}this.R();this.s();this.o();[this.m,this.u].forEach(e=>{e.addEventListener("change",()=>{this.mode=this.m.checked?o:a;this.o();this.M(k,{colorScheme:this.mode})})});this.k.addEventListener("change",()=>{this.mode=this.k.checked?a:o;this.s();this.M(k,{colorScheme:this.mode})});this.h.addEventListener("change",()=>{this.permanent=this.h.checked;this.M(f,{permanent:this.permanent})});this._();this.M(k,{colorScheme:this.mode});this.M(f,{permanent:this.permanent})}attributeChangedCallback(e,t,s){if(e===p){if(![o,a].includes(s)){throw new RangeError(`Allowed values: "${o}" and "${a}".`)}if(matchMedia("(hover:none)").matches&&this.remember){this.A()}if(this.permanent){i.setItem(L,this.mode)}this.s();this.o();this._()}else if(e===g){if(![b,m].includes(s)){throw new RangeError(`Allowed values: "${b}" and "${m}".`)}this.R()}else if(e===u){if(this.permanent){i.setItem(L,this.mode)}else{i.removeItem(L)}this.h.checked=this.permanent}else if(e===d){this.$.textContent=s}else if(e===c){this.C.textContent=s}else if(e===o){this.g.textContent=s;if(this.mode===o){this.v.textContent=s}}else if(e===a){this.p.textContent=s;if(this.mode===a){this.v.textContent=s}}}M(e,i){this.dispatchEvent(new CustomEvent(e,{bubbles:true,composed:true,detail:i}))}R(){const e=this.appearance===b;this.m.hidden=e;this.g.hidden=e;this.u.hidden=e;this.p.hidden=e;this.k.hidden=!e;this.v.hidden=!e}s(){if(this.mode===o){this.m.checked=true}else{this.u.checked=true}}o(){if(this.mode===o){this.v.style.setProperty(`--${L}-checkbox-icon`,`var(--${L}-light-icon,url("${x}moon.png"))`);this.v.textContent=this.light;this.k.checked=false}else{this.v.style.setProperty(`--${L}-checkbox-icon`,`var(--${L}-dark-icon,url("${x}sun.png"))`);this.v.textContent=this.dark;this.k.checked=true}}_(){if(this.mode===o){this.t.forEach(e=>{e.media=v;e.disabled=false});this.i.forEach(e=>{e.media=$;e.disabled=true})}else{this.i.forEach(e=>{e.media=v;e.disabled=false});this.t.forEach(e=>{e.media=$;e.disabled=true})}}A(){this.L.style.visibility="visible";setTimeout(()=>{this.L.style.visibility="hidden"},3e3)}}customElements.define(L,DarkModeToggle); \ No newline at end of file diff --git a/layouts/partials/body/scripts.html b/layouts/partials/body/scripts.html index 6634d31..7916a40 100644 --- a/layouts/partials/body/scripts.html +++ b/layouts/partials/body/scripts.html @@ -1,5 +1,5 @@ \ No newline at end of file + \ No newline at end of file From 995dd9f8f3fb7e1dcba3d687f1da017ab13bf550 Mon Sep 17 00:00:00 2001 From: Rohan Verma Date: Thu, 7 Nov 2019 01:30:55 +0530 Subject: [PATCH 6/6] fix: send mjs as text/javascript --- content/static/js/{darkmode.mjs => darkmode.js} | 0 layouts/partials/body/scripts.html | 2 +- layouts/partials/head/custom.html | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename content/static/js/{darkmode.mjs => darkmode.js} (100%) diff --git a/content/static/js/darkmode.mjs b/content/static/js/darkmode.js similarity index 100% rename from content/static/js/darkmode.mjs rename to content/static/js/darkmode.js diff --git a/layouts/partials/body/scripts.html b/layouts/partials/body/scripts.html index 7916a40..075d8be 100644 --- a/layouts/partials/body/scripts.html +++ b/layouts/partials/body/scripts.html @@ -1,5 +1,5 @@ \ No newline at end of file + \ No newline at end of file