a tiny linear cli

i’m a fan of the way linear has a button to pop out a git branch name for an issue, but sometimes i’m working on that branch and get back to linear. this CLI does exactly that.FYI that there’s also a vscode extension from linear that does this, too.

additionally, if you rename the directory your project is in to start with the team id, it’ll let you jump to the team.

it has three commands:

linear issueview the issue from your current branch
linear teamjump to the team view based on the project directory name
linear idprint out the current branch’s issue idi use this in a gh alias that prefill a pull request with the issue id.

full script below, copy it to somewhere on your $PATH.i briefly considered pushing this up to homebrew but that takes away from the fun of having a script you can tweak. since i use this all the time, i have it aliased to l. if i ever make updates to this i’ll push them up to github in my dotfiles.

please note, this assumes mac os, the linear desktop app is installed and that gnu coreutils with the funny g prefixes (e.g. ggrep) are installed.

bash code:i used rust to write a more full featured cli for the previous proj mgmt tool i used. authorized api calls, formatted table output, llm summaries for branch names… the works. with linear i need a lot less of that, and having this in bash means i don’t have to compile anything after changing it.

#!/bin/bash

function usage() {
    echo "Usage: $0 <command> <sub-command>"
    echo "Commands:"
    echo "  i|issue         View the linear issue linked to the current git branch"
    echo "  t|team          View the linear team based on the git repo's directory name"
    echo "  id|issue-id     Print the issue id in the current git branch"
    exit 1;
}

function issue() {
    issueId=$(id)

    if [ "$issueId" ]; then
        url="https://linear.app/issue/$issueId"
        echo "Opening $url in Linear.app"
        open -a /Applications/Linear.app "$url"
    else
        echo "The current branch does not contain a valid linear issue id."
        exit 1
    fi
}

function id() {
    gitBranch=$(git symbolic-ref --short HEAD)
    issueId=$(echo $gitBranch | ggrep -oP '[a-zA-Z]{2,5}-[1-9][0-9]*')

    if [ "$issueId" ]; then
        echo $issueId | awk '{print toupper($0)}'
    fi
}

function team() {
    dir=$(basename $(git rev-parse --show-toplevel))
    # given your directory name starts with the team id, e.g.
    # exmpl-platform -> exmpl
    teamId=$(echo $dir | ggrep -oP '^[a-zA-Z]{2,5}' | awk '{print toupper($0)}')

    if [ "$teamId" ]; then
        open -a /Applications/Linear.app "https://linear.app/team/$teamId"
    else
        echo "Could not determine team id from directory name."
        exit 1
    fi
}

CMD=${1:-""}
case $CMD in
    i | issue)
        issue
        ;;
    id | issue-id)
        id
        ;;
    t | team)
        team
        ;;
    *)
        usage
        ;;
esac

© 2024 peter schilling