about summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cmd/slocalc/README.md20
-rw-r--r--cmd/slocalc/main.go51
-rw-r--r--nix/flake/packages.nix4
-rw-r--r--nix/profiles/home-manager/shell.nix1
-rw-r--r--packages/slocalc/default.nix25
-rwxr-xr-xpackages/slocalc/slocalc.py69
6 files changed, 98 insertions, 72 deletions
diff --git a/cmd/slocalc/README.md b/cmd/slocalc/README.md
deleted file mode 100644
index 660b653..0000000
--- a/cmd/slocalc/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# slocalc
-
-A simple SLO calculator for the command line.
-
-## Usage
-
-```bash
-slocalc <availability>
-```
-
-## Example
-
-```bash
-% slocalc 99.9
-daily    : 0 days, 0 hours, 0 minutes, 4 seconds
-weekly   : 0 days, 0 hours, 0 minutes, 30 seconds
-monthly  : 0 days, 0 hours, 2 minutes, 9 seconds
-quarterly: 0 days, 0 hours, 6 minutes, 28 seconds
-yearly   : 0 days, 0 hours, 26 minutes, 16 seconds
-```
diff --git a/cmd/slocalc/main.go b/cmd/slocalc/main.go
deleted file mode 100644
index ae4998b..0000000
--- a/cmd/slocalc/main.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"os"
-	"strconv"
-)
-
-const (
-	secondsPerHour = 3600
-)
-
-func main() {
-	if len(os.Args) <= 1 {
-		fmt.Println("Please provide a value")
-		os.Exit(1)
-	}
-
-	uptime, _ := strconv.ParseFloat(os.Args[1], 64)
-	switch {
-	case uptime <= 0:
-		uptime = 0
-	case uptime >= 100:
-		uptime = 100
-	}
-
-	allowedDowntime := (((100 * 100) - (uptime * 100)) / (100 * 100))
-
-	dailySeconds := secondsPerHour * 24 * allowedDowntime
-	weekSeconds := dailySeconds * 7
-	monthSeconds := dailySeconds * 30
-	quarterSeconds := dailySeconds * 90
-	yearSeconds := dailySeconds * 365
-
-	fmt.Printf("daily    : %s\n", secondsToHumanTime(int(dailySeconds)))
-	fmt.Printf("weekly   : %s\n", secondsToHumanTime(int(weekSeconds)))
-	fmt.Printf("monthly  : %s\n", secondsToHumanTime(int(monthSeconds)))
-	fmt.Printf("quarterly: %s\n", secondsToHumanTime(int(quarterSeconds)))
-	fmt.Printf("yearly   : %s\n", secondsToHumanTime(int(yearSeconds)))
-}
-
-// secondsToHumanTime converts seconds to human readable time
-func secondsToHumanTime(seconds int) string {
-	days := seconds / 86400
-	seconds = seconds % 86400
-	hours := seconds / 3600
-	seconds = seconds % 3600
-	minutes := seconds / 60
-	seconds = seconds % 60
-	return fmt.Sprintf("%d days, %d hours, %d minutes, %d seconds", days, hours, minutes, seconds)
-}
diff --git a/nix/flake/packages.nix b/nix/flake/packages.nix
index 1d310d3..71b9dc5 100644
--- a/nix/flake/packages.nix
+++ b/nix/flake/packages.nix
@@ -6,7 +6,8 @@
   perSystem = { config, pkgs, ... }: {
     overlayAttrs = {
       inherit (config.packages)
-        seqstat;
+        seqstat
+        slocalc;
     };
 
     packages = {
@@ -14,6 +15,7 @@
       git-blame-stats = pkgs.callPackage "${self}/packages/git-blame-stats" { };
       git-broom = pkgs.callPackage "${self}/packages/git-broom" { };
       ipconverter = pkgs.callPackage "${self}/packages/ipconverter" { };
+      slocalc = pkgs.callPackage "${self}/packages/slocalc" { };
     };
   };
 }
diff --git a/nix/profiles/home-manager/shell.nix b/nix/profiles/home-manager/shell.nix
index 3869d9b..046cb5e 100644
--- a/nix/profiles/home-manager/shell.nix
+++ b/nix/profiles/home-manager/shell.nix
@@ -25,6 +25,7 @@
     self.packages.${pkgs.system}.git-broom
     self.packages.${pkgs.system}.ipconverter
     self.packages.${pkgs.system}.seqstat
+    self.packages.${pkgs.system}.slocalc
   ];
 
   home.sessionVariables = {
diff --git a/packages/slocalc/default.nix b/packages/slocalc/default.nix
new file mode 100644
index 0000000..114120e
--- /dev/null
+++ b/packages/slocalc/default.nix
@@ -0,0 +1,25 @@
+{ lib, python3, stdenvNoCC }:
+
+stdenvNoCC.mkDerivation rec {
+  pname = "slocalc";
+  src = ./slocalc.py;
+  version = "0.1.0";
+
+  buildInputs = [ python3 ];
+  propagatedBuildInputs = [ python3 ];
+
+  dontUnpack = true;
+  dontBuild = true;
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp $src $out/bin/${pname}
+  '';
+
+  meta = with lib; {
+    description = "Calculate SLO uptime.";
+    license = with licenses; [ mit ];
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ fcuny ];
+  };
+}
diff --git a/packages/slocalc/slocalc.py b/packages/slocalc/slocalc.py
new file mode 100755
index 0000000..e13e850
--- /dev/null
+++ b/packages/slocalc/slocalc.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+"""
+A simple SLO calculator for the command line.
+
+$ slocalc.py 99.99
+daily:     0 days, 0 hours, 0 minutes, 8 seconds
+weekly:    0 days, 0 hours, 1 minutes, 0 seconds
+monthly:   0 days, 0 hours, 4 minutes, 19 seconds
+quarterly: 0 days, 0 hours, 12 minutes, 57 seconds
+yearly:    0 days, 0 hours, 52 minutes, 33 seconds
+"""
+
+from typing import Optional
+from datetime import timedelta
+
+import sys
+
+
+seconds_in_hour = 60 * 60
+
+
+def convert_to_float(s: str) -> Optional[float]:
+    try:
+        return float(s)
+    except ValueError:
+        print(f"error: '{s}' cannot be converted to float")
+        return None
+
+
+def seconds_to_human_readable(seconds: int) -> str:
+    delta = timedelta(seconds=seconds)
+    days = delta.days
+    hours, remainder = divmod(delta.seconds, 3600)
+    minutes, seconds = divmod(remainder, 60)
+    return f"{days} days, {hours} hours, {minutes} minutes, {seconds} seconds"
+
+
+def cli():
+    if len(sys.argv) <= 1:
+        print("you need at least one argument", file=sys.stderr)
+        sys.exit(1)
+
+    uptime = convert_to_float(sys.argv[1])
+    if uptime is None:
+        print("failed to read input")
+        sys.exit(1)
+
+    if uptime <= 0:
+        uptime = 0
+    if uptime >= 100:
+        uptime = 100
+
+    allowed_downtime = ((100 * 100) - (uptime * 100)) / (100 * 100)
+
+    daily_seconds = seconds_in_hour * 24 * allowed_downtime
+    week_seconds = daily_seconds * 7
+    month_seconds = daily_seconds * 30
+    quarter_seconds = daily_seconds * 90
+    year_seconds = daily_seconds * 365
+
+    print("daily:     {0}".format(seconds_to_human_readable(daily_seconds)))
+    print("weekly:    {0}".format(seconds_to_human_readable(week_seconds)))
+    print("monthly:   {0}".format(seconds_to_human_readable(month_seconds)))
+    print("quarterly: {0}".format(seconds_to_human_readable(quarter_seconds)))
+    print("yearly:    {0}".format(seconds_to_human_readable(year_seconds)))
+
+
+if __name__ == "__main__":
+    cli()