/card-counter

A CLI for quickly summarizing story points in Trello lists.

Primary LanguageRust

card-counter

A CLI for quickly summarizing story points in Trello lists.

./images/card-counter.gif

card-counter 1.0.0
Justin Barclay <justincbarclay@gmail.com>
A CLI for quickly summarizing story points in Trello lists

USAGE:
    card-counter [FLAGS] [OPTIONS] [SUBCOMMAND]

FLAGS:
    -c, --compare    Compares the current trello board with a previous entry
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -b, --board-id <ID>          The ID of the board where the cards are meant to be counted from
    -d, --database <DATABASE>    Choose the database you want to save current request in [possible values: local, aws,
                                 azure]
    -f, --filter <FILTER>        Filters out all lists with a name that contains the substring FILTER
    -k, --kanban <KANBAN>        The kanban API to get your board and card information from [possible values: jira,
                                 trello]
    -s, --save <SAVE>            Save the current entry in the database [default: true]  [possible values: true, false]

SUBCOMMANDS:
    burndown    Parses data for a board and prints out data to be piped to gnuplot
    config      Edit properties associated with card-counter.
    help        Prints this message or the help of the given subcommand(s)

Getting Started for Getting Started

Before you can even think about getting started, you will need a Trello account. If you don’t have a Trello account, go get one. Use it for a while. But not just use it, breathe it, live it, feel it deep down in your meat covered bones. Once your entire being is permeated with Trello, you are ready to start tracking the progress you make in sprints.

Finally, you’ve got a Trello account and you’ve created some boards. Within those boards, you’ve created stacks of lists of cards. And within each card, you’ve scoped out the work and given it a score.

Great! You’ve got the theory down. I decree that you are an official agile scrum master. I even made a certificate for you.

./images/certificate_of_mastery.png

Finally, finally, we’re ready to get started.

Getting Started

You can begin thinking about getting started with card-counter now. But before you can start thinking about card-counter itself, however, you will need to take some steps to retrieve and save information from Trello:

Trello

  1. Get your API key
  2. Generate a Trello API token by going to https://trello.com/1/authorize?expiration=1day&name=card-counter&scope=read&response_type=token&key=<your-key-here>
  3. Save these:
    • As an environment variable:
    export TRELLO_API_KEY=<your API key>
    export TRELLO_API_TOKEN=<your API token>
        
    • Or in the config file:
    card-counter config
        

There! We’re done thinking about getting started. card-counter now knows enough about you to start talking to the Trello API.

Jira

  1. Generate an API token for your user
  2. Save the token, url, and username:
    • As an environment variable:
    export JIRA_USERNAME=<your username>
    export JIRA_API_TOKEN=<your API token>
    export JIRA_URL=<your Jira URL>
        
    • Or in the config file:
    card-counter config
        

Curiosity

If you’re curious about what information card-counter stores, you can find the config file and local database in $HOME/.card-counter/. If you have privacy concerns about what card-counter is doing with your information, don’t worry about it. card-counter pulls down your data from the Trello API, processes it, and stores it all locally on your machine.

Setting up your Kanban board

What’s the point?

Now that you understand the theory, we are ready to set up our boards to be processed by card-counter. Luckily, preparing your board for card-counter is simple. You just put in some numbers and you are set. Ok, it’s not quite that simple, but it’s close.

card-counter tracks the estimated and actual effort a card has taken. It does this by using numbers inside of parentheses – () – and square brackets – [] – within the card’s title. If the title only has a number in parentheses, it acts as both the “actual” and “estimated” effort. However, suppose there are numbers in parentheses and in square brackets in the title. In that case, the number in the square brackets will count as the “actual” effort taken and the number in the parentheses will act as the “estimated” effort. In short, numbers in square brackets are only counted as corrective numbers.

It’s hard to see what this means so let’s walk through an example:

Sally has a list, “This Sprint”, which has a singled card titled “Write docs for card-counter”. They have done their homework and they know that the documentation for card-counter is lacking. They estimate that this is going to be an effort of 2. Sally updates the card’s name to “Write docs for card-counter (2)”. If Sally ran card-counter, it would report:

ListCardsScoreEstimatedUnscored
This Sprint1220

After completing the task, Sally had learned that card-counter’s docs were in a much graver state than she had estimated. So she updates the card’s title to “(2)[4] Write docs for card-counter”.

Now, if Sally ran card-counter, it would report:

ListCardsScoreEstimatedUnscored
This Sprint1420

Burn it all down

If you have a boss, you know how much they like images. Images are great communication tools. They are easy to understand and they have pretty colours. card-counter can help produce burn down charts for you. You need to do two things to facilitate this process: One, have a board that has “Done” somewhere in the name. Two, run card-counter regularly to produce a reasonable amount of data for that board (daily).

CLI Examples

When you first run card-counter on a new machine, you can run the config command. This allows card-counter to capture important pieces of information, like how to access your Trello data and your preferred database.

card-counter config

After that, you can run the command itself.

card-counter 

This will bring up a list of boards you have access to and get you to choose what board you want to run the command on.

If you know that you will be running card-counter on the same board all the time, you can use the -b (--board-id) option and set the board-id. You can find the board-id in the URL for your board.

A typical Trello board URL looks like: https://trello.com/b/<board-id>/<your-board>

For example: if you want to use the Trello board-id for card-counter, https://trello.com/b/wtPNQDEV/card-counter, you would use “wtPNQDEV” as the board-id.

card-counter --board-id wtPNQDEV 

If you have a board that is a little noisy, you can filter out lists that you don’t want to track. You can do this by using the -f (--filter) option. If you add a substring to the list(s), such as [ignore], card-counter can filter out these lists for you. Be careful, however, the filter option is case sensitive.

card-counter --board-id wtPNQDEV --filter ignore

If you’d like to generate a burndown chart for your boss or because you like graphs, there is the burndown command. It will output comma-separated values that you can feed to your graphing library of choice. For this example, we’ll have gnuplot generate a graph for us.

First, we’ll need to set-up a gnuplot script to parse the data for us. Save the following example in a file titled “burndown.gp”.

set datafile separator ','
set xdata time
set timefmt '%d-%m-%y'
set format x "%d %b"
set autoscale x
plot for[col=2:3] "burndown.csv" u 1:col title columnheader(col) with lines

The burndown command requires -s (--start) and -e (--end) options to run. They represent the start and end dates you wish to generate the burndown chart. These dates are formatted as the string “year-month-day” for example: “2020-04-14”. Additionally, we’ll pass in filter and board-id options. Finally, we’ll save the output to a file and tell gnuplot to process it for us.

card-counter burndown --board-id wtPNQDEV --start 2020-04-01 --end 2020-04-14 -f NoBurn > burndown.csv && gnuplot burndown.gp -p

./images/burndown.png

Jira Board ID

Similarly to Trello, Jira stores the board-id in the URL as well <your based url>/jira/software/projects/CC/boards/<board-id>

So for example, to extract the information from your Jira board url https://card-counter.atlassian.net/jira/software/projects/CC/boards/1, the base URL would be “https://card-counter.atlassian.net” and the board-id would be “1”.

export JIRA_URL=https://card-counter.atlassian.net
card-counter --board-id 1

Alternative outputs

If you don’t want to use gnuplot or some other sort of graphing library, I’ve helpfully decided to implement both svg or ascii graphs.

For ascii output you pass in the option --output ascii

card-counter burndown --board-id wtPNQDEV --start 2020-04-01 --end 2020-04-14 -f NoBurn --output ascii

… and for svg output you pass in the option --output svg

card-counter burndown --board-id wtPNQDEV --start 2020-04-01 --end 2020-04-14 -f NoBurn --output svg

Like csv both of these options print to the terminal.

“Advanced”

Are you forced to collaborate with others? Weirder yet, do you like to collaborate with others? Or do you just demand that everything needs to be in the cloud? If any 3 of those are correct, but especially if ALL of them are, I have the solution for you. It’s card-counter cloud edition! Where we allow you to store your data in DynamoDB or CosmosDB.

To start with you’ll need to ask your administrator to give you read/write access to Dynamo or Cosmos. This process can take anywhere from 3 weeks to 4 months.

AWS DynamoDB

Authentication

Did you return with the correct AWS permissions? That’s great! I’m assuming in the interceding 3 months that you’ve become familiar with the AWS CLI. If so, this suggests your credentials are set somewhere. You probably don’t need to do anything. If you have rushed into this, and it is your first time using AWS, you can start reading Amazon’s documentation to find out what you need to set.

card-counter will check several locations for your AWS credentials and Region.

In order, the locations are:

  1. Environment Variables
  2. Credential Files
  3. IAM ECS Container Profile
  4. IAM EC2 Instance Profile

Configuring

You can tell card-counter you want to use AWS as your database (instead of the local database) in two ways:

  1. As an option through the CLI
    card-counter --database aws
        
  2. Select the aws option in your config file
    card-counter config
        

DynamoDB Table

For those of you who want to avoid doing as much work as possible, card-counter can create the necessary table in DynamoDB for you. When you run card-counter for the first time, with AWS as your database, it will ask for permission to create the “card-counter” table.

If you’re a control freak (or worse yet, if you like config files everywhere), you can manage the database yourself. I’ve provided the terraform below to help you create the “card-counter” table.

resource "aws_dynamodb_table" "card-counter-table" {
  name           = "card-counter"
  billing_mode   = "PROVISIONED"
  read_capacity  = 1
  write_capacity = 1
  hash_key       = "board_id"
  range_key      = "time_stamp"

  attribute {
    name = "board_id"
    type = "S"
  }

  attribute {
    name = "time_stamp"
    type = "N"
  }

  tags = {
    Name        = "dynamodb-table-1"
    Environment = "production"
  }
}

CosmosDB

Authentication

Did your administrator give you access? Bless their heart, they trusted you!

Before card-counter can talk to the all mighty Azure we need you to set some environment variables:

export COSMOS_ACCOUNT=<your azure account name>
export COSMOS_MASTER_KEY=<what a tasteless name, but it's what Azure calls it and it goes here>

Configuring

You can tell card-counter to use CosmosDB as the backend in two ways:

  1. As an option through the CLI
    card-counter --database azure
        
  2. Select the azure option in your config file and set the database name and container name
    card-counter config
        

CosmosDB Database and Container

Like with DynamoDB card-counter can create the CosmosDB for you, I mean, if you’re lazy and trust me. If you don’t trust me but are still kind of lazy, here’s where I create stuff.

But we all know you’re a control freak and that you’ve fallen in love with IaaC, but have managed to stay away from the dreaded ARM templates. So let me throw more terraform in your lap to manage.

data "azurerm_cosmosdb_account" "example" {
  name                = "tfex-cosmosdb-account"
  resource_group_name = "tfex-cosmosdb-account-rg"
}

resource "azurerm_cosmosdb_sql_database" "example" {
  name                = "card-counter"
  resource_group_name = data.azurerm_cosmosdb_account.example.resource_group_name
  account_name        = data.azurerm_cosmosdb_account.example.name
  throughput          = 400
}

resource "azurerm_cosmosdb_sql_container" "example" {
  name                  = "card-counter"
  resource_group_name   = azurerm_cosmosdb_account.example.resource_group_name
  account_name          = azurerm_cosmosdb_account.example.name
  database_name         = azurerm_cosmosdb_sql_database.example.name
  partition_key_path    = "/board_id"
  partition_key_version = 1
  throughput            = 400

  indexing_policy {
    indexing_mode = "Consistent"

    included_path {
      path = "/*"
    }
  }

  unique_key {
    paths = ["/board_id"]
  }
}

Build from source

Don’t trust the binaries I provided? I have an easy solution for you. Build it from source. (Easy if you already have rust and cargo installed)

git clone https://github.com/justinbarclay/card-counter.git
cd card-counter
cargo install --path ./card-counter/cli

Fin, finally.

But wait there’s more (λ)

As a bonus treat for those of you dealing with corporate overlords and Slack, if you’re so inclined you could create a Slack Slash command to send. I’ve created an outline, or a sketch, of how your could this here.