<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[MatsieFTW!]]></title><description><![CDATA[What's for Lunch?]]></description><link>http://matsie.net/</link><generator>Ghost 0.11</generator><lastBuildDate>Sat, 21 Jul 2018 18:36:08 GMT</lastBuildDate><atom:link href="http://matsie.net/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Sending Messages to Users on a Server]]></title><description><![CDATA[How to send messages to users logged into a server using a shell script.]]></description><link>http://matsie.net/sending-messages-to-users-on-a-server/</link><guid isPermaLink="false">cc3176f0-77db-42f7-a573-90a4f21cbdcf</guid><category><![CDATA[shell]]></category><category><![CDATA[command line]]></category><category><![CDATA[git]]></category><dc:creator><![CDATA[Mattie Kenny]]></dc:creator><pubDate>Fri, 06 Jan 2017 01:07:12 GMT</pubDate><content:encoded><![CDATA[<p>Programmers are inherently idiosyncratic creatures, in my opinion. These idiosyncrasies manifest can spawn both innovation and stagnation in our coding practices. But I have recently been met with idiosyncrasies that have caused some Bad Coding Habits<sup>TM</sup> in some of my teammates that none of my attempts to address have seemed to squash.</p>

<p>Some of my teammates have become accustomed to some bad git habits. They leave tons of uncommitted and unstashed changes on shared repos and don't clean up old branches. These kinds of behaviors can manifest in any team. We all develop Bad Coding Habits<sup>TM</sup>. I know I have several I should do more to break.</p>

<p>Becoming frustrated with my team's growing problem with git etiquette, I decided to create a cron job to send a gentle reminder to my teammates to do some housekeeping. I created a bash script to send a randomized wall message on Tuesdays and Thursdays to anyone logged into our demo server. This may seem like using dynamite to catch a fish, but part of me really just wanted to figure out how to do something like this.</p>

<h2 id="yougetamessageandyougetamessageandyougetamessage">You Get a Message! And You Get a Message! And You Get a Message!</h2>

<p>I knew a few things going in to this: <br>
1. I need to send a message to all users logged into our demo server. <br>
2. I wanted the message to not say it was specifically from me because I felt it'd be ignored. <br>
3. I wanted to be able to send a randomized message from a list of messages.</p>

<p>Knowing this, I knew I had to write a cronjob (a scheduled action on a server) that executed a <a href="http://man7.org/linux/man-pages/man1/wall.1.html">wall message</a>. With this knowledge, all I had left to do was write out my messages and do a little digging into how to get a random integer in bash.</p>

<p>Let's take a look at <a href="https://github.com/matsieftw/matsie-tools/tree/master/git-reminder">the script</a> and then go in some greater detail:</p>

<pre><code>#!/bin/bash
# This script displays a message
# about good git etiquette to the user.

array=("Commit your changes early and often and before sending to QA."  
    "Good Housekeeping: Prune old branches. We got the commits!" 
    "A new branch does not mean lost work." 
    "Don't leave uncommitted or untashed changes on a repo.")

n=$((RANDOM%3+0))

echo "${array[n]}" | sudo /usr/bin/wall -n  
</code></pre>

<p>The script is fairly simple. It takes an array of four different messages, then determines a random integer between 0 &amp; 3. Then it echoes out whatever message is at the random number index of the array and passes that the wall command.</p>

<p>A few key notes:</p>

<ul>
<li>When using a lot of builtin commands in a shell script, it's important to give the full path of the command (i.e., <code>/usr/bin/wall</code>), rather than just the command. In general, it's just better to use full paths in scripts.</li>
<li>The wall command can only be sent "anonymously" as root. The <code>-n</code> flag indicates "no banner," so only the message itself without any other information is broadcast.</li>
</ul>

<p>I set up a cronjob that runs as root on Tuesdays and Thursdays and executes gitreminder.sh and voila! Everyone gets a message!</p>]]></content:encoded></item><item><title><![CDATA[Clearing Your Shell with Only the Return Key]]></title><description><![CDATA[A simple shell script to clear your screen using the return key.]]></description><link>http://matsie.net/clearing-your-shell-with-only-the-return-key/</link><guid isPermaLink="false">3ec0cb7b-f24c-44ac-9af9-cc57a5f8b895</guid><category><![CDATA[shell]]></category><category><![CDATA[zsh]]></category><dc:creator><![CDATA[Mattie Kenny]]></dc:creator><pubDate>Sat, 05 Nov 2016 16:10:20 GMT</pubDate><content:encoded><![CDATA[<p>I am a die hard command line user. I am not highly opinionated on whether or not everyone else should be working solely out of the command line, but my own personal idiosyncrasies kind of demand it -- I <em>hate</em> having multiple windows open. This means, I use a lot of tabs and splits and my preferred text editor is Vim. I work from my terminal and I love it because it provides me with both simplicity (one window) and complexity (text editor, shell, <a href="https://github.com/michael-lazar/rtv">reddit browser</a>).</p>

<h2 id="somanytypos">So Many Typos</h2>

<p>That being said, I end up entering a lot of commands into my terminal and now I've got a cluttered screen where all my relevant text is at the bottom. I've gotten into the habit of typing <code>clear</code> <em>a lot</em>. But this leaves room for typos...sometimes so many typos. Ugh. SO. MANY. TYPOS.</p>

<p><img src="http://matsie.net/content/images/2016/11/clearScreenTypo.png" alt="Clear Shell Typo - MatsieFTW!"></p>

<p>My deskmate is a 'return key' guy. He just presses return a bunch until he's got some whitespace on the screen and continues running commands. This got me thinking on how to combine these two methods to make one Super Method<sup>TM</sup>.</p>

<h2 id="enterthereturnkeyclearshellscript">Enter the Return Key Clear Shell Script</h2>

<p>So now I looked for a solution that cleared my shell whenever I pressed the return key twice. And behold, <a href="https://github.com/matsieftw/matsie-tools/tree/master/return-key-clear">return_key_clear.sh</a>:  </p>

<pre><code>declare empty_counter=0

precmd_hook() {  
    if [[ $empty_count -gt 1 ]]; then
        /usr/bin/clear
        let empty_count=0
    fi

    let empty_count=$empty_count+1
}

preexec_hook() {  
    let empty_count=0
}

autoload -U add-zsh-hook

add-zsh-hook precmd precmd_hook  
add-zsh-hook preexec preexec_hook  
</code></pre>

<p><small>**This shell script works reliably and predictably for <code>zsh</code> on both macOS and Ubuntu Linux.</small></p>

<p><small><strong>Update 2016-11-16 - The original version of this post used <code>MacOS</code> instead <code>macOS</code>. For this, I am eternally regretful of the internet points I lost. As we all know, they can never be regained.</strong></small></p>]]></content:encoded></item><item><title><![CDATA[How I Learned to Love tmux]]></title><description><![CDATA[Why use tmux instead of iTerm2's split panes?]]></description><link>http://matsie.net/how-i-learned-to-love-tmux/</link><guid isPermaLink="false">1f291c4b-1650-4254-af7d-62a94dc31a1c</guid><category><![CDATA[command line]]></category><category><![CDATA[tmux]]></category><dc:creator><![CDATA[Mattie Kenny]]></dc:creator><pubDate>Sun, 29 May 2016 20:48:13 GMT</pubDate><content:encoded><![CDATA[<p>My coworker, <a href="http://github.com/wheresmyjetpack">Paul</a> and I were discussing the virtues of <a href="https://github.com/tmux/tmux">tmux</a> a few days ago and both of us were at a loss at to why it was useful. tmux brands itself as a "terminal multiplexer". It gives you the ability to have multiple terminals instances opened at once without having to use multiple windows. </p>

<p>This seems useful at first, but both Paul and I use <a href="https://www.iterm2.com/">iTerm2</a> as our terminal app and iTerm2 already provides tabbed windows and split panes. This weekend provided me with the motivation to learn tmux more fully and try it out in my workflow -- and boy am I enjoying it.</p>

<p>What's amazing about my change of heart is that I'm using tmux only in the most basic implementation right now. I use it to background apps and to afford myself more screen real estate on my cramped Macbook Air screen.</p>

<p>I now have a tmux session that handles my <code>top</code> and <code>rails server</code> screens and I don't have to worry about if my ssh connection breaks or about losing a little bit of screen real estate. I even keep a split in the session for man pages I'm looking at.</p>

<p>So why use it over iTerm2's splits and tabs? iTerm won't keep your session going. If you're pulling a particularly large repo or installing something big, iTerm could lose that connection and your session is over, as is that download. With tmux, you're not just getting a way to manage your multiple windows -- <strong>you're gaining a way to manage multiple sessions</strong>. And that makes a WORLD of difference once you incorporate it into your workflow.</p>]]></content:encoded></item><item><title><![CDATA[Creating a Git Repository Remotely]]></title><description><![CDATA[Quick command for creating a github repo remotely via the command line.]]></description><link>http://matsie.net/creating-a-git-repository-remotely/</link><guid isPermaLink="false">7ea9b39e-c8c0-45e3-99c2-0b0fa0db625c</guid><category><![CDATA[git]]></category><category><![CDATA[command line]]></category><category><![CDATA[curl]]></category><category><![CDATA[github]]></category><category><![CDATA[version control]]></category><dc:creator><![CDATA[Mattie Kenny]]></dc:creator><pubDate>Fri, 27 May 2016 01:39:36 GMT</pubDate><content:encoded><![CDATA[<p>I have been banging my head on my keyboard for quite some time trying to figure out why using <code>git push origin master</code> has never seemed to work for me when trying to push the few local repos I have to github via the command line. I knew I was missing something essential about the process, but was struggling to put my finger on it.</p>

<p>Finally, I've found out there is no established git command that creates the repo when you attempt to push a local repo up. <strong>The repo has to have already been created.</strong> This posed a bit of an issue for me because I try to do as much of my work as possible via the command line.</p>

<p>Turns out, <code>curl</code> is perfect for just such a situation.</p>

<p><code>curl -u 'USERNAME' https://api.github.com/user/repos -d '{"name":"REPO_NAME"}'</code></p>

<p>This command will create a new repo in your profile using the github API.</p>]]></content:encoded></item><item><title><![CDATA[Collision Conf 2016 - Day 2]]></title><description><![CDATA[The second day of the conference was even better than the first!]]></description><link>http://matsie.net/collision-conf-2016-day-2/</link><guid isPermaLink="false">4ce9bdde-c44e-4a72-a1b6-754463916313</guid><category><![CDATA[collision-conf]]></category><category><![CDATA[networking]]></category><dc:creator><![CDATA[Mattie Kenny]]></dc:creator><pubDate>Sun, 01 May 2016 16:11:22 GMT</pubDate><media:content url="http://matsie.net/content/images/madeinALX.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://matsie.net/content/images/madeinALX.jpg" alt="Collision Conf 2016 - Day 2"><p>This recap is coming several days late, but day two of the conference was amazing! The second day's talks were much more relevant to my work as a developer and I remained incredibly engaged the whole time. I basically lived at the Builders Stage! So many great talks that were relevant to my work as a developer.</p>

<p>My networking skills are definitely in need of some work, though. I would get nervous and scramble for things to say or ask instead of letting the conversation just flow. The most embarrassing moment was when after I shook hands with someone and made to leave, I sidehugged the man for absolutely no reason at all. I was mortified and walk ran away as fast as I could! Aside from that horror story of a moment, my nervousness while networking didn't seem to be too detrimental. </p>

<p>Some highlights from Day 2:</p>

<ol>
<li><p><a href="https://twitter.com/marcusustwo">Marcus Woxneryd</a> of <a href="https://ustwo.com">ustwo</a>'s talk about the real human value of employees and company culture was amazing and quite uplifting. Watch a recorded version of this talk from Web Summit <a href="https://www.youtube.com/watch?v=DhzNTNlQS34">here</a>.</p></li>
<li><p>The panel on Open Source software was really amazing. And the tag question at the very end about how to create a culture in open source that is much more open to women and other underrepresented minorities was just as valuable as the rest of the talk. It's good to know IBM and jQuery are actively thinking about these communities and how the embedded culture in technology can be prohibitive of truly open participation.</p></li>
<li><p><a href="https://twitter.com/bryanl">Bryan Liles</a>' talk about continuous app deployment and the common mistakes companies &mdash; especially start ups &mdash; make while trying to push their updates was incredibly useful for me.</p></li>
<li><p><a href="https://www.silentcircle.com/our-story/">Mike Janke of Silent Circle</a> gave a great talk about cryptography and privacy in the modern era and how government influence is constantly butting up against user privacy rights.</p></li>
</ol>

<p>Honestly, the whole second day was a real home run. I'm incredibly glad that I was able to attend two days of <a href="https://collisionconf.com">Collision Conference</a> and can't wait to start utilizing what I learned (and improving my networking skills).</p>]]></content:encoded></item><item><title><![CDATA[Collision Conf 2016 - Day 1]]></title><description><![CDATA[A few highlights from my first day at Collision Conf.]]></description><link>http://matsie.net/collision-conf-2016-day-1/</link><guid isPermaLink="false">828d52aa-17c1-48f5-a80e-68de8aa224cd</guid><category><![CDATA[collision-conf]]></category><category><![CDATA[networking]]></category><dc:creator><![CDATA[Mattie Kenny]]></dc:creator><pubDate>Wed, 27 Apr 2016 01:39:06 GMT</pubDate><media:content url="http://matsie.net/content/images/2016/04/collisionconf.png" medium="image"/><content:encoded><![CDATA[<img src="http://matsie.net/content/images/2016/04/collisionconf.png" alt="Collision Conf 2016 - Day 1"><p>I have been eagerly anticipating today since I got my <a href="http://collisionconf.com">Collision</a> ticket back in October of last year. I have never been to an industry conference and the naive nerd inside of me was squeeing in utter delight that I finally get to go to a conference. My coworker, <a href="https://github.com/wheresmyjetpack">Paul</a>, and I took a whole hour to pore over the seminar descriptions and set up our joint schedules.</p>

<p>Day one of the conference definitely did not disappoint. We got plenty of schwag and saw quite a few really fantastic talks.</p>

<p>Some highlights from today...</p>

<ol>
<li><p>Schwag! Got some pretty neat socks from <a href="http://gitlab.com">GitLab</a> and a cute desk shark and tote from &hearts;<a href="http://digitalocean.com">Digital Ocean</a>&hearts;. We were also able to get a book on learning the <a href="https://www.wolfram.com/language/">Wolfram Programming Language</a>, which was new to both Paul and I.</p></li>
<li><p><a href="https://mikko.hypponen.com/">Mikko Hypponen</a>'s talk about web security and the reasons cybercrime occurs was incredibly interesting and thought provoking.</p></li>
<li><p><a href="https://www.twilio.com/company/management">Jeff Lawson</a>'s talk about making mistakes along your career path and finding the work that you have conviction in was inspiring to me. He was an animated speaker and was not so subtly nudging me and everyone else in the audience in the right direction for our careers.</p></li>
</ol>

<p>You can follow my live tweets of the conference <a href="http://twitter.com/matsie">here</a>.</p>]]></content:encoded></item><item><title><![CDATA[Setting Up Ghost - Part 1]]></title><description><![CDATA[My first attempt at setting up the Ember based Ghost CMS did not go as well as planned.]]></description><link>http://matsie.net/setting-up-ghost-part-1/</link><guid isPermaLink="false">b4026099-7e04-4ade-8570-7467d0a65616</guid><category><![CDATA[ghost]]></category><category><![CDATA[wordpress]]></category><category><![CDATA[failure]]></category><category><![CDATA[node]]></category><category><![CDATA[ember]]></category><dc:creator><![CDATA[Mattie Kenny]]></dc:creator><pubDate>Tue, 26 Apr 2016 14:25:51 GMT</pubDate><content:encoded><![CDATA[<p>My first run-through of setting up <a href="http://ghost.io">Ghost</a> went off largely without a hitch. I used <a href="http://digitalocean.com">Digital Ocean's</a> 1-click Ghost install. Which made the whole set up seem fairly breezy. Here are the steps I took that led me into the weeds.</p>

<ol>
<li><p><strong>Create a Ghost Droplet.</strong> - This was really simple! I selected my droplet image from Digital Ocean's selection of 1-Click Apps and voila! I now had a working instance of Ghost v. 0.7.9 running on Ubuntu v. 14.04.</p></li>
<li><p><strong>Implement Site Theme.</strong> - While the normal flow of the installation is to set up your domain name, I wasn't ready to switch my current website to Ghost until I had the new one all set up and ready to push live. So I found a great Ghost theme called <a href="https://github.com/dcefram/stupendous">Stupendous</a> and started tinkering. This was a pretty wild ride for me since I am new to Ember, so I fumbled through changing the theme a bit while I was learning. Here is where I had my first takeaway -- <strong>don't forget to restart Ghost after making changes to theme files.</strong></p></li>
<li><p><strong>Import Wordpress Posts.</strong> - I used the <a href="https://wordpress.org/plugins/ghost/">Ghost Plugin for Wordpress</a> to export all my posts into a JSON file. Then imported my posts (and pages) into Ghost via the Labs admin section.</p></li>
<li><p><strong>Set Up Domain Name on the Server.</strong> - First, change your nginx config (<code>/etc/nginx/sites-available/ghost</code>) to match your domain. Next, edit your Ghost config file (<code>/var/www/ghost/config.js</code>) so that the settings for production mode match your domain hostname. <strong>Don't forget to use http!</strong></p>

<p>Here's where I found myself in the weeds. Somewhere along the way of changing all the necessary settings in my Ghost and nginx config files, I really messed up. I got myself into a real pickle where no matter what I did, I had a <em>502 Bad Gateway</em> error message when trying to resolve my website. Which I didn't figure out until I...</p></li>
<li><p><strong>Set Up Domain Name on Digital Ocean &amp; Your Registrar.</strong> - I always wince when I change any of my DNS settings and it was a well earned wince because after I changed my nameservers on my registrar and then connected my droplet to a domain within Digital Ocean's Networking settings, I anxiously awaited the cache to clear and find my worst nightmare. My site was down.</p>

<p>After about two hours of trying to track down what the error in my log meant, <code>Unable to find node index</code>, I finally decided to scrap the droplet all together and start fresh.</p></li>
</ol>

<p>Second chances are plentiful when your willing to let yourself fail. More on my second attempt at setting up Ghost in Part 2 of this series.</p>]]></content:encoded></item><item><title><![CDATA[Switching to Ghost Was a Bit More Difficult Than I Thought...]]></title><description><![CDATA[Switching from Wordpress to Ghost CMS posed some issues, but I'm glad to have struggled through it.]]></description><link>http://matsie.net/switching-to-ghost-was-a-bit-more-difficult-than-i-thought/</link><guid isPermaLink="false">e4430004-b9ad-4f6b-a2f6-00c8799e8122</guid><dc:creator><![CDATA[Mattie Kenny]]></dc:creator><pubDate>Tue, 26 Apr 2016 01:04:00 GMT</pubDate><content:encoded><![CDATA[<p>It took me long enough and I fumbled through the set up, but finally, my blog is fully set up using <a href="http://ghost.io">Ghost</a>, <a href="http://nginx.com">nginx</a> and <a href="http://digitalocean.com">Digital Ocean</a>.</p>

<p>I hit quite a few snags along the way, mostly due to being very new to node, ember and nginx. In my experience as a web developer, I've dealt mainly with websites built on Apache servers using PHP. All of the past iterations of my own website were built using Wordpress or Typepad. So switching to Ghost was a real learning experience.</p>

<p>But here I am with new website banner, new CMS and a new sense of accomplishment. Yahoo!</p>]]></content:encoded></item></channel></rss>