My little Maple passed away on Sunday.

I was out of town one night only to come back to see her in a strange state I have never seen. Usually when we come home she is so excited, this was not the case... She was all fluffy on the floor on the corner of her cage... We immediately took her out and seems as if she was in state of shock..

She eventually started chirping in a periodic pace for about 10 mins. A short time later, about 30 mins after coming home, she chirped a few more times before having a seizure and passing away in our hands..

I don't know what happened but she waited for us to come home..

This is truly killing me inside..



I'm currently working with a project that contains many small git repos. Many of them are small utility scripts written in Golang and Bash. Luckily, the internal git server has a very simple API I can use to fetch all the project names.

The payload looks similar to the following. I have taken out a lot of nonsense and wrapped it in a 'json' variable for this post.

json='
{
   "limit":25,
   "isLastPage":false,
   "values":[
      {
         "name":"project-name1",
         "links":{
            "clone":[
               {
                  "href":"ssh://git@someip:port/project1.git",
                  "name":"ssh"
               },
               {
                  "href":"http://someip:port/project1.git",
                  "name":"http"
               }
            ],
            "self":[
               {
                  "href":"http://someip/project1"
               }
            ]
         }
      },
      {
         "name":"project-name2",
         "links":{
            "clone":[
               {
                  "href":"ssh://git@someip:port/project2.git",
                  "name":"ssh"
               },
               {
                  "href":"http://someip:port/project2.git",
                  "name":"http"
               }
            ],
            "self":[
               {
                  "href":"http://someip/project2"
               }
            ]
         }
      }
   ]
}
'

The payload contains two projects with both an http and ssh link destinations. What I want to do is iterate over this once, grab all the information I need and clone the repositories.

I'm also going to use Bash, as it rocks. Unlike other languages, Bash doesn't have a built in JSON processor like Go. Parsing json isn't so easy with bash, however there is a processor we can install that makes it much easier.

jq is a "lightweight and flexible command-line JSON processor"

After reading the documentation, I came up with the following expression

repos=$(echo $json | jq '.values[] | select(.links.clone[].name == "ssh") | {repoName: .name, repoType: .links.clone[].name, repoHref: .links.clone[].href}')

In short, im trying to extract the array of 'values' and the array of 'clone', apply a filter and fetch only the 'ssh' links, a long with the name of the project... after that I want o assign the values from the clone and it's parent to the following variables

  • 'repoName' - values[].name
  • 'repoType' - values[].clone[].name
  • 'repoHref' - values[].clone[].href

This looks pretty straight forward, lets print out the results

echo $repos | jq

{
  "repoName": "project-name1",
  "repoType": "ssh",
  "repoHref": "ssh://git@someip:port/project1.git"
}
{
  "repoName": "project-name1",
  "repoType": "ssh",
  "repoHref": "http://someip:port/project1.git"
}
{
  "repoName": "project-name1",
  "repoType": "http",
  "repoHref": "ssh://git@someip:port/project1.git"
}
{
  "repoName": "project-name1",
  "repoType": "http",
  "repoHref": "http://someip:port/project1.git"
}
{
  "repoName": "project-name2",
  "repoType": "ssh",
  "repoHref": "ssh://git@someip:port/project2.git"
}
{
  "repoName": "project-name2",
  "repoType": "ssh",
  "repoHref": "http://someip:port/project2.git"
}
{
  "repoName": "project-name2",
  "repoType": "http",
  "repoHref": "ssh://git@someip:port/project2.git"
}
{
  "repoName": "project-name2",
  "repoType": "http",
  "repoHref": "http://someip:port/project2.git"
}

hmmm.... not what i'm expecting... if you look at the results, looks like it's multiplying the arrays and returning all combinations of the result... Actually getting some strange results where the repo type is http but the href is the ssh link. Maybe this isn't as easy as I thought.

After some tweaking and a few games of Tetris ( gameboy version on the switch ), I filtered till i got to the 'clone' array. This looks more promising however

 repos=$(echo $json | jq '.values[] | .links.clone[] | select(.name == "ssh") | {repoName: .parent.name, repoType: .name, repoHref: .href}')

 echo $repos | jq

{
  "repoName": null,
  "repoType": "ssh",
  "repoHref": "ssh://git@someip:port/project1.git"
}
{
  "repoName": null,
  "repoType": "ssh",
  "repoHref": "ssh://git@someip:port/project2.git"
}

Notice that the parent item 'repoName' is null. Obviously I am not capturing the parent element properly.

Looks like you are able to capture a variable, We will do this to keep a reference of the parent in our filtered result.

Lets skip to the working solution...

repos=$(echo $json | jq '.values[] | . as $value | .links.clone[] | select(.name == "ssh") | { repoName: $value.name, repoType: .name, repoHref: .href }')

echo $repos | jq

{
  "repoName": "project-name1",
  "repoType": "ssh",
  "repoHref": "ssh://git@someip:port/project1.git"
}
{
  "repoName": "project-name2",
  "repoType": "ssh",
  "repoHref": "ssh://git@someip:port/project2.git"
}

Perfect... I am able to capture all the data I need.

Here is what the expressions do block by block

  • . as $value: stores the current value in the array in a variable named $value for later use.

  • | .links.clone[]: extracts an array of clone links from the JSON data.

  • | select(.name == "ssh"): filters the array of clone links so that only the links with a name field equal to "ssh" are selected.

  • The rest just takes the data and puts it into our newly constructed json array

Now that I am able to clone all the repos, time to merge these into a mono repo and play more Tetris



It's that time .... again... Amazing how time fly's

Lets talk Goals....

Work goals

In one more week, starting on Jan. 9th, I will hand over the crown to the next group. Working exclusively with a billing systems, for the last six years, has its ups and downs, but it's time to move on.

I will start a new position doing more of a development/devops role, as opposed to only development, in mid-January. This will give me a bit more power and control when it comes to getting things done, I hope...

I will need to discuss with the team and come up with some standard tools we maybe using. The current company is dealing with a monolith however we have idea of pulling pieces out into external services where it make sense.

Ideally I should be getting more experience with

  • AWS and all the Cloud nonsense when it comes to the operations.
  • Kubernetes
  • GoLang
  • Ansible / Terriform
  • Jenkins ( have some experience using this many years ago )
  • Sevelte
  • Maybe spend some time learning more modern c++ 20 things... professionally however off the C++ ship many years now...

Anyway, def. excited about the move. The team is fantastic and we will learn a lot from each other.

Personal Goals

Currently im working with a small business brainstorming ideas about how they can run their mom and pop shop a bit better than their current process. I can't go into too much detail just yet since this has just started however it will be fun. I maybe integrating with a an awesome digital kiosks with a pretty kickass api. A lot of cool stuff will be in the works I hope.

When it comes to health, I manged ride over 1500 miles last year according to Komoot. Huge accomplishment. Going to try to keep up the pace. Getting into biking has been an amazing experience. So much I attempted to apply for a software job with specialized bikes, unfortunately they did go with another candidate due to my lack of experience being a platform engineer. Need to get up to speed on this modern development..

Fun Development stuff

Last year I spend a good chunk of time building things with Quarkus. It has been a pleasure working with this framework. Got really familiar with Apache Camel. Definitely will be applying this to the current job. Super excited to see what Quarkus 3 will entail.

Another Version 3 im really excited to see being worked on... SDL3

I will be following this project religiously. I fell from the gamedev scene but hopefully get back and active in the next year or so. In the mean time this will be my nightly reading. A lot of work currently being in in the main branch... Those guys are rockstars and are on fire atm.. hopefully the heat continues....

Anywhoo... this is getting pretty boring. If you have any new years recommendations, please let me know...