<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Boris Jamot ✊ /</title>
    <description>The latest articles on DEV Community by Boris Jamot ✊ / (@biros).</description>
    <link>https://dev.to/biros</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F92151%2F877c4dbf-c4c1-4395-9329-c8af191aa66e.png</url>
      <title>DEV Community: Boris Jamot ✊ /</title>
      <link>https://dev.to/biros</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/biros"/>
    <language>en</language>
    <item>
      <title>Consistent Developer Journey with Dracula 🧛‍♂️</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Tue, 13 Aug 2019 17:50:17 +0000</pubDate>
      <link>https://dev.to/biros/consistent-developer-journey-with-dracula-5bae</link>
      <guid>https://dev.to/biros/consistent-developer-journey-with-dracula-5bae</guid>
      <description>&lt;p&gt;Recently, I've customized all my favorite apps with &lt;a href="https://draculatheme.com"&gt;Dracula theme&lt;/a&gt;. As the Dracula team does a great job, I quickly found themes for the following apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VSCode&lt;/li&gt;
&lt;li&gt;Intellij&lt;/li&gt;
&lt;li&gt;Vim&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are also many Dracula themes for Firefox. I choose &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/klorax-dracula/"&gt;Klorax' one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then, I wanted to go further and have the same journey in my terminal emulator. Fortunately, the &lt;a href="https://github.com/linuxdeepin/deepin-terminal"&gt;deepin-terminal&lt;/a&gt; comes with a lot of bundled themes, including Dracula.&lt;/p&gt;

&lt;p&gt;But as a Tmux user, I was a bit frustrated as the status line I used had nothing to do with Dracula. And there was no Dracula theme for Tmux. So I created one:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mamyn0va"&gt;
        mamyn0va
      &lt;/a&gt; / &lt;a href="https://github.com/mamyn0va/tmux-dracula"&gt;
        tmux-dracula
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🔥 Awesome .tmux.conf configuration file with Dracula theme 🧛‍♂️ and task support.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
tmux-dracula&lt;/h1&gt;
&lt;div&gt;&lt;a rel="noopener noreferrer" href="https://camo.githubusercontent.com/30160ca35814e779a8447209d4d7c8ab65e8f6d6/68747470733a2f2f64726163756c617468656d652e636f6d2f7374617469632f696d672f69636f6e732f64726163756c612e737667"&gt;&lt;img src="https://camo.githubusercontent.com/30160ca35814e779a8447209d4d7c8ab65e8f6d6/68747470733a2f2f64726163756c617468656d652e636f6d2f7374617469632f696d672f69636f6e732f64726163756c612e737667" width="400"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Self-contained, pretty and versatile &lt;code&gt;.tmux.conf&lt;/code&gt; configuration file with &lt;a href="https://draculatheme.com/" rel="nofollow"&gt;Dracula theme&lt;/a&gt; and task support.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://user-images.githubusercontent.com/11281228/62902826-15feac80-bd61-11e9-8d25-d5b1bb1770fc.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nf6PaV_h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/11281228/62902826-15feac80-bd61-11e9-8d25-d5b1bb1770fc.png" alt="Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;p&gt;Requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tmux &lt;strong&gt;&lt;code&gt;&amp;gt;= 2.1&lt;/code&gt;&lt;/strong&gt; running inside Linux, Mac, OpenBSD, Cygwin or WSL (Bash on
Ubuntu on Windows)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://taskwarrior.org/" rel="nofollow"&gt;taskwarrior&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;outside of tmux, &lt;code&gt;$TERM&lt;/code&gt; must be set to &lt;code&gt;xterm-256color&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To install, run the following from your terminal: (you may want to backup your
existing &lt;code&gt;~/.tmux.conf&lt;/code&gt; first)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cd
$ git clone git@github.com:mamyn0va/tmux-dracula.git .tmux
$ ln -s -f .tmux/.tmux.conf
$ cp .tmux/.tmux.conf.local
$ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then reload your tmux conf:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tmux source ~/.tmux.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then install the required plugins by pressing &lt;code&gt;prefix&lt;/code&gt; + I (capital i, as in &lt;strong&gt;I&lt;/strong&gt;nstall) to fetch the plugins using &lt;code&gt;tpm&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally proceed to &lt;a href="https://raw.githubusercontent.com/mamyn0va/tmux-dracula/master/#enabling-the-powerline-look"&gt;customize&lt;/a&gt; your &lt;code&gt;~/.tmux.conf.local&lt;/code&gt; copy.&lt;/p&gt;
&lt;p&gt;If you're a Vim user, setting the &lt;code&gt;$EDITOR&lt;/code&gt; environment variable to &lt;code&gt;vim&lt;/code&gt; will
enable and further customize the vi-style key bindings (see tmux manual).&lt;/p&gt;
&lt;p&gt;If you're new to tmux, I recommend…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mamyn0va/tmux-dracula"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;In fact, I just forked the awesome Tmux conf from &lt;a href="https://github.com/gpakosz/.tmux"&gt;gpakosz&lt;/a&gt; and I changed the colors according to the &lt;a href="https://github.com/dracula/dracula-theme/#color-palette"&gt;color palette of Dracula&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Et voilà!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lBqbNbGE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cn3qgitf5xx7kr223adt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lBqbNbGE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cn3qgitf5xx7kr223adt.png" alt="screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The shell in the screenshot is &lt;a href="https://fishshell.com/"&gt;fish&lt;/a&gt; with &lt;a href="https://github.com/matchai/spacefish"&gt;SpaceFish&lt;/a&gt; prompt.&lt;/p&gt;

&lt;p&gt;If you're looking to have the same look and feel when listing your folders (&lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;ll&lt;/code&gt; or &lt;code&gt;lla&lt;/code&gt;), I created a &lt;a href="https://github.com/mamyn0va/dotfiles-home/blob/master/.config/colorls/dark_colors.yaml"&gt;Dracula theme for colorls&lt;/a&gt; which is a drop-in replacement for &lt;code&gt;ls&lt;/code&gt; unix command.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And you're done!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>dracula</category>
      <category>theme</category>
    </item>
    <item>
      <title>It's Been One Year ! 🎉 🎂 🏆</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Mon, 12 Aug 2019 21:02:02 +0000</pubDate>
      <link>https://dev.to/biros/it-s-been-one-year-31ga</link>
      <guid>https://dev.to/biros/it-s-been-one-year-31ga</guid>
      <description>&lt;p&gt;Hi all!&lt;/p&gt;

&lt;p&gt;It's been one year since I joined the dev.to community.&lt;/p&gt;

&lt;p&gt;During this year:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✍️ I wrote 21 posts&lt;/li&gt;
&lt;li&gt;👍 I followed 60 people&lt;/li&gt;
&lt;li&gt;😍 I got 1877 posts reactions&lt;/li&gt;
&lt;li&gt;🤩 I got 4367 followers&lt;/li&gt;
&lt;li&gt;👁 I got 56625 posts views&lt;/li&gt;
&lt;li&gt;🏆 I got 5 different badges&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But most of all, I found a very welcoming community.&lt;/p&gt;

&lt;p&gt;So, thanks to all of you for being so open-minded. I'm sure &lt;a class="comment-mentioned-user" href="https://dev.to/ben"&gt;@ben&lt;/a&gt;
 and the staff (&lt;a class="comment-mentioned-user" href="https://dev.to/thepracticaldev"&gt;@thepracticaldev&lt;/a&gt;
) will do everything to keep this good spirit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/SRO0ZwmImic0/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/SRO0ZwmImic0/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>birthday</category>
      <category>badge</category>
      <category>oneyearclub</category>
    </item>
    <item>
      <title>🔥 🤩 My Fucking Awesome Dev Setup 🤩 🔥</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Mon, 24 Jun 2019 09:28:34 +0000</pubDate>
      <link>https://dev.to/biros/my-fucking-awesome-dev-setup-bfn</link>
      <guid>https://dev.to/biros/my-fucking-awesome-dev-setup-bfn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was inspired by this other post I saw recently:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/deepu105" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F178939%2F38a82d99-3a0c-4a47-84fc-76fff3144cda.png" alt="deepu105"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/deepu105/my-beautiful-linux-development-environment-2afc" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;My beautiful Linux development environment&lt;/h2&gt;
      &lt;h3&gt;Deepu K Sasidharan ・ Jun 16 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#linux&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#fedora&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#development&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#gnome&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
It always amazes me that such weekly articles always get so popular. So I wrote another one.
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  🔍 Quick Overview
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;OS: &lt;a href="https://manjaro.org/" rel="noopener noreferrer"&gt;Manjaro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Windows Management: &lt;a href="https://www.deepin.org/en/dde/" rel="noopener noreferrer"&gt;Deepin Desktop Environment&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;IDE: &lt;a href="https://www.jetbrains.com/idea" rel="noopener noreferrer"&gt;Intellij&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Editor: &lt;a href="https://neovim.io/" rel="noopener noreferrer"&gt;Neovim&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Terminal: &lt;a href="http://guake-project.org/" rel="noopener noreferrer"&gt;Guake&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Shell: &lt;a href="https://fishshell.com/" rel="noopener noreferrer"&gt;Fish&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tools:

&lt;ul&gt;
&lt;li&gt;Terminal Multiplexer: &lt;a href="https://github.com/tmux/tmux/wiki" rel="noopener noreferrer"&gt;Tmux&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Universal Launcher: &lt;a href="https://github.com/albertlauncher/albert" rel="noopener noreferrer"&gt;Albert&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;File Watcher: &lt;a href="https://github.com/cortesi/modd" rel="noopener noreferrer"&gt;Modd&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h1&gt;
  
  
  🐧 Manjaro
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://manjaro.org/" rel="noopener noreferrer"&gt;Manjaro&lt;/a&gt; is a Linux distribution based on ArchLinux. It's a rolling release, which means that you get updates for your apps very quickly. It can be great for developers, because we don't want to wait to have security or featured updates, but it's also dangerous because such distro can break more easily. So install it at your own risk! That being said, I must tell you that I'm not a great expert of Linux, and I never got stuck with my Manjaro.&lt;/p&gt;

&lt;p&gt;Pacman is the default CLI package manager. It's very basic and rudimentary. Now I use &lt;a href="https://github.com/Jguer/yay" rel="noopener noreferrer"&gt;yay&lt;/a&gt; which is more user-friendly. If you prefer graphical apps, have a look at &lt;a href="https://gitlab.manjaro.org/applications/pamac" rel="noopener noreferrer"&gt;pamac&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  🗔 Deepin Desktop Environment
&lt;/h1&gt;

&lt;p&gt;When it comes to choosing the right desktop environment for a Linux distro, we're often forced to select the less horrible one. You may think I'm a bit excessive, but many well-known window managers (Gnome, KDE, Cinnamon, xfce, ...) are, in their default configuration, just awful.&lt;/p&gt;

&lt;p&gt;After having tried many of them (xfce, Gnome, Budgie, i3wm, awesomewm), I finally opted for &lt;a href="https://www.deepin.org/en/dde/" rel="noopener noreferrer"&gt;Deepin Desktop Environment&lt;/a&gt;. It works like a charm out-of-the-box and as I'm a lazy developer, it was just perfect for me. The &lt;em&gt;look and feel&lt;/em&gt; is clearly inspired by macOS. The dock is very similar, the settings panel also. It's both pure and elegant. Its main advantage is also its main drawback: it's quite not configurable at all. So either it fits your need, either you choose another one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deepin Apps Browser&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz7mflnhqnyc3cqcrn9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz7mflnhqnyc3cqcrn9u.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deepin Settings Panel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzll722vksrmz0qe773a9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzll722vksrmz0qe773a9.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deepin Quick Launcher&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flf34nzwutkuwoszm3qth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flf34nzwutkuwoszm3qth.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deepin File Manager&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznekwp9r7t0146wkfowy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznekwp9r7t0146wkfowy.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Albert
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/albertlauncher/albert" rel="noopener noreferrer"&gt;Albert&lt;/a&gt; is an &lt;a href="https://www.alfredapp.com/" rel="noopener noreferrer"&gt;Alfred&lt;/a&gt;-like launcher that brings you many features in a simple search bar. Just invoke it by some user-defined hotkey (I use &lt;code&gt;&amp;lt;ctrl&amp;gt;+SPC&lt;/code&gt;) and start typing!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8fzmkvoq2q7sajtm01ks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8fzmkvoq2q7sajtm01ks.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can trigger web searches, in-line translations, calculations, shell commands, ... and it's widely extendable with plugins.&lt;/p&gt;

&lt;h1&gt;
  
  
  👨🏼‍💻 Intellij Ultimate + Go plugin
&lt;/h1&gt;

&lt;p&gt;As a Go developer, I am very pragmatic. Thus, I chose the best tool for my needs, which is Intellij with Go plugin. It has all I need in a modern IDE: completion, browsing, debugging, refactoring, syntax highlighting, ... But it's not a definitive choice. I already tried, with more or less success, several other IDE: VSCode, Atom, Vim. While the first two didn't fully work out-of-the-box, the last (Vim) was pretty impressive (with &lt;a href="https://spacevim.org/" rel="noopener noreferrer"&gt;SpaceVim&lt;/a&gt;). But as I wasn't very comfortable with keyboard shortcuts, I finally dropped it for Intellij. I may reconsider this very soon...&lt;/p&gt;

&lt;h1&gt;
  
  
  👽 Guake + Tmux + Fish + Vim + Modd
&lt;/h1&gt;

&lt;p&gt;Under Linux, you need a shell to run commands. But this shell can't run alone. It needs a terminal emulator. So imagine you want to edit a file, you'll need to run a terminal emulator (say &lt;code&gt;xterm&lt;/code&gt;), that will launch your default shell (say &lt;code&gt;bash&lt;/code&gt;), and then you'll be able to run &lt;code&gt;vim&lt;/code&gt;. It's like russian dolls (xterm &amp;gt; bash &amp;gt; vim). And if you want to split your terminal in several panes, you'll need another layer between your terminal emulator and your shell: &lt;code&gt;tmux&lt;/code&gt; (xterm &amp;gt; tmux &amp;gt; bash &amp;gt; vim).&lt;/p&gt;

&lt;p&gt;🧙‍♂️ It's the magic of Unix interoperability: each app does its job well, and only its job.&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 Guake
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://guake-project.org/" rel="noopener noreferrer"&gt;Guake&lt;/a&gt; is a drop-down terminal inspired by the terminal used in the game Quake. I customized it to remove scrollbars, tab bar and title bar so that it just looks like a nude terminal. By default it's hidden and it appears when I press &lt;code&gt;&amp;lt;F12&amp;gt;&lt;/code&gt;. I go full screen with &lt;code&gt;&amp;lt;F11&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;My conf:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;font: &lt;a href="https://github.com/cstrap/monaco-font" rel="noopener noreferrer"&gt;Monaco for Powerline Regular, size 10&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;transparency: 10%&lt;/li&gt;
&lt;li&gt;default interpreter: tmux&lt;/li&gt;
&lt;li&gt;theme: molokai&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🤖 Tmux
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/tmux/tmux/wiki" rel="noopener noreferrer"&gt;Tmux&lt;/a&gt; is a powerful terminal multiplexer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frz5y3gmapdd2m5i5zvz3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frz5y3gmapdd2m5i5zvz3.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;screenshot by &lt;a href="https://github.com/gpakosz/.tmux" rel="noopener noreferrer"&gt;@gpakozs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I posted an article about my custom setup earlier this year. Have a look on it if you're interested:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/biros" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F92151%2F877c4dbf-c4c1-4395-9329-c8af191aa66e.png" alt="biros"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/biros/building-a-custom-ide-with-tmux-2aeg" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Building a Custom IDE with Tmux&lt;/h2&gt;
      &lt;h3&gt;Boris Jamot ✊ / ・ Feb 5 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#cli&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#showdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#craftsmanship&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#githunt&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  🐟 Fish shell
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://fishshell.com/" rel="noopener noreferrer"&gt;Fish&lt;/a&gt; is a user-oriented shell with powerful features like auto-suggestion, completion, command colors, ...&lt;/p&gt;

&lt;p&gt;As the shell is the place I spend most time in, I need to have the most useful and clear information in it. That's why I use &lt;a href="https://github.com/matchai/spacefish" rel="noopener noreferrer"&gt;SpaceFish&lt;/a&gt; prompt. It empowers you with git information, version of your favorite language, Docker's version, Vi mode, last command status &amp;amp; duration, ...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhibnxqir1qk8sz2edz0r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhibnxqir1qk8sz2edz0r.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also use &lt;a href="https://github.com/oh-my-fish/oh-my-fish" rel="noopener noreferrer"&gt;oh-my-fish&lt;/a&gt; framework to extend the shell with plugins (I recommend &lt;code&gt;grc&lt;/code&gt;, &lt;code&gt;g2&lt;/code&gt; &lt;code&gt;fzf&lt;/code&gt;, &lt;code&gt;pj&lt;/code&gt; &amp;amp; &lt;code&gt;z&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  📝 Neovim
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/neovim/neovim" rel="noopener noreferrer"&gt;Neovim&lt;/a&gt; is a refactor of Vim that brings a better plugins system and that is easier to contribute to.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/neovim" rel="noopener noreferrer"&gt;
        neovim
      &lt;/a&gt; / &lt;a href="https://github.com/neovim/neovim" rel="noopener noreferrer"&gt;
        neovim
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Vim-fork focused on extensibility and usability
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/neovim/neovim.github.io/master/logos/neovim-logo-300x87.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fneovim%2Fneovim.github.io%2Fmaster%2Flogos%2Fneovim-logo-300x87.png" alt="Neovim"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://neovim.io/doc/" rel="nofollow noopener noreferrer"&gt;Documentation&lt;/a&gt; |
&lt;a href="https://app.element.io/#/room/#neovim:matrix.org" rel="nofollow noopener noreferrer"&gt;Chat&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://scan.coverity.com/projects/2227" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/03a677264f2c205589630a6f987f41b913e67912314660bdad77ea2a145adfff/68747470733a2f2f7363616e2e636f7665726974792e636f6d2f70726f6a656374732f323232372f62616467652e737667" alt="Coverity Scan analysis"&gt;&lt;/a&gt;
&lt;a href="https://repology.org/metapackage/neovim" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bbbb02f1997b04ac6e7dfd4a6336cec018e050ab59028d475d0664c7e99f5154/68747470733a2f2f7265706f6c6f67792e6f72672f62616467652f74696e792d7265706f732f6e656f76696d2e737667" alt="Packages"&gt;&lt;/a&gt;
&lt;a href="https://buildd.debian.org/neovim" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/94dbb145c0cbed548f5dff910a17174f7233f68cf1d2c16eb6d9f2463d055ba1/68747470733a2f2f6261646765732e64656269616e2e6e65742f6261646765732f64656269616e2f74657374696e672f6e656f76696d2f76657273696f6e2e737667" alt="Debian CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/neovim/neovim/releases/" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5bdc1841854422f2c36455e7b24f82fb59838f22a3f9aefa9b2debf981149120/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f6e656f76696d2f6e656f76696d2f746f74616c2e7376673f6d61784167653d32353932303031" alt="Downloads"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neovim is a project that seeks to aggressively refactor &lt;a href="https://www.vim.org/" rel="nofollow noopener noreferrer"&gt;Vim&lt;/a&gt; in order to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simplify maintenance and encourage &lt;a href="https://github.com/neovim/neovimCONTRIBUTING.md" rel="noopener noreferrer"&gt;contributions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Split the work between multiple developers&lt;/li&gt;
&lt;li&gt;Enable &lt;a href="https://github.com/neovim/neovim/wiki/Related-projects#gui" rel="noopener noreferrer"&gt;advanced UIs&lt;/a&gt; without modifications to the core&lt;/li&gt;
&lt;li&gt;Maximize &lt;a href="https://neovim.io/doc/user/ui.html" rel="nofollow noopener noreferrer"&gt;extensibility&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See the &lt;a href="https://github.com/neovim/neovim/wiki/Introduction" rel="noopener noreferrer"&gt;Introduction&lt;/a&gt; wiki page and &lt;a href="https://neovim.io/roadmap/" rel="nofollow noopener noreferrer"&gt;Roadmap&lt;/a&gt;
for more information.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Modern &lt;a href="https://github.com/neovim/neovim/wiki/Related-projects#gui" rel="noopener noreferrer"&gt;GUIs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/neovim/neovim/wiki/Related-projects#api-clients" rel="noopener noreferrer"&gt;API access&lt;/a&gt;
from any language including C/C++, C#, Clojure, D, Elixir, Go, Haskell, Java/Kotlin
JavaScript/Node.js, Julia, Lisp, Lua, Perl, Python, Racket, Ruby, Rust&lt;/li&gt;
&lt;li&gt;Embedded, scriptable &lt;a href="https://neovim.io/doc/user/terminal.html" rel="nofollow noopener noreferrer"&gt;terminal emulator&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Asynchronous &lt;a href="https://github.com/neovim/neovim/pull/2247" rel="noopener noreferrer"&gt;job control&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/neovim/neovim/pull/2506" rel="noopener noreferrer"&gt;Shared data (shada)&lt;/a&gt; among multiple editor instances&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/neovim/neovim/pull/3470" rel="noopener noreferrer"&gt;XDG base directories&lt;/a&gt; support&lt;/li&gt;
&lt;li&gt;Compatible with most Vim plugins, including Ruby and Python plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href="https://neovim.io/doc/user/vim_diff.html#nvim-features" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;:help nvim-features&lt;/code&gt;&lt;/a&gt; for the full list, and &lt;a href="https://neovim.io/doc/user/news.html" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;:help news&lt;/code&gt;&lt;/a&gt; for noteworthy changes in the latest version!&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Install from package&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Pre-built packages for Windows, macOS, and Linux are found on the
&lt;a href="https://github.com/neovim/neovim/releases/" rel="noopener noreferrer"&gt;Releases&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/neovim/neovim./INSTALL.md#install-from-package" rel="noopener noreferrer"&gt;Managed packages&lt;/a&gt; are in &lt;a href="https://formulae.brew.sh/formula/neovim" rel="nofollow noopener noreferrer"&gt;Homebrew&lt;/a&gt;, &lt;a href="https://packages.debian.org/testing/neovim" rel="nofollow noopener noreferrer"&gt;Debian&lt;/a&gt;, &lt;a href="https://packages.ubuntu.com/search?keywords=neovim" rel="nofollow noopener noreferrer"&gt;Ubuntu&lt;/a&gt;, &lt;a href="https://packages.fedoraproject.org/pkgs/neovim/neovim/" rel="nofollow noopener noreferrer"&gt;Fedora&lt;/a&gt;, &lt;a href="https://www.archlinux.org/packages/?q=neovim" rel="nofollow noopener noreferrer"&gt;Arch Linux&lt;/a&gt;, &lt;a href="https://voidlinux.org/packages/?arch=x86_64&amp;amp;q=neovim" rel="nofollow noopener noreferrer"&gt;Void&lt;/a&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/neovim/neovim" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://github.com/SpaceVim/SpaceVim" rel="noopener noreferrer"&gt;SpaceVim&lt;/a&gt; is a Vim distribution with some default configuration for developers. It comes with an outline (press &lt;code&gt;&amp;lt;F2&amp;gt;&lt;/code&gt;), a tree view (press &lt;code&gt;&amp;lt;F3&amp;gt;&lt;/code&gt;), and many supported languages (&lt;code&gt;golang&lt;/code&gt;, &lt;code&gt;php&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt;, &lt;code&gt;javascript&lt;/code&gt;, ...) for IDE features (completion, syntax highlighting, refactoring, code browsing, debugging, ...). The configuration is made easy with a simple TOML file. It's a good way to step into Vim for newbies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkccls72fr5qx5tgs1rbp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkccls72fr5qx5tgs1rbp.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🕺🏼 All together
&lt;/h2&gt;

&lt;p&gt;Below is a tree-pane view with the following panes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vim in the main pane (&lt;code&gt;golang&lt;/code&gt; SpaceVim layer, with &lt;code&gt;Tagbar&lt;/code&gt; and &lt;code&gt;Nerdtree&lt;/code&gt; plugins)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;modd&lt;/code&gt; in the bottom-left pane to run my unit tests on modifications&lt;/li&gt;
&lt;li&gt;a shell in the bottom-right pane to run git commands (&lt;code&gt;git lg&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkg0ies1g0m6dcyyjekmh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkg0ies1g0m6dcyyjekmh.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  👾 List of awesome dev CLI tools
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/lirantal/dockly" rel="noopener noreferrer"&gt;dockly&lt;/a&gt;: Docker UI in CLI&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://httpie.org/" rel="noopener noreferrer"&gt;httpie&lt;/a&gt;: awesome CLI HTTP client&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stedolan.github.io/jq/" rel="noopener noreferrer"&gt;jq&lt;/a&gt; &amp;amp; &lt;a href="http://fx.wtf/" rel="noopener noreferrer"&gt;fx&lt;/a&gt;: CLI JSON viewers&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://lnav.org/" rel="noopener noreferrer"&gt;lnav&lt;/a&gt;: a log file navigator&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/nicolargo/glances" rel="noopener noreferrer"&gt;glances&lt;/a&gt;: an eye on your system&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sharkdp/bat" rel="noopener noreferrer"&gt;bat&lt;/a&gt;: cat clone with syntax highlighting and Git integration&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://the.exa.website/" rel="noopener noreferrer"&gt;exa&lt;/a&gt;: the ultimate &lt;code&gt;ls&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jonas.github.io/tig/" rel="noopener noreferrer"&gt;tig&lt;/a&gt;: a powerful git wrapper for CLI users&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/postmanlabs/newman" rel="noopener noreferrer"&gt;newman&lt;/a&gt;: automate your Postman tests in CLI or CI/CD&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jefftk.com/icdiff" rel="noopener noreferrer"&gt;icdiff&lt;/a&gt;: a user-friendly diff tool (to use with git)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Here it is!&lt;/p&gt;

&lt;p&gt;I hope you found it useful.&lt;br&gt;
Don't hesitate to suggest other tools in comments!&lt;br&gt;
Don't hesitate to say if you're tired of seeing such &lt;em&gt;"awesome"&lt;/em&gt; articles! ;)&lt;/p&gt;

</description>
      <category>linux</category>
      <category>manjaro</category>
      <category>deepin</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What do you think of environmental impact of services like Netflix, Google, Amazon and what are your alternatives ? </title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Sat, 08 Jun 2019 11:34:52 +0000</pubDate>
      <link>https://dev.to/biros/what-do-you-think-of-environmental-impact-of-services-like-netflix-google-amazon-and-what-are-your-alternatives-3bkd</link>
      <guid>https://dev.to/biros/what-do-you-think-of-environmental-impact-of-services-like-netflix-google-amazon-and-what-are-your-alternatives-3bkd</guid>
      <description>

</description>
      <category>earth</category>
      <category>pollution</category>
      <category>alternatives</category>
      <category>discuss</category>
    </item>
    <item>
      <title>DEV's community growth 🥳</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Tue, 28 May 2019 07:37:49 +0000</pubDate>
      <link>https://dev.to/biros/dev-s-community-growth-1inf</link>
      <guid>https://dev.to/biros/dev-s-community-growth-1inf</guid>
      <description>&lt;p&gt;Hi guys! Our community has grown up from 119000 to 172600 users (+53600) in the last 6 months.&lt;/p&gt;

&lt;p&gt;What do you think?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>meta</category>
    </item>
    <item>
      <title>📛 🗣️ Which dev conferences did you attend?</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Thu, 07 Mar 2019 22:33:20 +0000</pubDate>
      <link>https://dev.to/biros/--what-dev-conferences-did-you-attend-32p8</link>
      <guid>https://dev.to/biros/--what-dev-conferences-did-you-attend-32p8</guid>
      <description>&lt;h1&gt;
  
  
  Hi guys!
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Did you ever attend any dev conference?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've been developing for almost 20 years but I discovered dev conferences only in 2016. That year, I had the chance to attend the very famous &lt;a href="https://www.devoxx.fr/" rel="noopener noreferrer"&gt;devoxx&lt;/a&gt; conference in Paris. The tickets, the train and the hotel room were paid by my company.&lt;/p&gt;

&lt;p&gt;It was very exciting! Meeting so many developers, hearing some famous speakers talking about hot topics, getting my first stickers... 😉&lt;/p&gt;

&lt;p&gt;That was also after this event that I wrote my first blog post on the corporate social network. And that I started to blog.&lt;/p&gt;

&lt;p&gt;I usually try to be very open-minded when I attend such events. I don't go to the talks about my favorite stack. I prefer attend talks about some exotic technology (&lt;strong&gt;blockchain&lt;/strong&gt;, &lt;strong&gt;rust&lt;/strong&gt;, ...) or hear feedbacks from people who experimented something new in production (&lt;strong&gt;CQRS&lt;/strong&gt;, &lt;strong&gt;docker&lt;/strong&gt;, &lt;strong&gt;microservices&lt;/strong&gt;, ...). I also like talks about &lt;strong&gt;testing&lt;/strong&gt;, &lt;strong&gt;devops&lt;/strong&gt; and &lt;strong&gt;agility&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now, let me introduce you to the events I had the chance to go.&lt;/p&gt;

&lt;h1&gt;
  
  
  BreizhCamp
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.billetweb.fr%2Ffiles%2Fpage%2Fthumb%2Fbreizhcamp-2019.png%3Fv%3D1550406210" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.billetweb.fr%2Ffiles%2Fpage%2Fthumb%2Fbreizhcamp-2019.png%3Fv%3D1550406210" alt="breizhcamp-logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;em&gt;&lt;a href="https://www.breizhcamp.org/" rel="noopener noreferrer"&gt;www.breizhcamp.org&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
🐦 &lt;em&gt;&lt;a href="https://twitter.com/breizhcamp" rel="noopener noreferrer"&gt;twitter.com/breizhcamp&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
📆 &lt;em&gt;20-22 / 03 / 2019&lt;/em&gt;&lt;br&gt;
🗺️ &lt;em&gt;&lt;a href="https://www.google.fr/maps/place/Rennes" rel="noopener noreferrer"&gt;Rennes&lt;/a&gt; (🇫🇷)&lt;/em&gt;&lt;br&gt;
💵 &lt;em&gt;90€&lt;/em&gt;&lt;br&gt;
👩‍💻 &lt;em&gt;~800 attendees&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Codeurs en Seine
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codeursenseine.com%2Fimages%2Fedition2018%2Fsocial.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codeursenseine.com%2Fimages%2Fedition2018%2Fsocial.jpg" alt="codeursenseine-logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;em&gt;&lt;a href="https://www.codeursenseine.com" rel="noopener noreferrer"&gt;www.codeursenseine.com&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
🐦 &lt;em&gt;&lt;a href="https://twitter.com/codeursenseine" rel="noopener noreferrer"&gt;twitter.com/codeursenseine&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
📆 &lt;em&gt;21 / 11 / 2019&lt;/em&gt;&lt;br&gt;
🗺️ &lt;em&gt;&lt;a href="https://www.google.fr/maps/place/Rouen" rel="noopener noreferrer"&gt;Rouen&lt;/a&gt; (🇫🇷)&lt;/em&gt;&lt;br&gt;
💵 &lt;em&gt;Free&lt;/em&gt;&lt;br&gt;
👩‍💻 &lt;em&gt;~900 attendees&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Devoxx France
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.clever-age.com%2Fwp-content%2Fuploads%2Fsites%2F2%2F2016%2F06%2Fdevoxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.clever-age.com%2Fwp-content%2Fuploads%2Fsites%2F2%2F2016%2F06%2Fdevoxx.png" alt="devoxx-logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;em&gt;&lt;a href="https://www.devoxx.fr/" rel="noopener noreferrer"&gt;www.devoxx.fr&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
🐦 &lt;em&gt;&lt;a href="http://www.twitter.com/DevoxxFR" rel="noopener noreferrer"&gt;twitter.com/DevoxxFR&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
📆 &lt;em&gt;17-19 / 04 / 2019&lt;/em&gt;&lt;br&gt;
🗺️ &lt;em&gt;&lt;a href="https://www.google.fr/maps/place/Paris" rel="noopener noreferrer"&gt;Paris&lt;/a&gt; (🇫🇷)&lt;/em&gt;&lt;br&gt;
💵 &lt;em&gt;605€&lt;/em&gt;&lt;br&gt;
👩‍💻 &lt;em&gt;~3000 attendees&lt;/em&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;And you, which conferences did you attend?&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>career</category>
      <category>learning</category>
      <category>conference</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Building a Custom IDE with Tmux</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Tue, 05 Feb 2019 22:27:52 +0000</pubDate>
      <link>https://dev.to/biros/building-a-custom-ide-with-tmux-2aeg</link>
      <guid>https://dev.to/biros/building-a-custom-ide-with-tmux-2aeg</guid>
      <description>&lt;h2&gt;
  
  
  Hi!
&lt;/h2&gt;

&lt;p&gt;Today, I want to share about a tool I've been using for a few months and which helps me a lot in my day to day job: &lt;a href="https://github.com/tmux/tmux/wiki"&gt;tmux&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As a software craftsman and &lt;a href="https://dev.to/biros/cli-love-inside-4lgl"&gt;CLI lover&lt;/a&gt;, I'm always looking for the best tools to be as productive as possible.&lt;/p&gt;

&lt;p&gt;Let me show you how I use &lt;em&gt;tmux&lt;/em&gt; as the foundation of what I call &lt;em&gt;my custom IDE&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Tmux?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Tmux is a wonderful terminal multiplexer that comes with some plugins.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You might wonder why you would need to use such a thing. Many terminal emulators come with built-in feature for splitting your term. &lt;br&gt;
In fact, it comes that &lt;em&gt;tmux&lt;/em&gt; is much more powerful for splitting and resizing windows. &lt;br&gt;
The other reason is that &lt;em&gt;tmux&lt;/em&gt; can work with any term. So if you change your term, you don't need to reconfigure all your presets. &lt;em&gt;Tmux&lt;/em&gt; does it for you. &lt;br&gt;
And you can also use &lt;em&gt;tmux&lt;/em&gt; without X, in a simple &lt;code&gt;tty&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/tmux"&gt;
        tmux
      &lt;/a&gt; / &lt;a href="https://github.com/tmux/tmux"&gt;
        tmux
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      tmux source code
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Welcome to tmux!&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;tmux is a terminal multiplexer: it enables a number of terminals to be created
accessed, and controlled from a single screen. tmux may be detached from a
screen and continue running in the background, then later reattached.&lt;/p&gt;
&lt;p&gt;This release runs on OpenBSD, FreeBSD, NetBSD, Linux, macOS and Solaris.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Dependencies&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;tmux depends on &lt;a href="https://libevent.org" rel="nofollow"&gt;libevent&lt;/a&gt; 2.x, available from &lt;a href="https://github.com/libevent/libevent/releases/latest"&gt;this
page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It also depends on &lt;a href="https://www.gnu.org/software/ncurses/" rel="nofollow"&gt;ncurses&lt;/a&gt;, available
from &lt;a href="https://invisible-mirror.net/archives/ncurses/" rel="nofollow"&gt;this page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To build tmux, a C compiler (for example gcc or clang), make, pkg-config and a
suitable yacc (yacc or bison) are needed.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Binary packages&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Some platforms provide binary packages for tmux, although these are sometimes
out of date. Examples are listed on
&lt;a href="https://github.com/tmux/tmux/wiki/Installing"&gt;this page&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;From release tarball&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;To build and install tmux from a release tarball, use:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;./configure &lt;span class="pl-k"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make
sudo make install&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;tmux can use the utempter library to update utmp(5), if it is…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/tmux/tmux"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Install it
&lt;/h3&gt;

&lt;p&gt;Install &lt;em&gt;tmux&lt;/em&gt; through your favorite package manager, or compile it from the sources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/tmux/tmux.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;tmux
&lt;span class="nv"&gt;$ &lt;/span&gt;sh autogen.sh
&lt;span class="nv"&gt;$ &lt;/span&gt;./configure &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure it
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Tmux&lt;/em&gt; may look a bit raw and difficult to handle at the beginning. Fortunately, it comes with a great community that helps a lot to set it up. After trying many configurations, I've ended up with the one of &lt;a href="https://github.com/gpakosz/.tmux"&gt;gpakosz&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdi4u1yho9rmhags9j1e.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdi4u1yho9rmhags9j1e.gif" alt="tmux" width="1770" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It comes with presets for bindings and a great &lt;a href="https://github.com/powerline/powerline"&gt;powerline&lt;/a&gt; look for the status bar.&lt;/p&gt;

&lt;p&gt;Just have a loot at the &lt;a href="https://github.com/gpakosz/.tmux/blob/master/README.md"&gt;README&lt;/a&gt; to customize it to your needs!&lt;/p&gt;

&lt;p&gt;Personally, I find it useless to have the uptime in my status bar, so I removed it from the configuration. I also added some plugins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/tmux-plugins/tpm"&gt;tmux-plugins/tpm&lt;/a&gt; &lt;em&gt;The Tmux Plugin Manager&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tmux-plugins/tmux-sensible"&gt;tmux-plugins/tmux-sensible&lt;/a&gt; &lt;em&gt;Basic settings&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tmux-plugins/tmux-yank"&gt;tmux-plugins/tmux-yank&lt;/a&gt; &lt;em&gt;Allows copying to system clipboard&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tmux-plugins/tmux-open"&gt;tmux-plugins/tmux-open&lt;/a&gt; &lt;em&gt;Key bindings for quick opening of a highlighted file or url&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/chriszarate/tmux-tasks"&gt;chriszarate/tmux-tasks&lt;/a&gt; &lt;em&gt;Display the count of (urgent) tasks in the status bar. Requires &lt;a href="https://github.com/GothenburgBitFactory/taskwarrior"&gt;taskwarrior&lt;/a&gt;.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use it
&lt;/h3&gt;

&lt;p&gt;You have to set &lt;em&gt;tmux&lt;/em&gt; as your default shell in your preferred terminal emulator. Once done, &lt;em&gt;tmux&lt;/em&gt; will be launched each time you open a new term.&lt;/p&gt;

&lt;p&gt;Basically, when &lt;em&gt;tmux&lt;/em&gt; starts, it creates an empty session with a single window containing a blank pane and a status bar. The status bar is divided in 3 parts: left, middle and right. If, like me, you choose to use the configuration above, the left part will display the &lt;strong&gt;session&lt;/strong&gt;'s name (or index if name is unset) and the uptime. The right part will display the battery, the date, the username and the hostname. In the middle, you'll see the &lt;strong&gt;windows&lt;/strong&gt;' titles (or the name of the process running in the focused pane if the name is unset).&lt;/p&gt;

&lt;p&gt;The basics are &lt;strong&gt;sessions&lt;/strong&gt;, &lt;strong&gt;windows&lt;/strong&gt; and &lt;strong&gt;panes&lt;/strong&gt;. Each time you open a term (or a new tab in the term), &lt;em&gt;tmux&lt;/em&gt; launches a new session. A new session contains a window. A new window contains a pane in your &lt;code&gt;$HOME&lt;/code&gt; dir.&lt;/p&gt;

&lt;p&gt;Bindings in &lt;em&gt;tmux&lt;/em&gt; are essential: you can access them by using the prefix &lt;code&gt;Ctrl-a&lt;/code&gt; or &lt;code&gt;Ctrl-b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here are the main bindings I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;prefix&amp;gt; Ctrl-c&lt;/code&gt; creates a new session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;prefix&amp;gt; c&lt;/code&gt; creates a new window&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;prefix&amp;gt; %&lt;/code&gt; splits the current pane vertically&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;prefix&amp;gt; "&lt;/code&gt; splits the current pane horizontally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, if you feel uncomfortable with bindings, &lt;em&gt;tmux&lt;/em&gt; has a great mouse mode, allowing you to select, switch and resize panes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get the most of it
&lt;/h3&gt;

&lt;p&gt;The killer feature of &lt;em&gt;tmux&lt;/em&gt; is the &lt;strong&gt;sessions&lt;/strong&gt;. Imagine you want to build a window with 3 panes for editing a file, play with git and run your tests. Just create a new session, split the panes and adjust their size to your needs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Great? Not that much.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As there is no built-in mechanism to save session, I use the &lt;a href="https://tmuxp.git-pull.com/en/latest/"&gt;tmuxp&lt;/a&gt; tool. This is a must-have session manager for &lt;em&gt;tmux&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Install it through your distro's manager or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; tmuxp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In two words: &lt;em&gt;tmuxp&lt;/em&gt; allows you to easily create sessions from &lt;code&gt;yaml&lt;/code&gt;/&lt;code&gt;json&lt;/code&gt; files and to load 'em when you need it. And it's not only about creating the windows &amp;amp; panes layout: you can also run commands in each of the panes. So you can run &lt;code&gt;vim&lt;/code&gt; in the main pane, &lt;code&gt;cd&lt;/code&gt; to your project directory in another pane to play with &lt;code&gt;git&lt;/code&gt;, and run a file-watcher in a 3rd pane to trigger your tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# my-project.yaml&lt;/span&gt;
&lt;span class="na"&gt;session_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my project&lt;/span&gt;
&lt;span class="na"&gt;windows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;window_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my custom IDE&lt;/span&gt;
  &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main-vertical&lt;/span&gt;
  &lt;span class="na"&gt;shell_command_before&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pj my-project&lt;/span&gt;
  &lt;span class="na"&gt;panes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;vim&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git status&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;phpunit-watcher watch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then just run &lt;code&gt;tmuxp load -y my-project.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And if, like me, you need to build up a full environment to work on your app, know that there is no limit. The session I use for my current project has many windows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 &lt;strong&gt;IDE&lt;/strong&gt; window: 3-panes with &lt;code&gt;vim&lt;/code&gt;, a term to play with &lt;code&gt;git&lt;/code&gt; and a term to run the tests,&lt;/li&gt;
&lt;li&gt;9 windows, one for each log file I need to grep with &lt;a href="https://stedolan.github.io/jq/"&gt;jq&lt;/a&gt; or &lt;a href="http://lnav.org/"&gt;lnav&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;a window to serve the assets of my front,&lt;/li&gt;
&lt;li&gt;a window to run my stubs (typically a SpringBoot app).&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;That's it!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope you learned something by reading this article and that you'll have a look at &lt;em&gt;tmux&lt;/em&gt;. I'm not an expert of it. I must say I don't use 10% of the features, but this tool has become an essential part of my dev env. I guess it could do the same for you.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;Bye.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>showdev</category>
      <category>craftsmanship</category>
      <category>githunt</category>
    </item>
    <item>
      <title>My Go Toolkit to Build a Frameworkless App</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Mon, 28 Jan 2019 15:26:49 +0000</pubDate>
      <link>https://dev.to/biros/my-go-toolkit-to-build-a-frameworkless-app-5777</link>
      <guid>https://dev.to/biros/my-go-toolkit-to-build-a-frameworkless-app-5777</guid>
      <description>&lt;p&gt;A few months ago, I started &lt;a href="https://dev.to/biros/my-journey-from-php-to-go-55bd"&gt;my journey from PHP to Go&lt;/a&gt; on a new app in my company.&lt;/p&gt;

&lt;p&gt;Some 3 months after, I posted another Article on DEV talking about &lt;a href="https://dev.to/biros/its-been-three-months-since-my-first-go-loc----419d"&gt;my feedbacks on the language&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now it's the time to share about the libraries &amp;amp; tools I've been using so far. Note that I don't use any framework nor any ORM. Just the right libraries to do the job.&lt;/p&gt;




&lt;h2&gt;
  
  
  Libraries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Viper
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;7,353&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/spf13" rel="noopener noreferrer"&gt;
        spf13
      &lt;/a&gt; / &lt;a href="https://github.com/spf13/viper" rel="noopener noreferrer"&gt;
        viper
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Go configuration with fangs
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Viper v2 feedback&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Viper is heading towards v2 and we would love to hear what &lt;em&gt;&lt;strong&gt;you&lt;/strong&gt;&lt;/em&gt; would like to see in it. Share your thoughts here: &lt;a href="https://forms.gle/R6faU74qPRPAzchZ9" rel="nofollow noopener noreferrer"&gt;https://forms.gle/R6faU74qPRPAzchZ9&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thank you!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/spf13/viper.github/logo.png?raw=true"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fspf13%2Fviper.github%2Flogo.png%3Fraw%3Dtrue" alt="Viper"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/avelino/awesome-go#configuration" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/adb8f3e4da7635816556cc11275410d326f132ce011955a341259bc1061ff351/68747470733a2f2f617765736f6d652e72652f6d656e74696f6e65642d62616467652d666c61742e737667" alt="Mentioned in Awesome Go"&gt;&lt;/a&gt;
&lt;a href="https://repl.it/@sagikazarmark/Viper-example#main.go" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fa8e183781be4fc65db5226484ed3feebcb16b822e82a614ac7670b97314efd4/68747470733a2f2f7265706c2e69742f62616467652f6769746875622f736167696b617a61726d61726b2f56697065722d6578616d706c65" alt="run on repl.it"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/spf13/viper/actions?query=workflow%3ACI" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c071fbafa8a6e9f171605c06a929f34bb2abadc2f502f0b5f7e4e96edb245936/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f73706631332f76697065722f63692e79616d6c3f6272616e63683d6d6173746572267374796c653d666c61742d737175617265" alt="GitHub Workflow Status"&gt;&lt;/a&gt;
&lt;a href="https://gitter.im/spf13/viper?utm_source=badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=pr-badge&amp;amp;utm_content=badge" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ef3705254e766b5edea93f49291c6d9239f29b942cfdb84f3296d0e37898b067/68747470733a2f2f6261646765732e6769747465722e696d2f4a6f696e253230436861742e737667" alt="Join the chat at https://gitter.im/spf13/viper"&gt;&lt;/a&gt;
&lt;a href="https://goreportcard.com/report/github.com/spf13/viper" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0ea957f5e1823b9f2c95927942c67cde8c45d93f8d1ad98572edc302108c68e3/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f73706631332f76697065723f7374796c653d666c61742d737175617265" alt="Go Report Card"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/3acc05d72f6d1b319bda5313c62db4bf91b51752aa1b9a909be423722aee3915/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f676f25323076657273696f6e2d2533453d312e32312d3631434644442e7376673f7374796c653d666c61742d737175617265"&gt;&lt;img src="https://camo.githubusercontent.com/3acc05d72f6d1b319bda5313c62db4bf91b51752aa1b9a909be423722aee3915/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f676f25323076657273696f6e2d2533453d312e32312d3631434644442e7376673f7374796c653d666c61742d737175617265" alt="Go Version"&gt;&lt;/a&gt;
&lt;a href="https://pkg.go.dev/mod/github.com/spf13/viper" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/423cf99dbb881b294919715964455b99ee6f98649c533939de6654336d249803/68747470733a2f2f706b672e676f2e6465762f62616467652f6d6f642f6769746875622e636f6d2f73706631332f7669706572" alt="PkgGoDev"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Go configuration with fangs!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Many Go projects are built using Viper including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://gohugo.io" rel="nofollow noopener noreferrer"&gt;Hugo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://rexray.readthedocs.org/en/stable/" rel="nofollow noopener noreferrer"&gt;EMC RexRay&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Imgur/incus" rel="noopener noreferrer"&gt;Imgur’s Incus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/nanobox-io/nanobox" rel="noopener noreferrer"&gt;Nanobox&lt;/a&gt;/&lt;a href="https://github.com/nanopack" rel="noopener noreferrer"&gt;Nanopack&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/docker/Notary" rel="noopener noreferrer"&gt;Docker Notary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bloomapi.com/" rel="nofollow noopener noreferrer"&gt;BloomApi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/digitalocean/doctl" rel="noopener noreferrer"&gt;doctl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jgsqware/clairctl" rel="noopener noreferrer"&gt;Clairctl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mercure.rocks" rel="nofollow noopener noreferrer"&gt;Mercure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/meshery/meshery" rel="noopener noreferrer"&gt;Meshery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bearer/bearer" rel="noopener noreferrer"&gt;Bearer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/coder/coder" rel="noopener noreferrer"&gt;Coder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vitess.io/" rel="nofollow noopener noreferrer"&gt;Vitess&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Install&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;go get github.com/spf13/viper&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Viper uses &lt;a href="https://go.dev/wiki/Modules" rel="nofollow noopener noreferrer"&gt;Go Modules&lt;/a&gt; to manage dependencies.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is Viper?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Viper is a complete configuration solution for Go applications including &lt;a href="https://12factor.net/#the_twelve_factors" rel="nofollow noopener noreferrer"&gt;12-Factor apps&lt;/a&gt;.
It is designed to work within an application, and can handle all types of configuration needs
and formats. It supports:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;setting defaults&lt;/li&gt;
&lt;li&gt;reading from JSON, TOML, YAML, HCL, envfile and Java properties config files&lt;/li&gt;
&lt;li&gt;live watching and re-reading of config files (optional)&lt;/li&gt;
&lt;li&gt;reading from environment variables&lt;/li&gt;
&lt;li&gt;reading from remote config systems (etcd or Consul), and watching changes&lt;/li&gt;
&lt;li&gt;reading from command line flags&lt;/li&gt;
&lt;li&gt;reading…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/spf13/viper" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  2. Gin Gonic
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;23,913&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/gin-gonic" rel="noopener noreferrer"&gt;
        gin-gonic
      &lt;/a&gt; / &lt;a href="https://github.com/gin-gonic/gin" rel="noopener noreferrer"&gt;
        gin
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Gin Web Framework&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/gin-gonic/logo/master/color.png"&gt;&lt;img width="159px" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fgin-gonic%2Flogo%2Fmaster%2Fcolor.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/gin-gonic/gin/actions?query=branch%3Amaster" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/gin-gonic/gin/workflows/Run%20Tests/badge.svg?branch=master" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/gin-gonic/gin" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6ad3c96b0f7c96493359cdfcad9ff4838ef7e863728505f79adf6d47fce15a91/68747470733a2f2f636f6465636f762e696f2f67682f67696e2d676f6e69632f67696e2f6272616e63682f6d61737465722f67726170682f62616467652e737667" alt="codecov"&gt;&lt;/a&gt;
&lt;a href="https://goreportcard.com/report/github.com/gin-gonic/gin" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/01ff534851848eb769a9470a63f5dc930d8317f756d160f83199655a52cf62a9/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f67696e2d676f6e69632f67696e" alt="Go Report Card"&gt;&lt;/a&gt;
&lt;a href="https://pkg.go.dev/github.com/gin-gonic/gin?tab=doc" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d9ef87bbc7a4f3dd497579212c91d8b2fa3a01a615c2eccfcdffb5d195840ac6/68747470733a2f2f706b672e676f2e6465762f62616467652f6769746875622e636f6d2f67696e2d676f6e69632f67696e3f7374617475732e737667" alt="Go Reference"&gt;&lt;/a&gt;
&lt;a href="https://sourcegraph.com/github.com/gin-gonic/gin?badge" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/af8bc5abcfea7718f1975f5fa0f056864f1e9a08bb10be37d2f62b783ca60e92/68747470733a2f2f736f7572636567726170682e636f6d2f6769746875622e636f6d2f67696e2d676f6e69632f67696e2f2d2f62616467652e737667" alt="Sourcegraph"&gt;&lt;/a&gt;
&lt;a href="https://www.codetriage.com/gin-gonic/gin" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/37020efd3efbea0530f66cdf344b024248ae5230118912a658ebd6251998e4bd/68747470733a2f2f7777772e636f64657472696167652e636f6d2f67696e2d676f6e69632f67696e2f6261646765732f75736572732e737667" alt="Open Source Helpers"&gt;&lt;/a&gt;
&lt;a href="https://github.com/gin-gonic/gin/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b69cdd5dc4d9c8bd1ff42177f86b36dd70d68864de05bff831b965da87c5cf2b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f67696e2d676f6e69632f67696e2e7376673f7374796c653d666c61742d737175617265" alt="Release"&gt;&lt;/a&gt;
&lt;a href="https://www.tickgit.com/browse?repo=github.com/gin-gonic/gin" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/45c8dd1971fd99bee5d83982bdf7e66e5a0be1273357eab538231d52e523297c/68747470733a2f2f62616467656e2e6e65742f68747470732f6170692e7469636b6769742e636f6d2f62616467656e2f6769746875622e636f6d2f67696e2d676f6e69632f67696e" alt="TODOs"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Gin is a web framework written in &lt;a href="https://go.dev/" rel="nofollow noopener noreferrer"&gt;Go&lt;/a&gt;. It features a martini-like API with performance that is up to 40 times faster thanks to &lt;a href="https://github.com/julienschmidt/httprouter" rel="noopener noreferrer"&gt;httprouter&lt;/a&gt;
If you need performance and good productivity, you will love Gin.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gin's key features are:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zero allocation router&lt;/li&gt;
&lt;li&gt;Speed&lt;/li&gt;
&lt;li&gt;Middleware support&lt;/li&gt;
&lt;li&gt;Crash-free&lt;/li&gt;
&lt;li&gt;JSON validation&lt;/li&gt;
&lt;li&gt;Route grouping&lt;/li&gt;
&lt;li&gt;Error management&lt;/li&gt;
&lt;li&gt;Built-in rendering&lt;/li&gt;
&lt;li&gt;Extensible&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting started&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Prerequisites&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Gin requires &lt;a href="https://go.dev/" rel="nofollow noopener noreferrer"&gt;Go&lt;/a&gt; version &lt;a href="https://go.dev/doc/devel/release#go1.21.0" rel="nofollow noopener noreferrer"&gt;1.21&lt;/a&gt; or above.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Getting Gin&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;With &lt;a href="https://go.dev/wiki/Modules#how-to-use-modules" rel="nofollow noopener noreferrer"&gt;Go's module support&lt;/a&gt;, &lt;code&gt;go [build|run|test]&lt;/code&gt; automatically fetches the necessary dependencies when you add the import in your code:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;import &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;github.com/gin-gonic/gin&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Alternatively, use &lt;code&gt;go get&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;go get -u github.com/gin-gonic/gin&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Running Gin&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;A basic example:&lt;/p&gt;
&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;package&lt;/span&gt; main
&lt;span class="pl-k"&gt;import&lt;/span&gt; (
  &lt;span class="pl-s"&gt;"net/http"&lt;/span&gt;

  &lt;span class="pl-s"&gt;"github.com/gin-gonic/gin"&lt;/span&gt;
)

&lt;span class="pl-k"&gt;func&lt;/span&gt; &lt;span class="pl-en"&gt;main&lt;/span&gt;() {
  &lt;span class="pl-s1"&gt;r&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; &lt;span class="pl-s1"&gt;gin&lt;/span&gt;.&lt;span class="pl-en"&gt;Default&lt;/span&gt;()
  &lt;span class="pl-s1"&gt;r&lt;/span&gt;.&lt;span class="pl-en"&gt;GET&lt;/span&gt;(&lt;span class="pl-s"&gt;"/ping"&lt;/span&gt;, &lt;span class="pl-k"&gt;func&lt;/span&gt;(&lt;span class="pl-s1"&gt;c&lt;/span&gt; &lt;span class="pl-c1"&gt;*&lt;/span&gt;gin.&lt;span class="pl-smi"&gt;Context&lt;/span&gt;) {
    &lt;span class="pl-s1"&gt;c&lt;/span&gt;.&lt;span class="pl-en"&gt;JSON&lt;/span&gt;(&lt;span class="pl-s1"&gt;http&lt;/span&gt;.&lt;span class="pl-c1"&gt;StatusOK&lt;/span&gt;,&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/gin-gonic/gin" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  3. Mgo
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;1,385&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/globalsign" rel="noopener noreferrer"&gt;
        globalsign
      &lt;/a&gt; / &lt;a href="https://github.com/globalsign/mgo" rel="noopener noreferrer"&gt;
        mgo
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The MongoDB driver for Go
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://travis-ci.org/globalsign/mgo" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/84b2c732fc88176d59414fbe4b1754c64cc01450ecbe86224d3ebfb088175309/68747470733a2f2f7472617669732d63692e6f72672f676c6f62616c7369676e2f6d676f2e7376673f6272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt; &lt;a href="https://godoc.org/github.com/globalsign/mgo" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8f191d0c8c95be51491d3f83a6b7cf80fae5141763a1d97ec996d784b7d8734d/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676c6f62616c7369676e2f6d676f3f7374617475732e737667" alt="GoDoc"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;The MongoDB driver for Go&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;This fork has had a few improvements by ourselves as well as several PR's merged from the original mgo repo that are currently awaiting review
Changes are mostly geared towards performance improvements and bug fixes, though a few new features have been added.&lt;/p&gt;
&lt;p&gt;Further PR's (with tests) are welcome, but please maintain backwards compatibility.&lt;/p&gt;
&lt;p&gt;Detailed documentation of the API is available at
&lt;a href="https://godoc.org/github.com/globalsign/mgo" rel="nofollow noopener noreferrer"&gt;GoDoc&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;a href="https://godoc.org/github.com/globalsign/mgo/bson" rel="nofollow noopener noreferrer"&gt;sub-package&lt;/a&gt; that implements the &lt;a href="http://bsonspec.org" rel="nofollow noopener noreferrer"&gt;BSON&lt;/a&gt; specification is also included, and may be used independently of the driver.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Supported Versions&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;mgo&lt;/code&gt; is known to work well on (and has integration tests against) MongoDB v3.0, 3.2, 3.4 and 3.6.&lt;/p&gt;
&lt;p&gt;MongoDB 4.0 is currently experimental - we would happily accept PRs to help improve support!&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Changes&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Fixes attempting to authenticate before every query (&lt;a href="https://github.com/go-mgo/mgo/issues/254" rel="noopener noreferrer"&gt;details&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Removes bulk update / delete batch size limitations (&lt;a href="https://github.com/go-mgo/mgo/issues/288" rel="noopener noreferrer"&gt;details&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Adds native support for &lt;code&gt;time.Duration&lt;/code&gt; marshalling…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/globalsign/mgo" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  4. Zap
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;5,901&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/uber-go" rel="noopener noreferrer"&gt;
        uber-go
      &lt;/a&gt; / &lt;a href="https://github.com/uber-go/zap" rel="noopener noreferrer"&gt;
        zap
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Blazing fast, structured, leveled logging in Go.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;⚡ zap&lt;/h1&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;Blazing fast, structured, leveled logging in Go.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/uber-go/zapassets/logo.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fuber-go%2Fzapassets%2Flogo.png" alt="Zap logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://pkg.go.dev/go.uber.org/zap" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/cdd103dcede7fd7d6e31a57a84f58a3bb6b555f67f281bbe6f7400aa6629b1a4/68747470733a2f2f706b672e676f2e6465762f62616467652f676f2e756265722e6f72672f7a6170" alt="GoDoc"&gt;&lt;/a&gt; &lt;a href="https://github.com/uber-go/zap/actions/workflows/go.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/uber-go/zap/actions/workflows/go.yml/badge.svg" alt="Build Status"&gt;&lt;/a&gt; &lt;a href="https://codecov.io/gh/uber-go/zap" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/21f7a0306f9359d41dbe11a26ff41518c27e38e1399db23df3235a2f97e04f17/68747470733a2f2f636f6465636f762e696f2f67682f756265722d676f2f7a61702f6272616e63682f6d61737465722f67726170682f62616467652e737667" alt="Coverage Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;go get -u go.uber.org/zap&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Note that zap only supports the two most recent minor versions of Go.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;In contexts where performance is nice, but not critical, use the
&lt;code&gt;SugaredLogger&lt;/code&gt;. It's 4-10x faster than other structured logging
packages and includes both structured and &lt;code&gt;printf&lt;/code&gt;-style APIs.&lt;/p&gt;
&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-s1"&gt;logger&lt;/span&gt;, &lt;span class="pl-s1"&gt;_&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; &lt;span class="pl-s1"&gt;zap&lt;/span&gt;.&lt;span class="pl-en"&gt;NewProduction&lt;/span&gt;()
&lt;span class="pl-k"&gt;defer&lt;/span&gt; &lt;span class="pl-s1"&gt;logger&lt;/span&gt;.&lt;span class="pl-en"&gt;Sync&lt;/span&gt;() &lt;span class="pl-c"&gt;// flushes buffer, if any&lt;/span&gt;
&lt;span class="pl-s1"&gt;sugar&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; &lt;span class="pl-s1"&gt;logger&lt;/span&gt;.&lt;span class="pl-en"&gt;Sugar&lt;/span&gt;()
&lt;span class="pl-s1"&gt;sugar&lt;/span&gt;.&lt;span class="pl-en"&gt;Infow&lt;/span&gt;(&lt;span class="pl-s"&gt;"failed to fetch URL"&lt;/span&gt;,
  &lt;span class="pl-c"&gt;// Structured context as loosely typed key-value pairs.&lt;/span&gt;
  &lt;span class="pl-s"&gt;"url"&lt;/span&gt;, &lt;span class="pl-s1"&gt;url&lt;/span&gt;,
  &lt;span class="pl-s"&gt;"attempt"&lt;/span&gt;, &lt;span class="pl-c1"&gt;3&lt;/span&gt;,
  &lt;span class="pl-s"&gt;"backoff"&lt;/span&gt;, &lt;span class="pl-s1"&gt;time&lt;/span&gt;.&lt;span class="pl-c1"&gt;Second&lt;/span&gt;,
)
&lt;span class="pl-s1"&gt;sugar&lt;/span&gt;.&lt;span class="pl-en"&gt;Infof&lt;/span&gt;(&lt;span class="pl-s"&gt;"Failed to fetch URL: %s"&lt;/span&gt;, &lt;span class="pl-s1"&gt;url&lt;/span&gt;)&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;When performance and type safety are critical, use the &lt;code&gt;Logger&lt;/code&gt;. It's even
faster than the &lt;code&gt;SugaredLogger&lt;/code&gt; and allocates far less, but it only…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/uber-go/zap" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  5. &lt;del&gt;Go.uuid&lt;/del&gt; gofrs/uuid
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;394&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/gofrs" rel="noopener noreferrer"&gt;
        gofrs
      &lt;/a&gt; / &lt;a href="https://github.com/gofrs/uuid" rel="noopener noreferrer"&gt;
        uuid
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A UUID package for Go
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;UUID&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/gofrs/uuid/blob/master/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/71b05a15250398d5f35bf99cf9e791c589a9f6e1501ebcca018559557ce50bbf/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f676f6672732f757569642e737667" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/gofrs/uuid/actions/workflows/go.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/gofrs/uuid/actions/workflows/go.yml/badge.svg" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://pkg.go.dev/github.com/gofrs/uuid/v5" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e9f1d0ed0f25988cd21e5001645989aab6dc0f8493293f307c71de7118e4d43c/68747470733a2f2f706b672e676f2e6465762f62616467652f6769746875622e636f6d2f676f6672732f757569642f76352e737667" alt="Go Reference"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/gofrs/uuid/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22618d9b24dd2d5580311e2d531207dba23271c1849468a18900522961b02cd6/68747470733a2f2f636f6465636f762e696f2f67682f676f6672732f757569642f6272616e63682f6d61737465722f6772617068732f62616467652e7376673f6272616e63683d6d6173746572" alt="Coverage Status"&gt;&lt;/a&gt;
&lt;a href="https://goreportcard.com/report/github.com/gofrs/uuid" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f8f0660f521d769ba4510861af96bbaed830ce5fe86475b091f9a5e059d67c26/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f676f6672732f75756964" alt="Go Report Card"&gt;&lt;/a&gt;
&lt;a href="https://github.com/gofrs/uuid/actions/workflows/codeql.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/gofrs/uuid/actions/workflows/codeql.yml/badge.svg" alt="CodeQL"&gt;&lt;/a&gt;
&lt;a href="https://www.bestpractices.dev/projects/8929" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d6ced19f8e593b16bad5e6a964f306a6f831d9e3f1a92bc7bdf788af40afdddc/68747470733a2f2f7777772e626573747072616374696365732e6465762f70726f6a656374732f383932392f6261646765" alt="OpenSSF Best Practices"&gt;&lt;/a&gt;
&lt;a href="https://scorecard.dev/viewer/?uri=github.com/gofrs/uuid" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/872646f2cedfa6880017d3c8794a17a0b435edece38e1ec9cb1756e1437f735c/68747470733a2f2f6170692e73636f7265636172642e6465762f70726f6a656374732f6769746875622e636f6d2f676f6672732f757569642f6261646765" alt="OpenSSF Scorecard"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Package uuid provides a pure Go implementation of Universally Unique Identifiers
(UUID) variant as defined in RFC-9562. This package supports both the creation
and parsing of UUIDs in different formats.&lt;/p&gt;
&lt;p&gt;This package supports the following UUID versions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Version 1, based on timestamp and MAC address&lt;/li&gt;
&lt;li&gt;Version 3, based on MD5 hashing of a named value&lt;/li&gt;
&lt;li&gt;Version 4, based on random numbers&lt;/li&gt;
&lt;li&gt;Version 5, based on SHA-1 hashing of a named value&lt;/li&gt;
&lt;li&gt;Version 6, a k-sortable id based on timestamp, and field-compatible with v1&lt;/li&gt;
&lt;li&gt;Version 7, a k-sortable id based on timestamp&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Project History&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;This project was originally forked from the
&lt;a href="https://github.com/satori/go.uuid" rel="noopener noreferrer"&gt;github.com/satori/go.uuid&lt;/a&gt; repository after
it appeared to be no longer maintained, while exhibiting &lt;a href="https://github.com/satori/go.uuid/issues/73" rel="noopener noreferrer"&gt;critical
flaws&lt;/a&gt;. We have decided to take
over this project to ensure it receives regular maintenance for the benefit of
the larger Go community.&lt;/p&gt;
&lt;p&gt;We'd like to thank Maxim Bublis for his hard work on the…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/gofrs/uuid" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  6. JWT-Go
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;4,849&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/dgrijalva" rel="noopener noreferrer"&gt;
        dgrijalva
      &lt;/a&gt; / &lt;a href="https://github.com/dgrijalva/jwt-go" rel="noopener noreferrer"&gt;
        jwt-go
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ARCHIVE - Golang implementation of JSON Web Tokens (JWT). This project is now maintained at:
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;THIS REPOSITORY IS NO LONGER MAINTANED&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;The new repository can be found at: &lt;a href="https://github.com/golang-jwt/jwt" rel="noopener noreferrer"&gt;https://github.com/golang-jwt/jwt&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For more information, see issue &lt;a href="https://github.com/dgrijalva/jwt-go/issues/462" rel="noopener noreferrer"&gt;#462&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;jwt-go&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://travis-ci.org/dgrijalva/jwt-go" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5fdd490fa637f9df80af94f2785ba82bff6d6e6afd7f758c94cf1eadc39af7e3/68747470733a2f2f7472617669732d63692e6f72672f646772696a616c76612f6a77742d676f2e7376673f6272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://godoc.org/github.com/dgrijalva/jwt-go" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c55fbb3dc0a559e0830793ac731103f3136e23c6d4470090397ee84d4a163f62/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f646772696a616c76612f6a77742d676f3f7374617475732e737667" alt="GoDoc"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A &lt;a href="http://www.golang.org" rel="nofollow noopener noreferrer"&gt;go&lt;/a&gt; (or 'golang' for search engine friendliness) implementation of &lt;a href="http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html" rel="nofollow noopener noreferrer"&gt;JSON Web Tokens&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NEW VERSION COMING:&lt;/strong&gt; There have been a lot of improvements suggested since the version 3.0.0 released in 2016. I'm working now on cutting two different releases: 3.2.0 will contain any non-breaking changes or enhancements. 4.0.0 will follow shortly which will include breaking changes. See the 4.0.0 milestone to get an idea of what's coming. If you have other ideas, or would like to participate in 4.0.0, now's the time. If you depend on this library and don't want to be interrupted, I recommend you use your dependency mangement tool to pin to version 3.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SECURITY NOTICE:&lt;/strong&gt; Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dgrijalva/jwt-go" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  7. Testify
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;6,634&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/stretchr" rel="noopener noreferrer"&gt;
        stretchr
      &lt;/a&gt; / &lt;a href="https://github.com/stretchr/testify" rel="noopener noreferrer"&gt;
        testify
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A toolkit with common assertions and mocks that plays nicely with the standard library
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Testify - Thou Shalt Write Tests&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;ℹ️ We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: &lt;a href="https://cutt.ly/testify" rel="nofollow noopener noreferrer"&gt;https://cutt.ly/testify&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/stretchr/testify/actions/workflows/main.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/stretchr/testify/actions/workflows/main.yml/badge.svg?branch=master" alt="Build Status"&gt;&lt;/a&gt; &lt;a href="https://goreportcard.com/report/github.com/stretchr/testify" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c9ecd02f3731984449f035f1d9a5a01e8e6ae50088424d0ace3837853eb40854/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f73747265746368722f74657374696679" alt="Go Report Card"&gt;&lt;/a&gt; &lt;a href="https://pkg.go.dev/github.com/stretchr/testify" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ef6b9ca9a80d8e6e07bce8ab223997d3ad637dfa1d1766dd07e88b76d33cd470/68747470733a2f2f706b672e676f2e6465762f62616467652f6769746875622e636f6d2f73747265746368722f74657374696679" alt="PkgGoDev"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Go code (golang) set of packages that provide many tools for testifying that your code will behave as you intend.&lt;/p&gt;
&lt;p&gt;Features include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/stretchr/testify#assert-package" rel="noopener noreferrer"&gt;Easy assertions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/stretchr/testify#mock-package" rel="noopener noreferrer"&gt;Mocking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/stretchr/testify#suite-package" rel="noopener noreferrer"&gt;Testing suite interfaces and functions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Get started:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install testify with &lt;a href="https://github.com/stretchr/testify#installation" rel="noopener noreferrer"&gt;one line of code&lt;/a&gt;, or &lt;a href="https://github.com/stretchr/testify#staying-up-to-date" rel="noopener noreferrer"&gt;update it with another&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;For an introduction to writing test code in Go, see &lt;a href="https://go.dev/doc/code#Testing" rel="nofollow noopener noreferrer"&gt;https://go.dev/doc/code#Testing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Check out the API Documentation &lt;a href="https://pkg.go.dev/github.com/stretchr/testify" rel="nofollow noopener noreferrer"&gt;https://pkg.go.dev/github.com/stretchr/testify&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://github.com/Antonboom/testifylint" rel="noopener noreferrer"&gt;testifylint&lt;/a&gt; (via &lt;a href="https://golangci-lint.run/" rel="nofollow noopener noreferrer"&gt;golanci-lint&lt;/a&gt;) to avoid common mistakes&lt;/li&gt;
&lt;li&gt;A little about &lt;a href="https://en.wikipedia.org/wiki/Test-driven_development" rel="nofollow noopener noreferrer"&gt;Test-Driven Development (TDD)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;
&lt;a href="https://pkg.go.dev/github.com/stretchr/testify/assert" title="API documentation" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;assert&lt;/code&gt;&lt;/a&gt; package&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;assert&lt;/code&gt; package provides some helpful methods that allow you to write better test code in Go.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prints friendly, easy to read failure descriptions&lt;/li&gt;
&lt;li&gt;Allows for very readable code&lt;/li&gt;
&lt;li&gt;Optionally annotate each assertion with a message&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See it in action:&lt;/p&gt;
&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;package&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/stretchr/testify" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  8. Go-yaml
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;2,692&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/go-yaml" rel="noopener noreferrer"&gt;
        go-yaml
      &lt;/a&gt; / &lt;a href="https://github.com/go-yaml/yaml" rel="noopener noreferrer"&gt;
        yaml
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      YAML support for the Go language.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;YAML support for the Go language&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Introduction&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The yaml package enables Go programs to comfortably encode and decode YAML
values. It was developed within &lt;a href="https://www.canonical.com" rel="nofollow noopener noreferrer"&gt;Canonical&lt;/a&gt; as
part of the &lt;a href="https://juju.ubuntu.com" rel="nofollow noopener noreferrer"&gt;juju&lt;/a&gt; project, and is based on a
pure Go port of the well-known &lt;a href="http://pyyaml.org/wiki/LibYAML" rel="nofollow noopener noreferrer"&gt;libyaml&lt;/a&gt;
C library to parse and generate YAML data quickly and reliably.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Compatibility&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The yaml package supports most of YAML 1.2, but preserves some behavior
from 1.1 for backwards compatibility.&lt;/p&gt;
&lt;p&gt;Specifically, as of v3 of the yaml package:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;YAML 1.1 bools (&lt;em&gt;yes/no, on/off&lt;/em&gt;) are supported as long as they are being
decoded into a typed bool value. Otherwise they behave as a string. Booleans
in YAML 1.2 are &lt;em&gt;true/false&lt;/em&gt; only.&lt;/li&gt;
&lt;li&gt;Octals encode and decode as &lt;em&gt;0777&lt;/em&gt; per YAML 1.1, rather than &lt;em&gt;0o777&lt;/em&gt;
as specified in YAML 1.2, because most parsers still use the old format
Octals in the  &lt;em&gt;0o777&lt;/em&gt; format are supported though, so new files…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/go-yaml/yaml" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Gomock + mockgen
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;2,023&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Gomock is a testing library that allows you to mock your dependencies and to make assertions on them. Mockgen is a CLI tool packaged with gomock to create your mocks.&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/golang" rel="noopener noreferrer"&gt;
        golang
      &lt;/a&gt; / &lt;a href="https://github.com/golang/mock" rel="noopener noreferrer"&gt;
        mock
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      GoMock is a mocking framework for the Go programming language.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;gomock&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Update, June 2023&lt;/strong&gt;: &lt;em&gt;This repo and tool are no longer maintained
Please see &lt;a href="https://github.com/uber/mock" rel="noopener noreferrer"&gt;go.uber.org/mock&lt;/a&gt; for a maintained fork instead.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/golang/mock/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/golang/mock/actions/workflows/test.yaml/badge.svg" alt="Build Status"&gt;&lt;/a&gt; &lt;a href="https://pkg.go.dev/github.com/golang/mock" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f66763d1b86e4b9f4cec1d00c67ced453d7feb058a90fe5bdf6ebaee8258a693/68747470733a2f2f706b672e676f2e6465762f62616467652f6769746875622e636f6d2f676f6c616e672f6d6f636b2e737667" alt="Go Reference"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;gomock is a mocking framework for the &lt;a href="http://golang.org/" rel="nofollow noopener noreferrer"&gt;Go programming language&lt;/a&gt;. It
integrates well with Go's built-in &lt;code&gt;testing&lt;/code&gt; package, but can be used in other
contexts too.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Once you have &lt;a href="http://golang.org/doc/install.html#releases" rel="nofollow noopener noreferrer"&gt;installed Go&lt;/a&gt;, install the &lt;code&gt;mockgen&lt;/code&gt; tool.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If you have not done so already be sure to add &lt;code&gt;$GOPATH/bin&lt;/code&gt; to your
&lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To get the latest released version use:&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Go version &amp;lt; 1.16&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;GO111MODULE=on go get github.com/golang/mock/mockgen@v1.6.0&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Go 1.16+&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;go install github.com/golang/mock/mockgen@v1.6.0&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;If you use &lt;code&gt;mockgen&lt;/code&gt; in your CI pipeline, it may be more appropriate to fixate
on a specific mockgen version. You should try to keep the library in sync with
the version of mockgen used to generate your mocks.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Running mockgen&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;mockgen&lt;/code&gt; has two modes of operation: source and reflect.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Source mode&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Source…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/golang/mock" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  2. Modd
&lt;/h3&gt;

&lt;p&gt;🌠 &lt;em&gt;977&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A file watcher allowing you to restart your app, to run your unit tests and much more&lt;/em&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/cortesi" rel="noopener noreferrer"&gt;
        cortesi
      &lt;/a&gt; / &lt;a href="https://github.com/cortesi/modd" rel="noopener noreferrer"&gt;
        modd
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A flexible developer tool that runs processes and responds to filesystem changes
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://travis-ci.org/cortesi/modd" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f5fee6d39e79cf8597ee029e7c6f97e89a9e6aec891fcb92c32a95857dc1d2b9/68747470733a2f2f7472617669732d63692e6f72672f636f72746573692f6d6f64642e7376673f6272616e63683d6d6173746572" alt="Travis Build Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Modd is a developer tool that triggers commands and manages daemons in response
to filesystem changes.&lt;/p&gt;
&lt;p&gt;If you use modd, you should also look at
&lt;a href="https://github.com/cortesi/devd" rel="noopener noreferrer"&gt;devd&lt;/a&gt;, a compact HTTP daemon for developers
Devd integrates with modd, allowing you to trigger in-browser livereload with
modd.&lt;/p&gt;
&lt;p&gt;The repo contains a set of example &lt;em&gt;modd.conf&lt;/em&gt; files that you can look at for a
quick idea of what modd can do:&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/cortesi/modd./examples/frontend.conf" rel="noopener noreferrer"&gt;frontend.conf&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;A front-end project with React + Browserify + Babel. Modd and devd replace many functions of Gulp/Grunt.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/cortesi/modd./examples/go.conf" rel="noopener noreferrer"&gt;go.conf&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Live unit tests for Go.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/cortesi/modd./examples/python.conf" rel="noopener noreferrer"&gt;python.conf&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Python + Redis, with devd managing livereload.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Install&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Modd is a single binary with no external dependencies, released for OSX
Windows, Linux, FreeBSD, NetBSD and OpenBSD. Go to the &lt;a href="https://github.com/cortesi/modd/releases/latest" rel="noopener noreferrer"&gt;releases
page&lt;/a&gt;, download the package for
your OS, and copy the binary to somewhere on your PATH.&lt;/p&gt;
&lt;p&gt;Alternatively, with Go 1.17+ installed, you can install…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/cortesi/modd" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;I hope that you'll find some of these libs/tools useful for your needs.&lt;/p&gt;

&lt;p&gt;Don't hesitate to propose the ones you find great.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>go</category>
      <category>tools</category>
      <category>githunt</category>
      <category>framework</category>
    </item>
    <item>
      <title>My PHP Toolkit to Build a (quite) Frameworkless App</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Tue, 22 Jan 2019 23:15:08 +0000</pubDate>
      <link>https://dev.to/biros/my-php-toolkit-to-build-a-quite-frameworkless-app-5f8g</link>
      <guid>https://dev.to/biros/my-php-toolkit-to-build-a-quite-frameworkless-app-5f8g</guid>
      <description>&lt;p&gt;Hey, let me introduce you some of the libraries &amp;amp; tools I've been using in many PHP projects running in production.&lt;/p&gt;

&lt;p&gt;I'm used to build my own framework by picking up libs in the below list each time I start a new PHP project. But to be honest, I must admit that I still use a micro-framework for basic HTTP stuff: &lt;a href="https://www.slimframework.com/" rel="noopener noreferrer"&gt;Slim&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;📝 &lt;em&gt;I use no ORM and I mainly build backend apps with Web APIs.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Libraries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Slim Framework
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3asza6ur405zc7usx81a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3asza6ur405zc7usx81a.png" alt="slim"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Micro-Framework intended to build Web APIs&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;9,475&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/slimphp/Slim" rel="noopener noreferrer"&gt;slimphp/slim&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Slim Framework CSRF protection middleware
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/slimphp" rel="noopener noreferrer"&gt;
        slimphp
      &lt;/a&gt; / &lt;a href="https://github.com/slimphp/Slim-Csrf" rel="noopener noreferrer"&gt;
        Slim-Csrf
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Slim Framework CSRF protection middleware
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Slim Framework CSRF Protection&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://travis-ci.org/slimphp/Slim-Csrf" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f2e2d5ed8209de93006414f0d57b7c375ace03eb695bd10042c354696f341751/68747470733a2f2f7472617669732d63692e6f72672f736c696d7068702f536c696d2d437372662e7376673f6272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://coveralls.io/github/slimphp/Slim-Csrf?branch=master" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/551c72a44d5f932b678b2e7eedb105415619f02a1186f21d00f675b2bde690e0/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f736c696d7068702f536c696d2d437372662f62616467652e7376673f6272616e63683d6d6173746572" alt="Coverage Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This repository contains a Slim Framework CSRF protection PSR-15 middleware. CSRF protection applies to all unsafe HTTP requests (POST, PUT, DELETE, PATCH).&lt;/p&gt;
&lt;p&gt;You can fetch the latest CSRF token's name and value from the Request object with its &lt;code&gt;getAttribute()&lt;/code&gt; method. By default, the CSRF token's name is stored in the &lt;code&gt;csrf_name&lt;/code&gt; attribute, and the CSRF token's value is stored in the &lt;code&gt;csrf_value&lt;/code&gt; attribute.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Install&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Via Composer&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;$ composer require slim/csrf&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Requires Slim 4.0.0 or newer.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;In most cases you want to register Slim\Csrf for all routes, however, as it is middleware, you can also register it for a subset of routes.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Register for all routes&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-c1"&gt;DI&lt;/span&gt;\&lt;span class="pl-v"&gt;Container&lt;/span&gt;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Slim&lt;/span&gt;\&lt;span class="pl-v"&gt;Csrf&lt;/span&gt;\&lt;span class="pl-v"&gt;Guard&lt;/span&gt;;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Slim&lt;/span&gt;\&lt;span class="pl-v"&gt;Factory&lt;/span&gt;\&lt;span class="pl-v"&gt;AppFactory&lt;/span&gt;;

&lt;span class="pl-k"&gt;require&lt;/span&gt; &lt;span class="pl-c1"&gt;__DIR__&lt;/span&gt; . &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;/vendor/autoload.php&lt;/span&gt;'&lt;/span&gt;;

&lt;span class="pl-c"&gt;// Start PHP session&lt;/span&gt;
&lt;span class="pl-en"&gt;session_start&lt;/span&gt;();

&lt;span class="pl-c"&gt;// Create Container&lt;/span&gt;
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;container&lt;/span&gt; = &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;Container&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/slimphp/Slim-Csrf" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Protect your GUI pages with a CSRF token&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;201&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/slimphp/Slim-Csrf" rel="noopener noreferrer"&gt;slimphp/csrf&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Slim Framework Flash Messages
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/slimphp" rel="noopener noreferrer"&gt;
        slimphp
      &lt;/a&gt; / &lt;a href="https://github.com/slimphp/Slim-Flash" rel="noopener noreferrer"&gt;
        Slim-Flash
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Slim Framework flash messages service provider
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Slim Framework Flash Messages&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://travis-ci.org/slimphp/Slim-Flash" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/25faf6deb88a7feef285a02cd465426289875cf1ab1cdd7c81f31a148d1bbc70/68747470733a2f2f7472617669732d63692e6f72672f736c696d7068702f536c696d2d466c6173682e7376673f6272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This repository contains a Slim Framework Flash messages service provider. This enables you to define transient messages that persist only from the current request to the next request.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Install&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Via Composer&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;$ composer require slim/flash&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Requires Slim 3.0.0 or newer.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Slim 4&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;This example assumes that you have &lt;code&gt;php-di/php-di&lt;/code&gt; installed.&lt;/p&gt;
&lt;div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-ent"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-c1"&gt;DI&lt;/span&gt;\&lt;span class="pl-v"&gt;ContainerBuilder&lt;/span&gt;;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Slim&lt;/span&gt;\&lt;span class="pl-v"&gt;Factory&lt;/span&gt;\&lt;span class="pl-v"&gt;AppFactory&lt;/span&gt;;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Slim&lt;/span&gt;\&lt;span class="pl-v"&gt;Flash&lt;/span&gt;\&lt;span class="pl-v"&gt;Messages&lt;/span&gt;;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Slim&lt;/span&gt;\&lt;span class="pl-v"&gt;Routing&lt;/span&gt;\&lt;span class="pl-v"&gt;RouteContext&lt;/span&gt;;

&lt;span class="pl-k"&gt;require_once&lt;/span&gt; &lt;span class="pl-c1"&gt;__DIR__&lt;/span&gt; . &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;/../vendor/autoload.php&lt;/span&gt;'&lt;/span&gt;;

&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;containerBuilder&lt;/span&gt; = &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;ContainerBuilder&lt;/span&gt;();

&lt;span class="pl-c"&gt;// Add container definition for the flash component&lt;/span&gt;
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;containerBuilder&lt;/span&gt;-&amp;gt;&lt;span class="pl-en"&gt;addDefinitions&lt;/span&gt;(
    [
        &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;flash&lt;/span&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="pl-k"&gt;function&lt;/span&gt; () {
            &lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;storage&lt;/span&gt; = [];
            &lt;span class="pl-k"&gt;return&lt;/span&gt; &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;Messages&lt;/span&gt;(&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;storage&lt;/span&gt;);
        }
    ]
);

&lt;span class="pl-v"&gt;AppFactory&lt;/span&gt;::&lt;span class="pl-en"&gt;setContainer&lt;/span&gt;(&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;containerBuilder&lt;/span&gt;-&amp;gt;&lt;span class="pl-en"&gt;build&lt;/span&gt;());

&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;app&lt;/span&gt; = &lt;span class="pl-v"&gt;AppFactory&lt;/span&gt;::&lt;span class="pl-en"&gt;create&lt;/span&gt;();

&lt;span class="pl-c"&gt;// Add session start&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/slimphp/Slim-Flash" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;This enables you to define transient messages that persist only from the current request to the next request&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;104&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/slimphp/Slim-Flash" rel="noopener noreferrer"&gt;slimphp/flash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Twig
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flh4j75lvwillag3ht1z5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flh4j75lvwillag3ht1z5.png" alt="twig"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;A very popular template engine that integrates well with Slim (&lt;a href="https://github.com/slimphp/Twig-View" rel="noopener noreferrer"&gt;slimphp/twig-view&lt;/a&gt;)&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;5,705&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/twigphp/Twig" rel="noopener noreferrer"&gt;twigphp/twig&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Monolog
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Seldaek" rel="noopener noreferrer"&gt;
        Seldaek
      &lt;/a&gt; / &lt;a href="https://github.com/Seldaek/monolog" rel="noopener noreferrer"&gt;
        monolog
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Sends your logs to files, sockets, inboxes, databases and various web services
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Seldaek/monologlogo.jpg"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FSeldaek%2Fmonologlogo.jpg" alt="Monolog"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Monolog - Logging for PHP &lt;a href="https://github.com/Seldaek/monolog/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/Seldaek/monolog/workflows/Continuous%20Integration/badge.svg?branch=main" alt="Continuous Integration"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://packagist.org/packages/monolog/monolog" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0772fd73cfbf6b5f6808f9ea341981751f96e82a20978d826123f06677dc8436/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6f6e6f6c6f672f6d6f6e6f6c6f672e737667" alt="Total Downloads"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/monolog/monolog" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1694b48b8d30939989b17b11ecf8757e50d3f02009d68afcfce4fe8ec24f2b6e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6f6e6f6c6f672f6d6f6e6f6c6f672e737667" alt="Latest Stable Version"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; This is the &lt;strong&gt;documentation for Monolog 3.x&lt;/strong&gt;, if you are using older releases
see the documentation for &lt;a href="https://github.com/Seldaek/monolog/blob/2.x/README.md" rel="noopener noreferrer"&gt;Monolog 2.x&lt;/a&gt; or &lt;a href="https://github.com/Seldaek/monolog/blob/1.x/README.md" rel="noopener noreferrer"&gt;Monolog 1.x&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Monolog sends your logs to files, sockets, inboxes, databases and various
web services. See the complete list of handlers below. Special handlers
allow you to build advanced logging strategies.&lt;/p&gt;
&lt;p&gt;This library implements the &lt;a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md" rel="noopener noreferrer"&gt;PSR-3&lt;/a&gt;
interface that you can type-hint against in your own libraries to keep
a maximum of interoperability. You can also use it in your applications to
make sure you can always use another compatible logger at a later time
As of 1.11.0 Monolog public APIs will also accept PSR-3 log levels
Internally Monolog still uses its own level scheme since it predates PSR-3.&lt;/p&gt;
&lt;div&gt;
  
  &lt;sup&gt;&lt;b&gt;Sponsored by:&lt;/b&gt;&lt;/sup&gt;
  &lt;br&gt;
  &lt;a href="https://betterstack.com" rel="nofollow noopener noreferrer"&gt;
    &lt;div&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F183678%2F288814555-7de58ce0-2fa2-45c0-b3e8-e60cebb3c4cf.png%3Fjwt%3DeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mjg0MDc0ODQsIm5iZiI6MTcyODQwNzE4NCwicGF0aCI6Ii8xODM2NzgvMjg4ODE0NTU1LTdkZTU4Y2UwLTJmYTItNDVjMC1iM2U4LWU2MGNlYmIzYzRjZi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQxMDA4JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MTAwOFQxNzA2MjRaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1hOGZhMDMzMTk1NGJiMzI3OWE5NGUyZGQ3NmRlMmY5MzA2NjBkMTE0ZGNkZDA5YzY1N2FiNTgxNDM4MTJlMDY2JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.hrSV0_duaVojggvckuiCnu6OIyZs4AwjbmLtYr5_HYw" width="200" alt="Better Stack"&gt;
    &lt;/div&gt;
    &lt;div&gt;
      Better Stack lets you centralize, search, and visualize your logs.
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;br&gt;
  
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Install the latest version with&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;composer require monolog/monolog&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Basic Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-ent"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="pl-k"&gt;use&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Seldaek/monolog" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Sends your logs to files, sockets, inboxes, databases and various web services&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;13,388&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/Seldaek/monolog" rel="noopener noreferrer"&gt;seldaek/monolog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  6. Zend ACL permissions
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/zendframework" rel="noopener noreferrer"&gt;
        zendframework
      &lt;/a&gt; / &lt;a href="https://github.com/zendframework/zend-permissions-acl" rel="noopener noreferrer"&gt;
        zend-permissions-acl
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;zend-permissions-acl&lt;/h1&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Repository abandoned 2019-12-31&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;This repository has moved to &lt;a href="https://github.com/laminas/laminas-permissions-acl" rel="noopener noreferrer"&gt;laminas/laminas-permissions-acl&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://secure.travis-ci.org/zendframework/zend-permissions-acl" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d438a67d40314d60ec21fdd9d402ab3211b6cd1d4b33b2f1bc86a5c929edb4dd/68747470733a2f2f7365637572652e7472617669732d63692e6f72672f7a656e646672616d65776f726b2f7a656e642d7065726d697373696f6e732d61636c2e7376673f6272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://coveralls.io/github/zendframework/zend-permissions-acl?branch=master" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/db5d7d3b23efecb3a4fb94122ab69af7e9460ae9d8cfed54af699dd331075f43/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f7a656e646672616d65776f726b2f7a656e642d7065726d697373696f6e732d61636c2f62616467652e7376673f6272616e63683d6d6173746572" alt="Coverage Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provides a lightweight and flexible access control list (ACL) implementation for
privileges management.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;File issues at &lt;a href="https://github.com/zendframework/zend-permissions-acl/issues" rel="noopener noreferrer"&gt;https://github.com/zendframework/zend-permissions-acl/issues&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Documentation is at &lt;a href="https://docs.zendframework.com/zend-permissions-acl/" rel="nofollow noopener noreferrer"&gt;https://docs.zendframework.com/zend-permissions-acl/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/zendframework/zend-permissions-acl" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Provides a lightweight and flexible access control list (ACL) implementation for privileges management&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;55&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/zendframework/zend-permissions-acl" rel="noopener noreferrer"&gt;zendframework/zend-permissions-acl&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  7. Guzzle
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/guzzle" rel="noopener noreferrer"&gt;
        guzzle
      &lt;/a&gt; / &lt;a href="https://github.com/guzzle/guzzle" rel="noopener noreferrer"&gt;
        guzzle
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Guzzle, an extensible PHP HTTP client
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/guzzle/guzzle.github/logo.png?raw=true"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fguzzle%2Fguzzle.github%2Flogo.png%3Fraw%3Dtrue" alt="Guzzle"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Guzzle, PHP HTTP client&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/guzzle/guzzle/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/eeaae7856cc6fedf377d29b4a5ed866a6b42324022b19f89311503cb473c0a78/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f67757a7a6c652f67757a7a6c652e7376673f7374796c653d666c61742d737175617265" alt="Latest Version"&gt;&lt;/a&gt;
&lt;a href="https://github.com/guzzle/guzzle/actions?query=workflow%3ACI" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/dc0873c837684e330e84050e87520a3eeeeda163e20e9ced26031c0d791a8a5a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f67757a7a6c652f67757a7a6c652f63692e796d6c3f6c6162656c3d63692532306275696c64267374796c653d666c61742d737175617265" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/guzzlehttp/guzzle" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c6ad70d067369a671e45a5f32f926181b2bd2078e65a3f202eb40ac9f6929356/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f67757a7a6c65687474702f67757a7a6c652e7376673f7374796c653d666c61742d737175617265" alt="Total Downloads"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and
trivial to integrate with web services.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple interface for building query strings, POST requests, streaming large
uploads, streaming large downloads, using HTTP cookies, uploading JSON data
etc...&lt;/li&gt;
&lt;li&gt;Can send both synchronous and asynchronous requests using the same interface.&lt;/li&gt;
&lt;li&gt;Uses PSR-7 interfaces for requests, responses, and streams. This allows you
to utilize other PSR-7 compatible libraries with Guzzle.&lt;/li&gt;
&lt;li&gt;Supports PSR-18 allowing interoperability between other PSR-18 HTTP Clients.&lt;/li&gt;
&lt;li&gt;Abstracts away the underlying HTTP transport, allowing you to write
environment and transport agnostic code; i.e., no hard dependency on cURL
PHP streams, sockets, or non-blocking event loops.&lt;/li&gt;
&lt;li&gt;Middleware system allows you to augment and compose client behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;client&lt;/span&gt; = &lt;span class="pl-k"&gt;new&lt;/span&gt; \&lt;span class="pl-v"&gt;GuzzleHttp&lt;/span&gt;\&lt;span class="pl-v"&gt;Client&lt;/span&gt;()
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;response&lt;/span&gt; = &lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;client&lt;/span&gt;-&amp;gt;&lt;span class="pl-en"&gt;request&lt;/span&gt;(&lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;GET&lt;/span&gt;'&lt;/span&gt;, &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;https://api.github.com/repos/guzzle/guzzle&lt;/span&gt;'&lt;/span&gt;);

&lt;span class="pl-k"&gt;echo&lt;/span&gt; &lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/guzzle/guzzle" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;15,355&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/guzzle/guzzle" rel="noopener noreferrer"&gt;guzzlehttp/guzzle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  8. PDO
&lt;/h3&gt;

&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;PHP extension to build and execute secured SQL prepared statements&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="http://php.net/manual/en/book.pdo.php" rel="noopener noreferrer"&gt;PDO&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  9. Zend XML-RPC
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/zendframework" rel="noopener noreferrer"&gt;
        zendframework
      &lt;/a&gt; / &lt;a href="https://github.com/zendframework/zend-xmlrpc" rel="noopener noreferrer"&gt;
        zend-xmlrpc
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      XmlRpc component from Zend Framework
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;zend-xmlrpc&lt;/h1&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Repository abandoned 2019-12-31&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;This repository has moved to &lt;a href="https://github.com/laminas/laminas-xmlrpc" rel="noopener noreferrer"&gt;laminas/laminas-xmlrpc&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://secure.travis-ci.org/zendframework/zend-xmlrpc" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/918717895fcdc2f4baf9e37d56aff337867082a398f0f59017d6edb8dfc7a808/68747470733a2f2f7365637572652e7472617669732d63692e6f72672f7a656e646672616d65776f726b2f7a656e642d786d6c7270632e7376673f6272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://coveralls.io/github/zendframework/zend-xmlrpc?branch=master" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f7df8bb75f23de799f6decfdaf43d1031033e26aca646146b99907116bead98d/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f7a656e646672616d65776f726b2f7a656e642d786d6c7270632f62616467652e7376673f6272616e63683d6d6173746572" alt="Coverage Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From its home page, XML-RPC is described as a ”...remote procedure calling using
HTTP as the transport and XML as the encoding. XML-RPC is designed to be as
simple as possible, while allowing complex data structures to be transmitted,
processed and returned.”&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Zend\XmlRpc&lt;/code&gt; provides support for both consuming remote XML-RPC services and
building new XML-RPC servers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;File issues at &lt;a href="https://github.com/zendframework/zend-xmlrpc/issues" rel="noopener noreferrer"&gt;https://github.com/zendframework/zend-xmlrpc/issues&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Documentation is at &lt;a href="https://docs.zendframework.com/zend-xmlrpc/" rel="nofollow noopener noreferrer"&gt;https://docs.zendframework.com/zend-xmlrpc/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/zendframework/zend-xmlrpc" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Provides support for both consuming remote XML-RPC services and building new XML-RPC servers&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;14&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/zendframework/zend-xmlrpc" rel="noopener noreferrer"&gt;zendframework/zend-xmlrpc&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  10. PHPMailer
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/PHPMailer" rel="noopener noreferrer"&gt;
        PHPMailer
      &lt;/a&gt; / &lt;a href="https://github.com/PHPMailer/PHPMailer" rel="noopener noreferrer"&gt;
        PHPMailer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The classic email sending library for PHP
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://supportukrainenow.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fvshymanskyy%2FStandWithUkraine%2Fmain%2Fbanner2-direct.svg" alt="SWUbanner"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/6d4a0a8d2ca2b19852106a326edc638c302cb7a4bfa3300f83993f5c278762ff/68747470733a2f2f7261772e6769746875622e636f6d2f5048504d61696c65722f5048504d61696c65722f6d61737465722f6578616d706c65732f696d616765732f7068706d61696c65722e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/6d4a0a8d2ca2b19852106a326edc638c302cb7a4bfa3300f83993f5c278762ff/68747470733a2f2f7261772e6769746875622e636f6d2f5048504d61696c65722f5048504d61696c65722f6d61737465722f6578616d706c65732f696d616765732f7068706d61696c65722e706e67" alt="PHPMailer"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;PHPMailer – A full-featured email creation and transfer class for PHP&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/PHPMailer/PHPMailer/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/PHPMailer/PHPMailer/workflows/Tests/badge.svg" alt="Test status"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/PHPMailer/PHPMailer" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e8d290abf582d18a91f9275e33b7b4e878742877f72440f283439389073702b5/68747470733a2f2f636f6465636f762e696f2f67682f5048504d61696c65722f5048504d61696c65722f6272616e63682f6d61737465722f67726170682f62616467652e7376673f746f6b656e3d694f525a70776d596d4d" alt="codecov.io"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/phpmailer/phpmailer" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/082a4b469d55b1af070c588210496a9bd0497cb883cbca19dfeaed441e711fab/68747470733a2f2f706f7365722e707567782e6f72672f7068706d61696c65722f7068706d61696c65722f762f737461626c652e737667" alt="Latest Stable Version"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/phpmailer/phpmailer" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b56a00b49d58b84a7b4056742b90914f23635008ec6ed5a067ee975ff815af6c/68747470733a2f2f706f7365722e707567782e6f72672f7068706d61696c65722f7068706d61696c65722f646f776e6c6f616473" alt="Total Downloads"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/phpmailer/phpmailer" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/12c0c395cd01dd2fb0aec76e0000c8eb6a0fd6f7b65f9f52b0dbd6f289e60fd3/68747470733a2f2f706f7365722e707567782e6f72672f7068706d61696c65722f7068706d61696c65722f6c6963656e73652e737667" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://phpmailer.github.io/PHPMailer/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://github.com/phpmailer/phpmailer/workflows/Docs/badge.svg" alt="API Docs"&gt;&lt;/a&gt;
&lt;a href="https://api.securityscorecards.dev/projects/github.com/PHPMailer/PHPMailer" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e3aec1b3bdc455e8617e3e3d97c4a3dada7b95dc97106a46b9c2ac1dfd6cdd7f/68747470733a2f2f6170692e736563757269747973636f726563617264732e6465762f70726f6a656374732f6769746875622e636f6d2f5048504d61696c65722f5048504d61696c65722f6261646765" alt="OpenSSF Scorecard"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Probably the world's most popular code for sending email from PHP!&lt;/li&gt;
&lt;li&gt;Used by many open-source projects: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! and many more&lt;/li&gt;
&lt;li&gt;Integrated SMTP support – send without a local mail server&lt;/li&gt;
&lt;li&gt;Send emails with multiple To, CC, BCC, and Reply-to addresses&lt;/li&gt;
&lt;li&gt;Multipart/alternative emails for mail clients that do not read HTML email&lt;/li&gt;
&lt;li&gt;Add attachments, including inline&lt;/li&gt;
&lt;li&gt;Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings&lt;/li&gt;
&lt;li&gt;SMTP authentication with LOGIN, PLAIN, CRAM-MD5, and XOAUTH2 mechanisms over SMTPS and SMTP+STARTTLS transports&lt;/li&gt;
&lt;li&gt;Validates email addresses automatically&lt;/li&gt;
&lt;li&gt;Protects against header injection attacks&lt;/li&gt;
&lt;li&gt;Error messages in over 50 languages!&lt;/li&gt;
&lt;li&gt;DKIM and S/MIME signing support&lt;/li&gt;
&lt;li&gt;Compatible with PHP 5.5 and later, including PHP 8.2&lt;/li&gt;
&lt;li&gt;Namespaced to prevent name clashes&lt;/li&gt;
&lt;li&gt;Much more!&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why you might need it&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Many PHP developers need to send email from their code. The only…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/PHPMailer/PHPMailer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;A full-featured email creation and transfer class for PHP&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;12,422&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/PHPMailer/PHPMailer" rel="noopener noreferrer"&gt;phpmailer/phpmailer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  11. Firebase / PHP-JWT
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/firebase" rel="noopener noreferrer"&gt;
        firebase
      &lt;/a&gt; / &lt;a href="https://github.com/firebase/php-jwt" rel="noopener noreferrer"&gt;
        php-jwt
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      PHP package for JWT
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/firebase/php-jwt/actions/workflows/tests.yml/badge.svg"&gt;&lt;img src="https://github.com/firebase/php-jwt/actions/workflows/tests.yml/badge.svg" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/firebase/php-jwt" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fcc941fe683436b4cc7b2016585faf60bcdf687ef61c7bd6eafaa55c549fb2fb/68747470733a2f2f706f7365722e707567782e6f72672f66697265626173652f7068702d6a77742f762f737461626c65" alt="Latest Stable Version"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/firebase/php-jwt" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d43df504cbf866691af0cc81e4662ae07757bc73007fa434ba3e240b6b12ffec/68747470733a2f2f706f7365722e707567782e6f72672f66697265626173652f7068702d6a77742f646f776e6c6f616473" alt="Total Downloads"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/firebase/php-jwt" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ba42fd0d1e7532b625056045b34404fd38a3948d69ac09074f641fbffa9fe817/68747470733a2f2f706f7365722e707567782e6f72672f66697265626173652f7068702d6a77742f6c6963656e7365" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;PHP-JWT&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to &lt;a href="https://tools.ietf.org/html/rfc7519" rel="nofollow noopener noreferrer"&gt;RFC 7519&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Use composer to manage your dependencies and download PHP-JWT:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;composer require firebase/php-jwt&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Optionally, install the &lt;code&gt;paragonie/sodium_compat&lt;/code&gt; package from composer if your
php env does not have libsodium installed:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;composer require paragonie/sodium_compat&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Example&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Firebase&lt;/span&gt;\&lt;span class="pl-c1"&gt;JWT&lt;/span&gt;\&lt;span class="pl-c1"&gt;JWT&lt;/span&gt;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Firebase&lt;/span&gt;\&lt;span class="pl-c1"&gt;JWT&lt;/span&gt;\&lt;span class="pl-v"&gt;Key&lt;/span&gt;;

&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;key&lt;/span&gt; = &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;example_key&lt;/span&gt;'&lt;/span&gt;;
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;payload&lt;/span&gt; = [
    &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;iss&lt;/span&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;http://example.org&lt;/span&gt;'&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;aud&lt;/span&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;http://example.com&lt;/span&gt;'&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;iat&lt;/span&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="pl-c1"&gt;1356999524&lt;/span&gt;,
    &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;nbf&lt;/span&gt;'&lt;/span&gt; =&amp;gt; &lt;span class="pl-c1"&gt;1357000000&lt;/span&gt;
];

&lt;span class="pl-c"&gt;/**&lt;/span&gt;
&lt;span class="pl-c"&gt; * IMPORTANT:&lt;/span&gt;
&lt;span class="pl-c"&gt; * You must specify supported algorithms for your application. See&lt;/span&gt;
&lt;span class="pl-c"&gt; * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40&lt;/span&gt;
&lt;span class="pl-c"&gt; * for a list of spec-compliant algorithms.&lt;/span&gt;
&lt;span class="pl-c"&gt; */&lt;/span&gt;
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;jwt&lt;/span&gt; = &lt;span class="pl-c1"&gt;JWT&lt;/span&gt;::&lt;span class="pl-en"&gt;encode&lt;/span&gt;(&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;payload&lt;/span&gt;, &lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;key&lt;/span&gt;, &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;HS256&lt;/span&gt;'&lt;/span&gt;);
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;decoded&lt;/span&gt; = &lt;span class="pl-c1"&gt;JWT&lt;/span&gt;::&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/firebase/php-jwt" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to RFC 7519&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;4,574&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/firebase/php-jwt" rel="noopener noreferrer"&gt;firebase/php-jwt&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  12. Hassankhan / Config
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/hassankhan" rel="noopener noreferrer"&gt;
        hassankhan
      &lt;/a&gt; / &lt;a href="https://github.com/hassankhan/config" rel="noopener noreferrer"&gt;
        config
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Config is a lightweight configuration file loader that supports PHP, INI, XML, JSON, and YAML files
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Config&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://packagist.org/packages/hassankhan/config" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/516f751dd26e08c5bd655a9bf1738421a2fdb136d65843b5cdae7da5e6e026ff/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f68617373616e6b68616e2f636f6e6669672e7376673f7374796c653d666c61742d737175617265" alt="Latest version"&gt;&lt;/a&gt;
&lt;a href="http://hassankhan.mit-license.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5ddd6787b46ff6b3a6e8bfa779dc451433a990e470ffe28b66c8fb4a3e5035ca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265" alt="Software License"&gt;&lt;/a&gt;
&lt;a href="https://github.com/hassankhan/config/actions?query=workflow%3A%22Continuous+Integration%22+branch%3Amaster" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c03cb478fa10e9e51e411f0665f8811f91f2776b287f7548b53f2f36ad039f04/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f68617373616e6b68616e2f636f6e6669672f436f6e74696e756f7573253230496e746567726174696f6e2f6d61737465723f7374796c653d666c61742d737175617265" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://scrutinizer-ci.com/g/hassankhan/config/code-structure" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/20465f54ddc957db7381cbd10d1100ac442c7347d22a6e6746c8860b920533d9/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f68617373616e6b68616e2f636f6e6669672e7376673f7374796c653d666c61742d737175617265" alt="Coverage Status"&gt;&lt;/a&gt;
&lt;a href="https://scrutinizer-ci.com/g/hassankhan/config" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6f35736fd7fb3976b27e4794e81b99eaecf4febad31ac0f3f6a84e963066d958/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f68617373616e6b68616e2f636f6e6669672e7376673f7374796c653d666c61742d737175617265" alt="Quality Score"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/hassankhan/config" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/cfd1cef83b6208b645b238a9aeb0a6a3b153dac4bd2464f8f938fcaf8dccd5f6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f68617373616e6b68616e2f636f6e6669672e7376673f7374796c653d666c61742d737175617265" alt="Total Downloads"&gt;&lt;/a&gt;
&lt;a href="https://gitter.im/hassankhan/config?utm_source=badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=pr-badge" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c5c1edbf90b923326a1dde700dede2255c90e87b9b3edf7fa19b74bba4c2e75f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4749545445522d4a4f494e253230434841542532302545322538362539322d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265" alt="Gitter"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Config is a file configuration loader that supports PHP, INI, XML, JSON
YML, Properties and serialized files and strings.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Config requires PHP 7.4+.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; If you want to use YAML files or strings, require the &lt;a href="https://github.com/symfony/Yaml" rel="noopener noreferrer"&gt;Symfony Yaml component&lt;/a&gt; in your &lt;code&gt;composer.json&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;The supported way of installing Config is via Composer.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;$ composer require hassankhan/config&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Config is designed to be very simple and straightforward to use. All you can do with
it is load, get, and set.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Loading files&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;Config&lt;/code&gt; object can be created via the factory method &lt;code&gt;load()&lt;/code&gt;, or
by direct instantiation:&lt;/p&gt;
&lt;div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Noodlehaus&lt;/span&gt;\&lt;span class="pl-v"&gt;Config&lt;/span&gt;
&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;Noodlehaus&lt;/span&gt;\&lt;span class="pl-v"&gt;Parser&lt;/span&gt;\&lt;span class="pl-v"&gt;Json&lt;/span&gt;;

&lt;span class="pl-c"&gt;// Load a single file&lt;/span&gt;
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;conf&lt;/span&gt; = &lt;span class="pl-v"&gt;Config&lt;/span&gt;::&lt;span class="pl-en"&gt;load&lt;/span&gt;(&lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;config.json&lt;/span&gt;'&lt;/span&gt;);
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;conf&lt;/span&gt; = &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;Config&lt;/span&gt;(&lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;config.json&lt;/span&gt;'&lt;/span&gt;);

&lt;span class="pl-c"&gt;// Load values from multiple files&lt;/span&gt;
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;conf&lt;/span&gt; = &lt;span class="pl-k"&gt;new&lt;/span&gt; &lt;span class="pl-v"&gt;Config&lt;/span&gt;([&lt;span class="pl-s"&gt;'&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/hassankhan/config" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Config is a lightweight configuration file loader that supports PHP, INI, XML, JSON, and YAML files&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;749&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/hassankhan/config" rel="noopener noreferrer"&gt;hassankhan/config&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;As a PHP craftsman, the tools below are mandatory in my toolkit. Most of them (except &lt;em&gt;shellcheck&lt;/em&gt;) are installable through &lt;em&gt;composer&lt;/em&gt;, which allows you to add them as dev dependencies to your project's &lt;code&gt;composer.json&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Composer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cbi7vpgocrpdnqd24qt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cbi7vpgocrpdnqd24qt.png" alt="composer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Essential PHP dependency manager, and much more&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;18,049&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://getcomposer.org/" rel="noopener noreferrer"&gt;Composer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. PHPUnit
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfw7rb307bulnlozz5mn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfw7rb307bulnlozz5mn.png" alt="phpunit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Awesome unit tests framework with mocking features&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;12,785&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://phpunit.de/" rel="noopener noreferrer"&gt;PHPUnit&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  3. PHP Code Sniffer
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/squizlabs" rel="noopener noreferrer"&gt;
        squizlabs
      &lt;/a&gt; / &lt;a href="https://github.com/squizlabs/PHP_CodeSniffer" rel="noopener noreferrer"&gt;
        PHP_CodeSniffer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-alert markdown-alert-warning"&gt;
&lt;p class="markdown-alert-title"&gt;Warning&lt;/p&gt;
&lt;p&gt;This repository has been abandoned. Its successor is &lt;a href="https://github.com/PHPCSStandards/PHP_CodeSniffer/" rel="noopener noreferrer"&gt;PHPCSStandards/PHP_CodeSniffer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;See issue &lt;a href="https://github.com/squizlabs/PHP_CodeSniffer/issues/3932" rel="noopener noreferrer"&gt;#3932&lt;/a&gt; for more information.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;About&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;PHP_CodeSniffer is a set of two PHP scripts; the main &lt;code&gt;phpcs&lt;/code&gt; script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a second &lt;code&gt;phpcbf&lt;/code&gt; script to automatically correct coding standard violations. PHP_CodeSniffer is an essential development tool that ensures your code remains clean and consistent.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/squizlabs/PHP_CodeSniffer/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/squizlabs/PHP_CodeSniffer/workflows/Validate/badge.svg?branch=master" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://github.com/squizlabs/PHP_CodeSniffer/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/squizlabs/PHP_CodeSniffer/workflows/Test/badge.svg?branch=master" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="http://squizlabs.github.io/PHP_CodeSniffer/analysis/squizlabs/PHP_CodeSniffer" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/271ff46c3e250c8b3d160ba75359db55e2f4a4ee738c3ff53dd8694739546b75/687474703a2f2f737175697a6c6162732e6769746875622e696f2f5048505f436f6465536e69666665722f616e616c797369732f737175697a6c6162732f5048505f436f6465536e69666665722f67726164652e737667" alt="Code consistency"&gt;&lt;/a&gt;
&lt;a href="https://gitter.im/squizlabs/PHP_CodeSniffer?utm_source=badge&amp;amp;utm_medium=badge&amp;amp;utm_campaign=pr-badge&amp;amp;utm_content=badge" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ef3705254e766b5edea93f49291c6d9239f29b942cfdb84f3296d0e37898b067/68747470733a2f2f6261646765732e6769747465722e696d2f4a6f696e253230436861742e737667" alt="Join the chat at https://gitter.im/squizlabs/PHP_CodeSniffer"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;PHP_CodeSniffer requires PHP version 5.4.0 or greater, although individual sniffs may have additional requirements such as external applications and scripts. See the &lt;a href="https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options" rel="noopener noreferrer"&gt;Configuration Options manual page&lt;/a&gt; for a list of these requirements.&lt;/p&gt;
&lt;p&gt;If you're using PHP_CodeSniffer as part of a team, or you're running it on a &lt;a href="https://en.wikipedia.org/wiki/Continuous_integration" rel="nofollow noopener noreferrer"&gt;CI&lt;/a&gt; server, you may want to configure your project's settings &lt;a href="https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file" rel="noopener noreferrer"&gt;using a configuration file&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The easiest way to get started with PHP_CodeSniffer is to download the Phar files for each of…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/squizlabs/PHP_CodeSniffer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Static analysis tool to detect &amp;amp; fix coding standard violations&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;5,915&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/squizlabs/PHP_CodeSniffer" rel="noopener noreferrer"&gt;squizlabs/php_codesniffer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  4. PHP Mess Detector aka &lt;em&gt;phpmd&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kc00skih8ugbv7xv253.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kc00skih8ugbv7xv253.png" alt="phpmd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Static analysis tool to detect code smells, bad design, bugs, unused parameters, etc.&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;1,315&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://phpmd.org/" rel="noopener noreferrer"&gt;phpmd/phpmd&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  5. PHP Coding Standard Fixer aka &lt;em&gt;php-cs-fixer&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxs3enzauafd1gk7844n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxs3enzauafd1gk7844n.png" alt="php-cs-fixer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Automatically fixes coding standard violations&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;7,036&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/FriendsOfPHP/PHP-CS-Fixer" rel="noopener noreferrer"&gt;friendsofphp/php-cs-fixer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  6. SensioLabs Security Checker
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ylsde0rr2gl6zuckc4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ylsde0rr2gl6zuckc4g.png" alt="security-checker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;The SensioLabs Security Checker is a command line tool that checks if your application uses dependencies with known security vulnerabilities&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;1,397&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/sensiolabs/security-checker" rel="noopener noreferrer"&gt;sensiolabs/security-checker&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  7. XML Linter
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sclable" rel="noopener noreferrer"&gt;
        sclable
      &lt;/a&gt; / &lt;a href="https://github.com/sclable/xml-lint" rel="noopener noreferrer"&gt;
        xml-lint
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A php tool to lint and validate xml files from the commandline.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Sclable XML Lint&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A php tool to lint and validate xml files from the commandline.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://travis-ci.com/sclable/xml-lint" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0e7e289779645b2baceec9bdef3f7f4e7143bd5458f731ddb1cc6564655f2adb/68747470733a2f2f7472617669732d63692e636f6d2f73636c61626c652f786d6c2d6c696e742e7376673f6272616e63683d6d61696e" alt="Build Status"&gt;&lt;/a&gt; &lt;a href="https://github.com/sclable/xml-lint//packagist.org/packages/sclable/xml-lint" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/79baf015c043f934ea598d76c6aa3843fccbce47908d57b856656ab45ae7a9c5/68747470733a2f2f706f7365722e707567782e6f72672f73636c61626c652f786d6c2d6c696e742f76" alt="Latest Stable Version"&gt;&lt;/a&gt; &lt;a href="https://github.com/sclable/xml-lint//packagist.org/packages/sclable/xml-lint" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/777a8d1bc476174b15cd1de3cd304fee33ec70b2a1317281b35d804cefdd74bc/68747470733a2f2f706f7365722e707567782e6f72672f73636c61626c652f786d6c2d6c696e742f646f776e6c6f616473" alt="Total Downloads"&gt;&lt;/a&gt; &lt;a href="https://github.com/sclable/xml-lint//packagist.org/packages/sclable/xml-lint" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/297376cb718c6af3fef4cfdda596c475516469c1ce7c8dcfd6d41ce5ba0d87b3/68747470733a2f2f706f7365722e707567782e6f72672f73636c61626c652f786d6c2d6c696e742f6c6963656e7365" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;XML Lint checks the syntax of any xml files and validates the file against the XSD schema defined in the file.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installation with Composer&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;If you'd like to include this library in your project with &lt;a href="https://getcomposer.org/" rel="nofollow noopener noreferrer"&gt;composer&lt;/a&gt;, simply run:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;composer require "sclable/xml-lint"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Command Line Usage&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;To lint a single xml file:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;vendor/bin/xmllint path/to/file.xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To lint a directory and all its subdirectories:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;vendor/bin/xmllint path/to/dir
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;Help&lt;/h4&gt;

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;xmllint&lt;/code&gt; has built in cli help screen:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;vendor/bin/xmllint --help
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;Options&lt;/h4&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-v&lt;/code&gt; be verbose, display the filename of the current file to lint&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-r 0&lt;/code&gt; don't search recursive (if the argument is a directory)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-e name&lt;/code&gt; exclude files or directories containing 'name'&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-s&lt;/code&gt; skip the xsd validation&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Development&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Run tests&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; check code style&lt;/span&gt;
php tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --dry-run -v

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; run tests&lt;/span&gt;
php vendor/bin/phpunit
php vendor/bin/behat&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Using docker:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Example&lt;/span&gt;
docker&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sclable/xml-lint" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;A PHP tool to lint and validate XML files from the command line&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;6&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/sclable/xml-lint" rel="noopener noreferrer"&gt;sclable/xml-lint&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  8. YAML Linter
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/j13k" rel="noopener noreferrer"&gt;
        j13k
      &lt;/a&gt; / &lt;a href="https://github.com/j13k/yaml-lint" rel="noopener noreferrer"&gt;
        yaml-lint
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A compact command line linting tool for validating YAML files.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;yaml-lint&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://packagist.org/packages/j13k/yaml-lint" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/03ccb4f90c171acf7b9a5c82c561300e7427c6a914a2a73d765e4dadb57a56f5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6a31336b2f79616d6c2d6c696e742e7376673f7374796c653d666c61742d737175617265" alt="Latest Version on Packagist"&gt;&lt;/a&gt;
&lt;a href="https://github.com/j13k/yaml-lintLICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5ddd6787b46ff6b3a6e8bfa779dc451433a990e470ffe28b66c8fb4a3e5035ca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265" alt="Software License"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/j13k/yaml-lint/stats" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/17401d5f98954be47ce46d51f95b336e54e1f1c436040f7c8de2bc260b7a8a79/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6a31336b2f79616d6c2d6c696e742e7376673f7374796c653d666c61742d737175617265" alt="Total Downloads"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/j13k/yaml-lint/stats" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/56bc76da667ce75d0a86da115e70ebb1d360359ca0a278e2f9085095f7858181/68747470733a2f2f706f7365722e707567782e6f72672f6a31336b2f79616d6c2d6c696e742f642f6d6f6e74686c79" alt="Monthly Downloads"&gt;&lt;/a&gt;
&lt;a href="https://github.com/j13k/yaml-lint/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/j13k/yaml-lint/actions/workflows/ci.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A compact command line linting tool for validating YAML files, using the parsing facility of
the &lt;a href="https://github.com/symfony/yaml" rel="noopener noreferrer"&gt;Symfony Yaml Component&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;usage: yaml-lint [options] [input source]

  input source    Path to file(s), or "-" to read from standard input

  -q, --quiet     Restrict output to syntax errors
  -h, --help      Display this help
  -V, --version   Display application version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Install&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Composer&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;To get started using yaml-lint in a project, install it with Composer:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;composer require --dev j13k/yaml-lint&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;It can then be run from the project's &lt;code&gt;vendor/bin&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;To set up yaml-lint globally, install it in the Composer home directory:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;composer global require j13k/yaml-lint&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;It can then be run from the &lt;code&gt;bin&lt;/code&gt; directory of Composer home (typically  &lt;code&gt;~/.composer/vendor/bin&lt;/code&gt;).&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Binary&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;A binary edition , &lt;code&gt;yaml-lint.phar&lt;/code&gt;, is available for download
with &lt;a href="https://github.com/j13k/yaml-lint/releases" rel="noopener noreferrer"&gt;each release&lt;/a&gt;. This embeds the latest stable version of the Symfony
Yaml component that is current at the time of the release.&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/j13k/yaml-lint" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Compact command line utility for checking YAML file syntax&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;3&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/j13k/yaml-lint" rel="noopener noreferrer"&gt;j13k/yaml-lint&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  9. Dockerfile Linter
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/projectatomic" rel="noopener noreferrer"&gt;
        projectatomic
      &lt;/a&gt; / &lt;a href="https://github.com/projectatomic/dockerfile_lint" rel="noopener noreferrer"&gt;
        dockerfile_lint
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://nodei.co/npm/dockerfile_lint/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9a6b4f8ff48bbd41fd93bba573d1c0560a22595650e12bcd637c918ab9de6d50/68747470733a2f2f6e6f6465692e636f2f6e706d2f646f636b657266696c655f6c696e742e706e673f646f776e6c6f6164733d7472756526646f776e6c6f616452616e6b3d747275652673746172733d74727565" alt="NPM"&gt;&lt;/a&gt;
&lt;a href="https://travis-ci.org/projectatomic/dockerfile_lint" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f4371afcf22012a72a4f05fefc59545fe2bdae4d4c0922ce13b009486cff33c8/68747470733a2f2f7472617669732d63692e6f72672f70726f6a65637461746f6d69632f646f636b657266696c655f6c696e742e7376673f6272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;dockerfile-lint&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A rule based 'linter' for &lt;a href="https://docs.docker.com/engine/reference/builder/" rel="nofollow noopener noreferrer"&gt;Dockerfiles&lt;/a&gt;. The linter rules can be used  to check file syntax as well as arbitrary semantic and best practice attributes determined by the rule file writer
The linter can also be used to check LABEL rules against docker images.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Table of Contents&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#quickstart" rel="noopener noreferrer"&gt;Quickstart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/projectatomic/dockerfile_lint#extending-and-customizing-rule-files" rel="noopener noreferrer"&gt;Extending and Customizing: Rule Files&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#profile-section" rel="noopener noreferrer"&gt;Profile Section&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#general-section" rel="noopener noreferrer"&gt;General Section&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#rule-attributes" rel="noopener noreferrer"&gt;Rule Attributes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#line-rule-section" rel="noopener noreferrer"&gt;Line Rule Section&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#required-instruction-section" rel="noopener noreferrer"&gt;Required Instruction Section&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/projectatomic/dockerfile_lint#library-usage" rel="noopener noreferrer"&gt;Library Usage&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#nodejs-application-use" rel="noopener noreferrer"&gt;Node.js application use&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#command-line-use" rel="noopener noreferrer"&gt;Command Line use&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#credits" rel="noopener noreferrer"&gt;Credits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint#license" rel="noopener noreferrer"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Quickstart&lt;/h1&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Change to directory where you have a Dockerfile&lt;/li&gt;
&lt;li&gt;run&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Atomic CLI&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;    atomic run projectatomic/dockerfile-lint

    atomic run projectatomic/dockerfile-lint image &amp;lt;imageid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Docker CLI&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;    docker run -it --rm -v $PWD:/root/ \
           projectatomic/dockerfile-lint \
           dockerfile_lint [-f Dockerfile]

    docker run -it --rm -v $PWD:/root/  \
           -v /var/run/docker.sock:/var/run/docker.sock \
           projectatomic/dockerfile-lint \
           dockerfile_lint  image &amp;lt;imageid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By default, the linter runs in strict mode (errors and/or warnings result in non-zero return code). Run the command with &lt;code&gt;-p&lt;/code&gt;  or &lt;code&gt;--permissive&lt;/code&gt; to…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/projectatomic/dockerfile_lint" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Rule based Dockerfile linter&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;259&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/projectatomic/dockerfile_lint" rel="noopener noreferrer"&gt;projectatomic/dockerfile_lint&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  10. Shellcheck
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/koalaman" rel="noopener noreferrer"&gt;
        koalaman
      &lt;/a&gt; / &lt;a href="https://github.com/koalaman/shellcheck" rel="noopener noreferrer"&gt;
        shellcheck
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ShellCheck, a static analysis tool for shell scripts
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://github.com/koalaman/shellcheck/actions/workflows/build.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/koalaman/shellcheck/actions/workflows/build.yml/badge.svg" alt="Build Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;ShellCheck - A shell script static analysis tool&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;ShellCheck is a GPLv3 tool that gives warnings and suggestions for bash/sh shell scripts:&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/koalaman/shellcheckdoc/terminal.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fkoalaman%2Fshellcheckdoc%2Fterminal.png" alt="Screenshot of a terminal showing problematic shell script lines highlighted"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The goals of ShellCheck are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To point out and clarify typical beginner's syntax issues that cause a shell
to give cryptic error messages.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To point out and clarify typical intermediate level semantic problems that
cause a shell to behave strangely and counter-intuitively.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To point out subtle caveats, corner cases and pitfalls that may cause an
advanced user's otherwise working script to fail under future circumstances.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href="https://github.com/koalaman/shellcheckREADME.md#user-content-gallery-of-bad-code" rel="noopener noreferrer"&gt;the gallery of bad code&lt;/a&gt; for examples of what ShellCheck can help you identify!&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/koalaman/shellcheck#how-to-use" rel="noopener noreferrer"&gt;How to use&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#on-the-web" rel="noopener noreferrer"&gt;On the web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#from-your-terminal" rel="noopener noreferrer"&gt;From your terminal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#in-your-editor" rel="noopener noreferrer"&gt;In your editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#in-your-build-or-test-suites" rel="noopener noreferrer"&gt;In your build or test suites&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#installing" rel="noopener noreferrer"&gt;Installing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/koalaman/shellcheck#compiling-from-source" rel="noopener noreferrer"&gt;Compiling from source&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#installing-cabal" rel="noopener noreferrer"&gt;Installing Cabal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#compiling-shellcheck" rel="noopener noreferrer"&gt;Compiling ShellCheck&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#running-tests" rel="noopener noreferrer"&gt;Running tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/koalaman/shellcheck#gallery-of-bad-code" rel="noopener noreferrer"&gt;Gallery of bad code&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#quoting" rel="noopener noreferrer"&gt;Quoting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#conditionals" rel="noopener noreferrer"&gt;Conditionals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#frequently-misused-commands" rel="noopener noreferrer"&gt;Frequently misused commands&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#common-beginners-mistakes" rel="noopener noreferrer"&gt;Common beginner's mistakes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#style" rel="noopener noreferrer"&gt;Style&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/koalaman/shellcheck#data-and-typing-errors" rel="noopener noreferrer"&gt;Data and typing errors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/koalaman/shellcheck" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;A static analysis tool for shell scripts&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;13,440&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/koalaman/shellcheck" rel="noopener noreferrer"&gt;koalaman/shellcheck&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  11. Swagger CLI
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sbj2lfcwu5u3m4vjl7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sbj2lfcwu5u3m4vjl7t.png" alt="swagger-cli"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙋 &lt;strong&gt;Purpose:&lt;/strong&gt; &lt;em&gt;Validate Swagger/OpenAPI files in JSON or YAML format&lt;/em&gt;&lt;br&gt;
🌠 &lt;strong&gt;GitHub stars:&lt;/strong&gt; &lt;em&gt;125&lt;/em&gt;&lt;br&gt;
🔗 &lt;strong&gt;URL:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://github.com/APIDevTools/swagger-cli" rel="noopener noreferrer"&gt;APIDevTools/swagger-cli&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;All these tools can be run automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in your IDE&lt;/li&gt;
&lt;li&gt;in a git hook&lt;/li&gt;
&lt;li&gt;in your CI/CD pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to go further, please have a look at one of my former articles:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/biros" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F92151%2F877c4dbf-c4c1-4395-9329-c8af191aa66e.png" alt="biros"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/biros/-how-to-master-your-code-through-your-project-lifecycle-22-2pej" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;🚥 How to Automate Code Quality Checks in your Workflow? ⚙&lt;/h2&gt;
      &lt;h3&gt;Boris Jamot ✊ / ・ Sep 10 '18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#git&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#automation&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#cleancode&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#bash&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;See ya!&lt;/p&gt;

</description>
      <category>php</category>
      <category>tools</category>
      <category>githunt</category>
      <category>framework</category>
    </item>
    <item>
      <title>🐘 Unit Tests in PHP</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Tue, 15 Jan 2019 21:51:57 +0000</pubDate>
      <link>https://dev.to/biros/-unit-tests-in-php-3il7</link>
      <guid>https://dev.to/biros/-unit-tests-in-php-3il7</guid>
      <description>&lt;p&gt;Hi folks! I'm going to talk about the way I use to design my unit tests in PHP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;Let's start with a (my?) definition of unit testing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The goal of unit tests is to check the correct behavior of each of the public functions, be given a representative set of data.&lt;br&gt;
The important thing is that external calls inside these functions must be tested in dedicated tests and therefore needs to be mocked.&lt;br&gt;
The interest of having these tests is to run them each time you modify the codebase to verify that no regression was introduced.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a pre-requisite, the code needs to be &lt;em&gt;testing ready&lt;/em&gt; in the sense that we need that to allow mocking of the dependencies. In a given function, a dependency can be internal (e.g. another class of the project), or external (e.g. a call to 3rd-party library).&lt;/p&gt;

&lt;p&gt;I won't be talking about the way of making the code testable. I know two techniques to achieve that using the dependency injection principle, but maybe there are other alternatives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first, you can modify the interface of your function to pass all its dependencies as parameters (or using the constructor or setters),&lt;/li&gt;
&lt;li&gt;or you can use a &lt;strong&gt;Dependency Injection Container&lt;/strong&gt; (aka DIC) which is a common (anti?)pattern in software development (see &lt;a href="https://www.php-fig.org/psr/psr-11/" rel="noopener noreferrer"&gt;PHP's PSR11&lt;/a&gt; for further details).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code architecture
&lt;/h2&gt;

&lt;p&gt;When I start a new web project, I usually split my code in several distinct layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;em&gt;router&lt;/em&gt; (usually Slim router), responsible for processing HTTP requests,&lt;/li&gt;
&lt;li&gt;a &lt;em&gt;controller&lt;/em&gt; layer, responsible for data validation and output rendering,&lt;/li&gt;
&lt;li&gt;a &lt;em&gt;business&lt;/em&gt; layer, responsible for the business logic,&lt;/li&gt;
&lt;li&gt;a &lt;em&gt;mapper&lt;/em&gt; layer (aka DTO),&lt;/li&gt;
&lt;li&gt;a &lt;em&gt;model&lt;/em&gt; layer (aka DAO).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing so makes the code more testable. &lt;/p&gt;

&lt;p&gt;Some additional stuff may be required, depending on the needs, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;checkers&lt;/em&gt;, to validate inputs,&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;views&lt;/em&gt;, to render outputs,&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;middlewares&lt;/em&gt;, to add pre- and post-processing of HTTP requests,&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;routes&lt;/em&gt;, to manage the REST API's routes,&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;enablers&lt;/em&gt;, to manage outgoing requests to 3rd-party APIs (SMS, Email,...).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And finally, a bootstrap file to create all the things.&lt;/p&gt;

&lt;p&gt;The classical workflow is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;em&gt;controller&lt;/em&gt; gets called on a given function,&lt;/li&gt;
&lt;li&gt;it validates the input using a dedicated &lt;em&gt;checker&lt;/em&gt;,&lt;/li&gt;
&lt;li&gt;it calls the &lt;em&gt;business&lt;/em&gt; layer with verified input,

&lt;ul&gt;
&lt;li&gt;the &lt;em&gt;business&lt;/em&gt; layer optionally uses a &lt;em&gt;mapper&lt;/em&gt; to interact with the db&lt;/li&gt;
&lt;li&gt;it may also interact with a 3rd-party API through an &lt;em&gt;enabler&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;it optionally returns &lt;em&gt;models&lt;/em&gt; to the &lt;em&gt;controller&lt;/em&gt; layer&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;the &lt;em&gt;controller&lt;/em&gt; renders the &lt;em&gt;models&lt;/em&gt; returned by the &lt;em&gt;business&lt;/em&gt; layer using a dedicated &lt;em&gt;view&lt;/em&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;When I write unit tests for a given layer, I only test the behavior of the layer's functions and I mock the calls to the functions of the sub-layers. For example, when I write a test for a &lt;em&gt;controller&lt;/em&gt;, I mock the call to the &lt;em&gt;business&lt;/em&gt; layer, to the &lt;em&gt;checker&lt;/em&gt; and to the &lt;em&gt;view&lt;/em&gt;. When I write a test for a &lt;em&gt;business&lt;/em&gt; object, I mock the call to the &lt;em&gt;mapper&lt;/em&gt;, to the &lt;em&gt;enabler&lt;/em&gt; and to other &lt;em&gt;business&lt;/em&gt; objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's see what it looks like for a &lt;em&gt;controller&lt;/em&gt; with a bit of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/** @var UserBusiness */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$business&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="cd"&gt;/** @var UserChecker */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$checker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="cd"&gt;/** @var UserView */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$view&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;UserBusiness&lt;/span&gt; &lt;span class="nv"&gt;$business&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="kt"&gt;UserChecker&lt;/span&gt; &lt;span class="nv"&gt;$checker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="kt"&gt;UserView&lt;/span&gt; &lt;span class="nv"&gt;$view&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;business&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$business&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;checker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$checker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$view&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;checker&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;checkId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;business&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you can see 3 dependencies in the &lt;code&gt;getById&lt;/code&gt; function. I choose to pass these dependencies through the constructor of my &lt;code&gt;UserController&lt;/code&gt; class. Alternatively, I could have used a Container passed to the function (or to the constructor), or I could have passed the deps through the function's parameters. The result would have been the same: I have to mock these 3 deps to test the function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using mocks
&lt;/h2&gt;

&lt;p&gt;Thankfully, &lt;a href="https://phpunit.de/" rel="noopener noreferrer"&gt;PHPUnit&lt;/a&gt; comes with a great API to work with mocks (see &lt;a href="https://phpunit.readthedocs.io/en/7.4/test-doubles.html" rel="noopener noreferrer"&gt;Test Doubles&lt;/a&gt;). I won't cover all the features here, but the documentation worth a look.&lt;/p&gt;

&lt;p&gt;First, I need to mock the &lt;code&gt;checkId&lt;/code&gt; function of the &lt;code&gt;UserChecker&lt;/code&gt;. As you may guess, it raises an exception if the &lt;code&gt;id&lt;/code&gt; is wrongly formatted.&lt;br&gt;
Then, I mock the &lt;code&gt;getById&lt;/code&gt; function of the &lt;code&gt;UserBusiness&lt;/code&gt;.&lt;br&gt;
And finally, the &lt;code&gt;render&lt;/code&gt; function of the &lt;code&gt;UserView&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserControllerTest&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PHPUnit\Framework\TestCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testGetById_Ok&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$business&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;UserBusiness&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$checker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;UserChecker&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createMock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;UserView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$expectedId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$expectedUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expectedId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'doe'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$expectedResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'result'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nv"&gt;$checker&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;expects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;once&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'checkId'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expectedId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$business&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;expects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;once&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'getById'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expectedId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expectedUser&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$view&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;expects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;once&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'render'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expectedUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;willReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expectedResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$business&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$checker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$view&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$actualResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$controller&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expectedId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$expectedResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$actualResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same has to be done for every layers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Writing exhaustive unit tests can be painful as most of the time, you'll spent more time writing the test than writing the "real" code.&lt;br&gt;
But IMO, there is no acceptable trade-off when it comes to testing your app.&lt;br&gt;
I know that other testing techniques exists (like TDT), but I see them as complementary tests as they're closer to integration tests than to unit tests. But maybe I'm wrong?&lt;/p&gt;




&lt;p&gt;Please feel free to give your opinion!&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>php</category>
      <category>testing</category>
      <category>showdev</category>
      <category>codequality</category>
    </item>
    <item>
      <title>It's Been Three Months Since My First Go LoC 🤓 🎓 </title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Sat, 22 Dec 2018 23:13:49 +0000</pubDate>
      <link>https://dev.to/biros/its-been-three-months-since-my-first-go-loc----419d</link>
      <guid>https://dev.to/biros/its-been-three-months-since-my-first-go-loc----419d</guid>
      <description>&lt;p&gt;It's been 3 months since I wrote my first Line of Code in Golang.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/biros" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F92151%2F877c4dbf-c4c1-4395-9329-c8af191aa66e.png" alt="biros"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/biros/my-journey-from-php-to-go-55bd" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;My Journey from PHP to Go&lt;/h2&gt;
      &lt;h3&gt;Boris Jamot ✊ / ・ Sep 20 '18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#php&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#go&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#feedback&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I'm still excited about learning this new language but it seems I faced my first issues with Go. I'll talk about it later.&lt;/p&gt;

&lt;p&gt;I introduced one of my previous post by saying that PHP was my main language and that I won't switch definitively to Go. Maybe this could change...&lt;/p&gt;

&lt;p&gt;I really enjoy strong typing and compilation. I can have real-time feedback on my code without running it and without additional 3rd-party tools. The Go SDK is fully featured for linting, formatting, testing, compiling, running.&lt;/p&gt;

&lt;h1&gt;
  
  
  Reading from request's body
&lt;/h1&gt;

&lt;p&gt;In my previous post, I was also saying that Go was a language for craftsmen. But this was far from the truth. I'll take an example: in Go, if you want to read the HTTP request's body in a middleware to analyze it for logging purpose, it becomes tricky:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;LoggingMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandlerFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// first, read the body and put it in a variable&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ioutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error reading body: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"can't read body"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"incoming request's body: %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// And now, re-assign the request's body with the original data&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ioutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NopCloser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="c"&gt;// finally, call next handler&lt;/span&gt;
        &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServeHTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mrw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you may guess, reading the request's body makes it empty. That's why you have to re-assign it afterwards. That's because request's body is a kind of stream you can read byte after byte. It can be useful if you want to start the request's processing without having to read all the data. But in most cases, you don't need that.&lt;/p&gt;

&lt;h1&gt;
  
  
  (un)-marshalling
&lt;/h1&gt;

&lt;p&gt;(un)marshalling is another thing that is not straightforward. What you need to know is that unmarshalling from JSON, BSON, YAML or whatever to a struct will almost never fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
    &lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="s"&gt;`json:"age"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"name":"bob","age":25}`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;bob&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"name":"alice","address":"NY"}`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"err: %v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"bob: %v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alice: %v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;err: &amp;lt;nil&amp;gt;
bob: {bob 25}
alice: {alice 0}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, I omitted the &lt;code&gt;age&lt;/code&gt; attribute in the JSON of Alice, but Go unmarshals it with no error. Confusing? That's because Go allocates default values for all missing attributes. In fact, you just have to provide valid JSON. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that supplementary JSON attributes are just ignored.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What really confused me was that I expected unmarshalling to fail with missing attributes. But if you want to check what you really got in the JSON, you can't trust the unmarshalling, you have to do it by yourself by checking all the fields of your struct manually. If one of the field has the default value for its type (e.g. 0 for integers, or empty string), then it could mean that it was missing from the JSON. But it could also mean that the client sent &lt;code&gt;{"name":"alice","age":0}&lt;/code&gt;. Then, how to distinguish between missing attributes and attributes with default values? You could unmarshal to a &lt;code&gt;map[string]interface{}&lt;/code&gt; and check manually that no key is missing, but it would be so WTF?!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If someone knows a better solution, don't hesitate!&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Unit testing
&lt;/h1&gt;

&lt;p&gt;Writing unit tests is the worst part of my developer journey in Golang. As an experimented OOP developer in PHP and Java, I used to write a lot of unit tests to have the best code coverage I can reach. In order to achieve it, I design my code with a high usage of dependency injection to allow me to replace dependencies by mocks in unit tests. &lt;/p&gt;

&lt;p&gt;With Go, there is no equivalent of PHPUnit or JUnit that allows to quickly mock any dependency. Mocking in Go is based on interfaces. If you're using a struct as a dependency somewhere in your code, you have to write a custom interface for it. That's where Go lacks of consistency. Depending on the library you're using, if you're lucky, it will provide an interface and not a struct (that's the case for &lt;a href="https://github.com/gin-gonic/gin" rel="noopener noreferrer"&gt;gin-gonic&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/uber-go/zap" rel="noopener noreferrer"&gt;uber-go/zap&lt;/a&gt;). But otherwise, you may encounter the mocking hell (that's the case with &lt;a href="https://github.com/globalsign/mgo" rel="noopener noreferrer"&gt;mgo mongo driver&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The drawback of writing interfaces for dependency injection is that you will lose the completion in your IDE. Let me explain it: when you write an interface for a 3rd-party library, you just put the functions you need in it. It means that if some day you want to use another function of that library, you don't even know what are the available functions. You can't hit ctrl+Space on the object to auto-complete because it will only display the functions of your custom interface, not the one of the original library object. So you have to browse the official doc on internet.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Knowing that, I would recommend to prefer "mocking-ready" libraries. It will save your time!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mocking your dependencies
&lt;/h2&gt;

&lt;p&gt;Depending on your testing strategy, you may have to mock some parts of your code, or some external library. As I said earlier, the first thing is to use interfaces instead of structs in your code, wether it be in the prototypes of your functions or in a Dependency Injection Container.&lt;/p&gt;

&lt;p&gt;The principle is really simple: you just have to switch the real object with a struct implementing the interface you want to mock. You can do it manually, or you can do it with &lt;a href="https://github.com/golang/mock" rel="noopener noreferrer"&gt;gomock&lt;/a&gt; if you want a fully featured mock, allowing you to count the number of calls, to check the types or even to capture the arguments. The only drawback of gomock is that you have to generate the mocks manually, and to update them each time you modify the interface. You also have to commit the mocks along with your "real" code.&lt;/p&gt;

&lt;h1&gt;
  
  
  My custom development environment
&lt;/h1&gt;

&lt;p&gt;In my first post about Go, I was saying that I tried many IDE: Atom, Intellij Ultimate and Vim. After that, I also tried Visual Studio Code which was pretty nice, but none of them fully statisfied me. So, as many of my colleagues use Intellij, I gave it a new try and finally succeeded to make it work. I use it to write code, but also to debug and to browse the code.&lt;/p&gt;

&lt;p&gt;Apart from Intellij, I also have a customized terminal with 3 panes using tmux. One of the panes is for playing with git or to type any other command. One is dedicated to vim. The last one is to run my app, check my conf and run the tests, all of this being possible with &lt;a href="https://github.com/cortesi/modd" rel="noopener noreferrer"&gt;modd&lt;/a&gt;, a file watcher:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;any modification of the codebase triggers a new run of my app (&lt;code&gt;go run ./...&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;any modification of a test file triggers the tests (&lt;code&gt;go test ./...&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;any modification of my conf files triggers a new check using &lt;a href="https://github.com/Grokzen/pykwalify" rel="noopener noreferrer"&gt;pykwalify&lt;/a&gt; which is a JSON/YAML validator.
The 3rd pane is a Vim allowing me to quickly edit files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;What I miss the most as a PHP developer is the community and the online resources. It seems like the official Go doc (which is great) is quite the only available resource, except posts on StackOverflow.&lt;br&gt;
What is also confusing is that if you google something like "go + stuff", you won't get many results. You'll have more luck with "golang + stuff".&lt;/p&gt;

&lt;p&gt;Anyway, these obstacles didn't hindered my motivation and my enthusiasm. I love the simplicity of the language.&lt;/p&gt;

&lt;p&gt;I'll keep you informed of my progress in a future post.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>go</category>
      <category>learning</category>
      <category>feedback</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🌍 Where Are DEV Users Coming From?</title>
      <dc:creator>Boris Jamot ✊ /</dc:creator>
      <pubDate>Fri, 30 Nov 2018 23:30:47 +0000</pubDate>
      <link>https://dev.to/biros/where-are-dev-users-coming-from-4l53</link>
      <guid>https://dev.to/biros/where-are-dev-users-coming-from-4l53</guid>
      <description>&lt;p&gt;As you may already know, dev.to has an API to fetch articles and users.&lt;/p&gt;

&lt;p&gt;Let's give it a try with my favorite HTTP client, &lt;a href="https://httpie.org/" rel="noopener noreferrer"&gt;httpie&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http https://dev.to/api/users/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"github_username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"benhalpern"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"joined_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Dec 27, 2015"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Brooklyn, NY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ben Halpern"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"profile_image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://res.cloudinary.com/practicaldev/image/fetch/s--DOU9qJSH--/c_fill,f_auto,fl_progressive,h_320,q_auto,w_320/https://thepracticaldev.s3.amazonaws.com/uploads/user/profile_image/1/f451a206-11c8-4e3d-8936-143d0a7e65bb.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A Canadian software developer who thinks he’s funny."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"twitter_username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bendhalpern"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type_of"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ben"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"website_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://benhalpern.com"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What I first noticed is that &lt;code&gt;id&lt;/code&gt; seems to be auto-incremented.&lt;br&gt;
After some tries, I quickly found out the total number of users on dev.to: around &lt;code&gt;119000&lt;/code&gt;.&lt;br&gt;
It gives me the idea to scrape all the users public data and try to play with it. &lt;/p&gt;

&lt;p&gt;Let's try with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..119000&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;http https://dev.to/api/users/&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; users.dev.to.json &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;","&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; users.dev.to.json &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"https://dev.to/api/users/&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a few hours running in the background, I finally got all the users in my JSON file.&lt;/p&gt;

&lt;p&gt;I ended up by importing the JSON file in a mongodb collection using &lt;a href="https://nosqlbooster.com/home" rel="noopener noreferrer"&gt;NoSQLBooster&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There isn't many information in the users' profile, but two of them worth having a look at them: &lt;code&gt;joined_at&lt;/code&gt; and &lt;code&gt;location&lt;/code&gt;. It could be very interesting to have a diagram showing the progression of registrations through time. Maybe I'll do it some day, but for now, let's compute some statistics on users' location.&lt;/p&gt;

&lt;p&gt;I used two queries to compute the statistics. This one helped me to get the big trends in people's location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users.dev.to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$group&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$location&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="na"&gt;$sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-count&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I use another query to get the count of people per location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users.dev.to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;location&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;bdublin&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The conclusions are the following:&lt;/p&gt;

&lt;p&gt;Most of the users (90%) don't fill their location.&lt;br&gt;
16.3% of the users who filled their location are from &lt;code&gt;USA&lt;/code&gt;.&lt;br&gt;
5.8% are from &lt;code&gt;India&lt;/code&gt;.&lt;br&gt;
4.9% are from &lt;code&gt;UK&lt;/code&gt;.&lt;br&gt;
4% are from &lt;code&gt;Japan&lt;/code&gt;.&lt;br&gt;
3.8% are from &lt;code&gt;Germany&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's have a look at the full statistics below:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;country&lt;/th&gt;
&lt;th&gt;region or city&lt;/th&gt;
&lt;th&gt;#region or city&lt;/th&gt;
&lt;th&gt;#country&lt;/th&gt;
&lt;th&gt;%&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;USA&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;1850&lt;/td&gt;
&lt;td&gt;16.32%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl New York&lt;/td&gt;
&lt;td&gt;205&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl CA&lt;/td&gt;
&lt;td&gt;194&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl NY&lt;/td&gt;
&lt;td&gt;147&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl San Francisco&lt;/td&gt;
&lt;td&gt;137&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl TX&lt;/td&gt;
&lt;td&gt;119&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Seattle&lt;/td&gt;
&lt;td&gt;117&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Los Angeles&lt;/td&gt;
&lt;td&gt;107&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Chicago&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Washington&lt;/td&gt;
&lt;td&gt;81&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl FL&lt;/td&gt;
&lt;td&gt;78&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl PA&lt;/td&gt;
&lt;td&gt;68&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl MA&lt;/td&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl AZ&lt;/td&gt;
&lt;td&gt;38&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl MI&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl OH&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;India&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;660&lt;/td&gt;
&lt;td&gt;5.82%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Bangalore&lt;/td&gt;
&lt;td&gt;107&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Delhi&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;UK&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;551&lt;/td&gt;
&lt;td&gt;4.86%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl London&lt;/td&gt;
&lt;td&gt;258&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl England&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Scotland&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Wales&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Japan&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;451&lt;/td&gt;
&lt;td&gt;3.98%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Tokyo&lt;/td&gt;
&lt;td&gt;242&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Germany&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;428&lt;/td&gt;
&lt;td&gt;3.77%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Berlin&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Brazil&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;301&lt;/td&gt;
&lt;td&gt;2.65%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;France&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;294&lt;/td&gt;
&lt;td&gt;2.59%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Paris&lt;/td&gt;
&lt;td&gt;98&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Canada&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;257&lt;/td&gt;
&lt;td&gt;2.27%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Toronto&lt;/td&gt;
&lt;td&gt;107&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Nigeria&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;187&lt;/td&gt;
&lt;td&gt;1.65%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Lagos&lt;/td&gt;
&lt;td&gt;97&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Netherlands&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;154&lt;/td&gt;
&lt;td&gt;1.36%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Incl Amsterdam&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Spain&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;110&lt;/td&gt;
&lt;td&gt;0.97%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Argentina&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;109&lt;/td&gt;
&lt;td&gt;0.96%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;Italy&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;0.90%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Indonesia&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;92&lt;/td&gt;
&lt;td&gt;0.81%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Russia&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;89&lt;/td&gt;
&lt;td&gt;0.78%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;Mexico&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;86&lt;/td&gt;
&lt;td&gt;0.76%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;Philippines&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;td&gt;0.75%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;Poland&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;81&lt;/td&gt;
&lt;td&gt;0.71%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;Ukraine&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;td&gt;0.66%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Portugal&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;63&lt;/td&gt;
&lt;td&gt;0.56%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;South Africa&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;td&gt;0.50%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;Pakistan&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;0.49%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;Turkey&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;55&lt;/td&gt;
&lt;td&gt;0.49%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;Belgium&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;td&gt;0.47%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;Egypt&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;52&lt;/td&gt;
&lt;td&gt;0.46%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;Bangladesh&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;0.44%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;Colombia&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;td&gt;0.41%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;Romania&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;0.40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;Kenya&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;0.40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;Switzerland&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;0.40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;Austria&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;0.38%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;China&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;0.35%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;Norway&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;38&lt;/td&gt;
&lt;td&gt;0.34%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;Ireland&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;0.29%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Total main locations&lt;/strong&gt; (listed above)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6683&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;58.94%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Other locations&lt;/strong&gt; (unlisted)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4656&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;41.06%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Total locations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;11339&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100.00%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;&lt;code&gt;&amp;lt;null&amp;gt;&lt;/code&gt;&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;90260&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;80.80%&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;&lt;code&gt;&amp;lt;empty&amp;gt;&lt;/code&gt;&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;10108&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;9.05%&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;111707&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: these numbers are one month old, but they give a good overview of the trends.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>meta</category>
      <category>statistics</category>
      <category>mongodb</category>
      <category>json</category>
    </item>
  </channel>
</rss>
