From a86e5876ebe805e9d922bce6eefd988acb7243b0 Mon Sep 17 00:00:00 2001
From: Siddharth Agrawal <siddharth@kognitos.com>
Date: Tue, 18 Oct 2022 16:54:26 +0530
Subject: [PATCH 1/2] create the circleci plugin

---
 plugins/circleci/README.md           | 23 +++++++++
 plugins/circleci/circleci.plugin.zsh | 12 +++++
 plugins/circleci/circleci_status.py  | 71 ++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+)
 create mode 100644 plugins/circleci/README.md
 create mode 100644 plugins/circleci/circleci.plugin.zsh
 create mode 100644 plugins/circleci/circleci_status.py

diff --git a/plugins/circleci/README.md b/plugins/circleci/README.md
new file mode 100644
index 000000000..ad84c6bbf
--- /dev/null
+++ b/plugins/circleci/README.md
@@ -0,0 +1,23 @@
+# CircleCi Plugin
+
+This plugin provides easy to use cli commands to query circle ci job statuses
+
+To use it, add `circleci` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... circleci)
+```
+
+## Prerequisites
+You need to have the `CIRCLECI_API_TOKEN` and `CIRCLECI_ORG_SLUG` as environment
+variables before calling the `circleci_status` function <br>
+You can learn how to add a circleci api token [here](https://circleci.com/docs/managing-api-tokens/) <br>
+The org slug takes the format of `{vcs}/{org_name}`
+
+## Usage
+```shell
+> circleci_status
+```
+The above command would list down all the jobs (with their run status) on the
+repository and branch that you are currently on <br>
+You can also use the `cis` alias to run the above function
diff --git a/plugins/circleci/circleci.plugin.zsh b/plugins/circleci/circleci.plugin.zsh
new file mode 100644
index 000000000..5cdcf8566
--- /dev/null
+++ b/plugins/circleci/circleci.plugin.zsh
@@ -0,0 +1,12 @@
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+__CI_ZSH_DIR="${0:h:A}"
+
+alias cis='circleci_status'
+
+
+function circleci_status() {
+    python3 "$__CI_ZSH_DIR"/circleci_status.py "$(git_current_branch)" "$(git_repo_name)" | less
+}
diff --git a/plugins/circleci/circleci_status.py b/plugins/circleci/circleci_status.py
new file mode 100644
index 000000000..7e40944cf
--- /dev/null
+++ b/plugins/circleci/circleci_status.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+
+import requests
+import os
+import sys
+
+CIRCLECI_API = "https://circleci.com/api/v2"
+org_slug = os.environ.get("CIRCLECI_ORG_SLUG")
+args = sys.argv
+
+
+class COLORS:
+    reset = '\033[0m'
+
+    class FG:
+        red = '\033[31m'
+        green = '\033[32m'
+        yellow = '\033[93m'
+
+
+def get_resp_items(resp):
+    if resp.status_code != 200:
+        sys.exit(0)
+    items = resp.json()["items"]
+    if len(items) == 0:
+        sys.exit(0)
+    return items
+
+
+def get_status_text(status):
+    if status == "success":
+        return COLORS.FG.green + "✓" + COLORS.reset
+    elif status in ("running", "not_run", "retried", "queued"):
+        return COLORS.FG.yellow + "·" + COLORS.reset
+    else:
+        return COLORS.FG.red + "˟" + COLORS.reset
+
+
+if not org_slug or len(args) != 3:
+    sys.exit(0)
+
+branch_name = args[1]
+repo_name = args[2]
+
+# Here we query for all the pipelines belonging to the current branch in the current repo
+headers = {"Circle-token": os.environ.get("CIRCLECI_API_TOKEN")}
+url = f"{CIRCLECI_API}/project/{org_slug}/{repo_name}/pipeline"
+params = {"branch": branch_name}
+response = requests.get(url, headers=headers, params=params)
+pipelines = get_resp_items(response)
+# use the latest pipeline
+pipeline_id = pipelines[0]["id"]
+
+# Now fetch the workflows for the selected pipeline
+url = f"{CIRCLECI_API}/pipeline/{pipeline_id}/workflow"
+response = requests.get(url, headers=headers)
+workflows = get_resp_items(response)
+# use the latest workflow
+workflow_id = workflows[0]["id"]
+
+url = f"{CIRCLECI_API}/workflow/{workflow_id}/job"
+response = requests.get(url, headers=headers)
+jobs = get_resp_items(response)
+
+for job in jobs:
+    status = job["status"]
+    name = job["name"]
+    project_slug = job["project_slug"]
+    job_number = job["job_number"]
+    url = f"https://circleci.com/{project_slug}/{job_number}"
+    print("{}  {:<50}  {}".format(get_status_text(status), name, url))

From c99a1c5fb52439b2666df94fdd944ae23164af01 Mon Sep 17 00:00:00 2001
From: Siddharth Agrawal <siddharth@kognitos.com>
Date: Tue, 18 Oct 2022 17:59:58 +0530
Subject: [PATCH 2/2] only print job status for some status values

---
 plugins/circleci/circleci_status.py | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/plugins/circleci/circleci_status.py b/plugins/circleci/circleci_status.py
index 7e40944cf..cedfb8265 100644
--- a/plugins/circleci/circleci_status.py
+++ b/plugins/circleci/circleci_status.py
@@ -30,10 +30,10 @@ def get_resp_items(resp):
 def get_status_text(status):
     if status == "success":
         return COLORS.FG.green + "✓" + COLORS.reset
-    elif status in ("running", "not_run", "retried", "queued"):
-        return COLORS.FG.yellow + "·" + COLORS.reset
+    elif status in ("running", "not_run", "retried"):
+        return COLORS.FG.yellow + "•" + COLORS.reset
     else:
-        return COLORS.FG.red + "˟" + COLORS.reset
+        return COLORS.FG.red + "✗" + COLORS.reset
 
 
 if not org_slug or len(args) != 3:
@@ -64,8 +64,10 @@ jobs = get_resp_items(response)
 
 for job in jobs:
     status = job["status"]
-    name = job["name"]
-    project_slug = job["project_slug"]
-    job_number = job["job_number"]
-    url = f"https://circleci.com/{project_slug}/{job_number}"
-    print("{}  {:<50}  {}".format(get_status_text(status), name, url))
+    if status in ("success", "running", "failed", "retried", "timedout",
+                  "on_hold", "canceled", "terminated_unknown"):
+      name = job["name"]
+      project_slug = job["project_slug"]
+      job_number = job["job_number"]
+      url = f"https://circleci.com/{project_slug}/{job_number}"
+      print("{}  {:<50}  {}".format(get_status_text(status), name, url))