diff --git a/.drone.yml b/.drone.yml index 927907f..651b629 100644 --- a/.drone.yml +++ b/.drone.yml @@ -2,12 +2,13 @@ kind: pipeline type: docker name: default -trigger: - branch: - - master + steps: - - name: ssh commands + - name: ssh commands for rohanverma.net image: appleboy/drone-ssh + when: + branch: + - master settings: host: 159.89.175.2 username: deploy @@ -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 + when: + branch: + - develop + settings: + host: 159.89.175.2 + username: deploy + port: 22 + key: + from_secret: ssh_key + script_stop: true + script: + - cd /home/rhnvrm/apps/next.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 diff --git a/content/static/js/darkmode.js b/content/static/js/darkmode.js new file mode 100644 index 0000000..2de0f18 --- /dev/null +++ b/content/static/js/darkmode.js @@ -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..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