Quick bugfixing with git bisect

git bisect is an indispensable tool for fixing bugs. It can be an extremely efficient way to identify a change that broke your code and therefore find a fix for your problem.

git bisect does its magic with a simple binary search. You start by specifying a commit where the code is broken (with git bisect bad) and a commit where the code works (git bisect good). git bisect will automatically check out a commit between those two commits. You test the code again, mark it as good or bad, and bisect will check out another commit. Eventually, you’ll narrow down to the commit when the code broke, and then you can fix the bug yourself (or identify who else broke the code, and get them to fix it).

My favorite way to run git bisect is with the run parameter. If you have a script ./script.sh that can test if the code is good or bad, and it exits with 0 for good and anything else for bad, then you can use git bisect run ./script.sh – it’ll automatically use the script’s output to mark commits as good or bad, and will quickly identify the breaking change.

There are a lot of finer points to using git bisect, as detailed in the official documentation, and I’ve glossed over some details, but I’ve never needed more than this basic usage. I hope it’ll make your coding life happier. Enjoy!

HTML validation with vnu

vnu is an HTML validation checker. It’s extremely easy to use and integrates well with all your other command-line tools. I installed it with brew install vnu – it’s also available through npm and pip.

I like to use it in conjunction with cURL, so I can quickly check the validation status of whatever I’m working on:

curl https://example.com | vnu -

I prefer the JSON output format, because I can pipe it into jq as follows:


// curl ENDPOINT | vnu --format json - 2>&1 | jq
{
  "messages": [
    {
      "type": "error",
      "lastLine": 3,
      "firstLine": 1,
      "lastColumn": 70,
      "firstColumn": 1,
      "message": "Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.",
      "extract": "  \n\n        <h2 class=\"popup-heading\" title=\"Blah Blah\"> Embed",
      "hiliteStart": 0,
      "hiliteLength": 74
    },
    {
      "type": "error",
      "lastLine": 3,
      "firstLine": 1,
      "lastColumn": 70,
      "firstColumn": 1,
      "message": "Element “head” is missing a required instance of child element “title”.",
      "extract": "  \n\n        <h2 class=\"popup-heading\" title=\"Blah Blah\"> Embed",
      "hiliteStart": 0,
      "hiliteLength": 74
    },
    {
      "type": "error",
      "lastLine": 3,
      "lastColumn": 1583,
      "firstColumn": 1559,
      "message": "Element “div” not allowed as child of element “label” in this context. (Suppressing further errors from this subtree.)",
      "extract": "n\"><label><div class=\"input-title\"> Width",
      "hiliteStart": 10,
      "hiliteLength": 25
    },

If your HTML is returned from a JSON endpoint, use another jq call to extract it from the JSON:

CURL COMMAND | jq -r .data.html | vnu --format json - 2>&1 | jq .messages

By default, vnu expects full HTML pages, and as such will complain if it’s asked to validate HTML fragments. If you’re validating HTML fragments like in the above examples, you’ll probably see messages like Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>” or Element “head” is missing a required instance of child element “title”. Don’t worry if this happens – these are only problems if you’re trying to validate a full page.

Combined with your other tools, vnu will help you fix your HTML quickly and efficiently. Enjoy!

Efficient endpoint testing with curl, jq and pup

Sometimes I need to work on web pages whose HTML is dynamically loaded from a JSON endpoint. There’s no better way to verify the module’s behaviour than manual testing, but much of the time, I just need to ensure the correct HTML is rendered. It’s slow to click around the site, so I use curl, but since the HTML is inside JSON, it isn’t feasible to interpret its output.

Fortunately, it’s easy to break this HTML out of its JSON cage. I use two excellent tools, jq and pup, for this kind of work.

Say the JSON endpoint’s output is structured as follows:


{ "data": {  "html" : "<div><h2>whatever</h2><span>hey</span></div>" } }

First, I go to the page I’m working on and open Chrome’s network tab. I manually perform the task that hits the JSON endpoint of interest, I right-click on the relevant call in the network tab, and I select “Copy as curl“, which copies all the relevant cookies and headers necessary to replicate the request.

The curl command will be piped into jq and pup as follows:


curl ((ARGS GO HERE)) | jq -r .data.html | pup -p

The jq call extracts the HTML from the JSON and the -r flag removes the outer quotation marks. The pup call formats the HTML and the -p unescapes the output (otherwise it’ll be full of entities).

The output will look like:


<html>
 <head>
 </head>
 <body>
  <div>
   <h2>
    whatever
   </h2>
   <span>
    hey
   </span>
  </div>
 </body>
</html>

You can use CSS selectors to filter the pup call as follows:


$ cat output.html | pup h2

<h2>
 whatever
</h2>

If you want to take your productivity up another level, you can use this combination with watchman-make as described in this post: watchman-make: focus on your code.

jq and pup are very powerful tools, and even though this example is probably the simplest thing you can do with them it can really accelerate your endpoint testing. You can install both tools through Homebrew. Happy coding!