Blog

Remove Passwords From Git History

Every once in a while you’ll check in a key or password into a git repository by mistake. Not to worry, there’s a great utility that can erase the values from history for you. You can delete the file or update the text from the current HEAD but the value still exists in your branch history so you need to go further to remove the value.

Luckily there’s the BFG Repo-Cleaner utility tool that goes through your git history and updates all references of the private value and replaces it with **Removed**.

Here’s how to use the BFG Repo-Cleaner to remove passwords from your git history. The BFG Repo-Cleaner is a Java file that can be saved to your local machine and run against your cloned git repo.

  1. Start by downloading the BFG Repo-Cleaner .jar file to your local machine. I saved mine to a folder called bfg on my D: drive – D:\code\bfg.
  2. Create a passwords.txt file that lists the passwords/keys you want to remove from your git repository and save to the same folder as the BFG Cleaner. The passwords.txt file is just a list of different passwords/keys that you want to remove from the repository.
    password1
    password2
    keyvalue123
  3. Clone your repository using the –mirror flag and make a full backup of the repo just in case something breaks.
    $ git clone --mirror https://github.com/clintmcmahon/delete-passwords.git
  4. Open command prompt and run the following command
    $ java -jar d:\code\bfg\bfg-1.13.0.jar --replace-text d:\code\bfg\passwords.txt d:\code\delete-passwords.git
  5. Move into the cloned git folder and run the following command
    $ cd delete-passwords.git
    $ git reflog expire --expire=now --all && git gc --prune=now --aggressive
  6. And finally push your changes back to the remote repository
    $ git push

That’s it. If you go into your repository now you will see that all references to your values from the passwords.txt file will now be replaced with **Removed**. This is just the tip of the utilities ability, there are more examples and other documentation on at the BFG Repo-Cleaner project Github page.

Sort Shopify Liquid Collection By A Nested Property

Suppose you want to sort or filter a Shopify collection by a sub/nested property. Well, this is an example of how you’d sort a Shopify collection by a nested property, specifically how to sort by a setting property of a logo list block.

Shopify tab example
Shopify filter tab example

I created a Shopify tab snippet to filter and sort the above list of logo blocks by a property within a single logo/block. The code below gets all the blocks in the logo list section, maps over the settings and returns the items where the logo_list property equals “brewery” then sorts the results by title. If you don’t need to return a specific sub-set of data and only want to sort by the property then simply remove | where: “logo_category”, “brewery” from the assign block.

{% assign breweries = section.blocks | map: 'settings' | where: "logo_category", "brewery" | sort: "title" %}

{% for block in breweries %}
    {%- assign logo = block.logo -%}
    {%- assign url = block.url -%}
        <div class="module-inline-item dynamic-logo-list-item" {{ block.shopify_attributes }}>
            {% if url != blank %}
              <a href="{{ url }}" target="_blank">
            {% endif %}

            {% if block.logo != blank %}
              {%
                include 'rimg',
                img: logo,
                size: '330x280',
                lazy: true
              %}
            {% else %}
              {{ 'logo' | placeholder_svg_tag: 'placeholder-svg' }}
            {% endif %}

            {% if url != blank %}
                </a>
            {% endif %}
          </div>
      {% endfor %}

And that’s all you need to do to filter a Shopify collection by a nested property. I will post the code for the full tab snippet in another post.

How To Create A Reusable Select List In React

This tutorial is on how to create a reusable dropdown list component in React. I broke the functionality down into two components — the actual select dropdown list component and the calling parent/calling component.

The parent component will be App.js and a component called DynamicSelect.js will handle the select list functionality. The entire source code project is on GitHub.

Let’s start with the DynamicSelect component. The DynamicSelect component is the component which will render an array of Seinfeld characters into select list and pass back the selected value via the props object to the parent component. When the onChange event is fired for the select list the event is passed into the handleChange function. This function will pass the selected value back to the parent (App.js) via the props object.

DynamicSelect.js Component

import React, {Component} from 'react';

class DynamicSelect extends Component{
    constructor(props){
        super(props)
    }

    //On the change event for the select box pass the selected value back to the parent
    handleChange = (event) =>
    {
        let selectedValue = event.target.value;
        this.props.onSelectChange(selectedValue);
    }

    render(){
        let arrayOfData = this.props.arrayOfData;
        let options = arrayOfData.map((data) =>
                <option 
                    key={data.id}
                    value={data.id}
                >
                    {data.name}
                </option>
            );

            return (
            <select name="customSearch" className="custom-search-select" onChange={this.handleChange}>
                <option>Select Item</option>
                {options}
           </select>
        )
    }
}

export default DynamicSelect;

App.js Component

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import DynamicSelect from './DynamicSelect';

const arrayOfData = [
  {
    id: '1 - Jerry',
    name: 'Jerry'    
  },
  {
    id: '2 - Elaine',
    name: 'Elaine'    
  },
  {
    id: '3 - Kramer',
    name: 'Kramer'    
  },
  {
    id: '4 - George',
    name: 'George'    
  },
];

class App extends Component {
  constructor(props){
    super(props)
    this.state={
      selectedValue: 'Nothing selected'
    }
  }

  handleSelectChange = (selectedValue) =>{
    this.setState({
      selectedValue: selectedValue
    });
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Dynamic Select Dropdown List</h1>
        </header>
        <p className="App-intro">
          <DynamicSelect arrayOfData={arrayOfData} onSelectChange={this.handleSelectChange} /> <br /><br />
          <div>
            Selected value: {this.state.selectedValue}
          </div>
        </p>
      </div>
    );
  }
}

export default App;

And that’s it. The repository for this code is available on GitHub in this class fashion. This functionatliy can be easily replicated via functional components with hooks as well.

Why I Write Unit Tests

In computer programming, unit testing is a software testing method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures, are tested to determine whether they are fit for use — wikipedia

Unit tests, who needs em? We all do. There are a lot of resources online that will tell you why unit testing is important or why writing unit tests before building implementations is a good idea. But I’m here to tell you how unit tests can save you a massive production headache.

A while back, a coworker pushed code to production that consumed and parsed large .csv files uploaded by users. The code looped through the file then parsed and mapped each record to the associated record in the model. The model contained a few bool fields that were populated by executing the C# Boolean.TryParse method against the text field to convert the string from the file to bool. If the TryParse method returned false then the value in the csv file must have been falsy, and vice versa for true. The record was applied to the model and saved to the database.

As it turned out, our code didn’t work as expected which caused a major problem. For bool fields users would upload either a 1 or 0. 1 being true and 0 being false. Because the source was a csv file all values were imported as strings. Therefore, before applying the values to our model, we must convert the string representation to the appropriate type within the model.

Here’s an example of the code, the Parse method below takes a string argument named parsable, does a Boolean.TryParse against parsable and returns the newly converted value.

	
	public static Main(){
	    var trueFalse = Parse("1");
	}
	
	public bool Parse(string parsable)
	{
		 bool flag;
		 bool result = Boolean.TryParse(parsable, out flag);
         return flag;
	}

From looking at the method and without knowing how C# Boolean.TryParse converts the string argument “1” to bool you’d think that this method returns true, not false. But in reality the above method returns false. Even though 1 generally equals true in most contexts, if passed in as a string the result is false, not true.

If we would have had proper unit tests set up we would have written a unit test that looks something like this:

[TestMethod]
public void Parse_BooleanTryParseString__ReturnsFalse()
{
    string stringToParse = "1";
    bool expected = true;
    bool actual = Parse(stringToParse);

    Assert.AreEqual(expected, actual);
}

The above unit test would have failed and we’d have found the problem, fixed it and been on our way. Unfortunately for us, we didn’t have a unit test for the above Parse method and QA didn’t catch the issue during their testing. The code eventually made its way to production, users start uploading files against the new code and yadda, yadda, yadda…we end up with a lot false values that should be true.

I've made a huge mistake

The good news is we were able to recover the lost data. But the recovery process took a few days and a lot of manual work which set us back on our timeline, not to mention created a garbage truck full of unwanted stress while we scrambled to recover the data and explain to our stakeholders that we’d made a huge mistake.

The takeaway my team and I had from this experience is how valuable a unit test can be. Unit tests are not just a key part of the testing process, but they’ve proven to be invaluable in making sure the code you write is actually doing what you think it’s doing.

How To Make Cold Brew Coffee At Home

Here’s an easy guide on how to make cold brew coffee at home. Makin cold brew coffee at home is pretty simple – just grind your beans then soak them in big jars on the counter for about 16 hours.

I follow the Stumptown method of 12:64, that’s 12 ounces of freshly ground coffee to 64 ounces of water. This will create a strong concentrate of coffee, so I usually cut the finished product with 1:1 amount of water. You can soak your coffee grounds longer if you want to some really strong coffee concentrate.

Step 1.

Get some coffee, preferably a 12 oz bag of whole coffee beans. I like to use my local Minneapolis roaster, Spyhouse Coffee. You can use already ground if you like as well.

Step 2:

Grind those beans on the coarsest setting possible. Or dump out your bag of already ground beans into a bowl if that’s the route you’re taking.

Step 3:

Fill a 64 ounce jar/pitcher/container of your choosing with filtered water. Dump your coffee into the jar.

Step 4:

Stir the coffee and water together.

Step 5:

Seal the jar or cover the jar with a towel and let it sit out on the counter for the next 16 or so hours.

Step 6:

After 16 hours of room temperature “chilling” the coffee is done. Grab a mesh strainer or other type of sieve, hold the strainer over another container/jar and pour the coffee through the strainer letting the liquid pour through into the second jar/container. This will catch the big chunks of coffee grounds.

Step 7:

Now we’re on to the final step. Rinse the junk out of the first jar/container and place a new coffee filter over it. Pour the first filtered coffee through the coffee filter into the original jar/container. This will filter out the rest of the sludge from the coffee.

And that’s it. Store the finished product in the fridge and enjoy over ice. I like to cut the final result with a 1:1 ratio of water to coffee to dull it down a little bit. Pour the final result over ice and enjoy the summer. A splash of milk of any variety is a nice touch as well.

Mapbox GL JS Access Denied In IE 11

Mapbox gives you the ability to load custom icons for different points in your maps. When I tried to load a custom icon to a Mapbox map I got the error “SCRIPT5: Access is denied.” in IE 11 – Firefox and Chrome loaded the icon fine.  My code was loading an imported image as an object inside a React component like this:

import centerImage from "./images/centerImage.png";

map.on('load', () => {
    map.loadImage(centerImage, (error, image) => {
        if (error) {
            return;
        }
        map.addImage('centerIcon', image);
    });
    ...
});

Updating the image URL parameter to a string URL fixed the problem. I didn’t dig too much into the issue to figure out why this was happening, but passing a valid image string URL was enough to get passed this issue.

map.on('load', () => {
    map.loadImage('/hospital.png', (error, image) => {
        if (error) {
            return;
        }
        map.addImage('centerIcon', image);
    });
    ...
});

The Best Internet Radio Stations To Stream

I listen to a lot of music while coding, reading and walking my dog. Over the years I’ve built up a solid go-to list of radio stations across the world to listen to when I want to put something on and not worry about choosing a specific album or playlist. These are the best Internet ratio stations I’ve found over the years to stream that keep me going throughout the day and night. These stations are actually more than just Internet radio actually, most of them are broadcast from a city over the FM dial. But since none of them are in my area I’ve come to rely on them strictly via the web.

They’re also commercial free radio so there’s no need to worry about interruptions from local car dealerships. They all rely on people like you and me to keep the music going, so drop them a dime or two if you find one that you like.

KEXP – Seattle

Indie/Variety
Stream URL
KEXP’s curatorial staff of 45 DJs, who are widely recognized as experts in their field, present the newest emerging popular artists alongside established bands. KEXP’s programming features both variety and specialty shows that brings you the emerging sounds and long-time favorites from the Pacific Northwest, the country, and throughout the world. – kexp.org

WWOZ- New Orleans

WWOZ 90.7 FM is the New Orleans Jazz and Heritage Station, a community radio station currently operating out of the French Quarter in New Orleans. Our governance board is appointed by the New Orleans Jazz & Heritage Festival and Foundation.
WWOZ’s mission is to be the worldwide voice, archive, and flag-bearer of New Orleans culture and musical heritage. – wwoz.org

WQXR – New York

Classical
Stream URL
WQXR is New York City’s only classical music radio station, broadcasting live on 105.9 FM. We share our audience’s passion for music by playing the most outstanding pieces on air, online and through our app. – wqxr.org

KCRW Eclectic 24- California

Indie/Variety
Stream URL
KCRW’s all-music channel blending the collected talents and tastes of all KCRW’s DJs into a single voice streaming 24 hours a day. – kcrw.org

After Hours FM – Internet

Techno/Trance
Stream URL

AH.FM is a online radio that plays Trance and Progressive mixes produced exclusively for AH.FM by the hottest DJs from around the world. Afterhours’ main purpose is to provide the Electronic Dance Music community the best and richest quality music, all for FREE. We don’t believe in charging listeners money to listen to music, we believe that if a listener likes what they hear and wishes to support Afterhours, they will simply donate or purchase something in the store to help. – ah.fm

React + Mapbox GeoJSON Example

Here’s an example of how to create a Mapbox map in React using a GeoJSON data set. When I started building my first React Mapbox map I built them around some of the other pre-built components out there like ReactMapboxGL or react-map-gl. Both of these wrappers are great but eventually figured out I was better able to control all the Mapbox features on my own by targeting the Mapbox GL JS libary directly vs using a another component.

This example uses React hooks but could easily be updated for a class component if that is what you are working with. Below is one component called Districts that loads Minnesota’s eight congressional districts from a separate geojson file. After loading the districts they are given a unique fill-color and added as a layer.

You can view the entire React Mapbox GeoJSON example project in the GitHub repository or you can view a live example at clintmcmahon.github.io/react-mapbox-example

Districts.js React Component

import React, { useState, useEffect, useRef } from "react";
import mnDistricts from "./data/mn/mn-districts.geojson";
import ReactDOM from 'react-dom';
import mapboxgl from 'mapbox-gl';

function Districts(props) {
    mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_KEY;
    const mapContainer = useRef(null);
    const [long, setLong] = useState(-94.503809);
    const [lat, setLat] = useState(46.443226);
    const [zoom, setZoom] = useState(4.5);
    const [hoveredDistrict, _setHoveredDistrict] = useState(null);
    const hoveredDistrictRef = useRef(hoveredDistrict);

    const setHoveredDistrict = data => {
        hoveredDistrictRef.current = data;
        _setHoveredDistrict(data);
    };

    useEffect(() => {

        let map = new mapboxgl.Map({
            container: mapContainer.current,
            style: "mapbox://styles/mapbox/light-v10",
            center: [long, lat],
            zoom: zoom
        });


            // Add zoom and rotation controls to the map.
            map.addControl(new mapboxgl.NavigationControl());
        map.once("load", function () {

            map.addSource('district-source', {
                'type': 'geojson',
                'data': mnDistricts
            });

            map.addLayer({
                'id': 'district-layer',
                'type': 'fill',
                'source': 'district-source',
                'layout': {},
                'paint': {
                    'fill-color': [
                        'match',
                        ['get', 'CD116FP'],
                        '01',
                        '#5AA5D7',
                        '02',
                        '#02735E',
                        '03',
                        '#00E0EF',
                        '04',
                        '#84D0D9',
                        '05',
                        '#202359',
                        '06',
                        '#CE7529',
                        '07',
                        '#00AE6C',
                        '08',
                        '#0056A3',
                        /* other */ '#ffffff'
                    ],
                    'fill-opacity': [
                        'case',
                        ['boolean', ['feature-state', 'hover'], false],
                        .8,
                        0.5
                    ]
                }
            });

            map.on('mousemove', 'district-layer', function (e) {
                if (e.features.length > 0) {
                    if (hoveredDistrictRef.current && hoveredDistrictRef.current > -1) {

                        map.setFeatureState(
                            { source: 'district-source', id: hoveredDistrictRef.current },
                            { hover: false }
                        );
                    }

                    let _hoveredDistrict = e.features[0].id;

                    map.setFeatureState(
                        { source: 'district-source', id: _hoveredDistrict },
                        { hover: true }
                    );

                    setHoveredDistrict(_hoveredDistrict);
                }

            });

            // When the mouse leaves the state-fill layer, update the feature state of the
            // previously hovered feature.
            map.on('mouseleave', 'district-layer', function () {
                if (hoveredDistrictRef.current) {
                    map.setFeatureState(
                        { source: 'district-source', id: hoveredDistrictRef.current },
                        { hover: false }
                    );
                }
                setHoveredDistrict(null);
            });

        });

    }, []);

    return (
        <div className="district-map-wrapper">
            <div id="districtDetailMap" className="map">
                <div style={{ height: "100%" }} ref={mapContainer}>

                </div>
            </div>
        </div>
    );
}

export default Districts;

Minnesota Congressional Districts GeoJSON

This geojson data set represents Minnesota’s eight congressional districts that I pulled from the US Census. Each feature has a property “CD116FP” that I’m using to set the fill-color of each district layer. The GeoJSON data is so big I didn’t include it in this blog post but you can download it from the Github repo.

You can view the source on Github.

That’s it. Happy coding!

Convert A Generic List To CSV File In C#

This is an example of how to convert a generic list to a dynamic downloadable .csv file using C#, the CsvHelper library and the FileStreamResult.

Download the repo and run the full project solution from Github

In this example a request comes into the controller, we create a generic list of type ListItem, created a memory stream and using the CsvWriter library  return a dynamic .csv file to the browser.

Step 1: Create the generic list class
This class will hold our generic list items. This can be whatever data you need.

public class ListItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Step 2: Create the MVC action to return the CSV file
This action method creates the generic list, writes it to memory with help from the CsvHelper library and returns the FileStreamResult back to the browser.

//Action Method for your controller
[HttpPost]
public ActionResult ConvertToCSV()
{
    //Create the test list
    var list = new List<ListItem>()
    {
        new ListItem(){Id = 1, Name = "Jerry"},
        new ListItem(){Id = 2, Name="George"},
        new ListItem(){Id = 3, Name="Kramer"},
        new ListItem(){Id = 4, Name = "Elaine"}
     };

    byte[] result;
    using (var memoryStream = new MemoryStream())
    {
        using (var streamWriter = new StreamWriter(memoryStream))
        {
            using (var csvWriter = new CsvWriter(streamWriter))
            {
                csvWriter.WriteRecords(list);
                streamWriter.Flush();
                result = memoryStream.ToArray();
            }
         }
     }

     return new FileStreamResult(new MemoryStream(result), "text/csv") { FileDownloadName = "filename.csv" };
}

h/t to this StackOverflow post

Download the repo and run the full project solution from Github