From 6847ed8e8415037665dcc7c8ff3de9efc760c429 Mon Sep 17 00:00:00 2001
From: Tung Bui <tung.bquang@gmail.com>
Date: Sat, 9 Mar 2024 08:47:57 +0700
Subject: [PATCH 1/9] tool: add latest version script

---
 scripts/python/check_latest_version.py | 48 ++++++++++++++++++++++++++
 scripts/python/requrement.txt          |  1 +
 2 files changed, 49 insertions(+)
 create mode 100644 scripts/python/check_latest_version.py
 create mode 100644 scripts/python/requrement.txt

diff --git a/scripts/python/check_latest_version.py b/scripts/python/check_latest_version.py
new file mode 100644
index 0000000..c4ebf7f
--- /dev/null
+++ b/scripts/python/check_latest_version.py
@@ -0,0 +1,48 @@
+import requests
+import re
+from bs4 import BeautifulSoup
+
+class VersionParser:
+    def __init__(self):
+        self.url = None
+        self.version = None
+
+    def fetch_html(self, url):
+        try:
+            response = requests.get(url)
+            response.raise_for_status()
+            return response.text
+        except requests.exceptions.RequestException as e:
+            print(f"Error fetching HTML: {e}")
+            return None
+
+    def check_python_version(self):
+        latest_python_version = None
+        # Define a regular expression pattern to match the version number
+        pattern = r'Python (\d+\.\d+\.\d+)'
+        text = self.fetch_html("https://www.python.org/downloads/")
+        # Use re.search to find the first occurrence of the pattern in the text
+        match = re.search(pattern, text)
+
+        # Check if a match is found and print the version number
+        if match:
+            latest_python_version = match.group(1)
+        else:
+            print("Version number not found.")
+        return latest_python_version
+
+# Example usage
+versions = {}
+
+version_parser = VersionParser()
+latest_version = version_parser.check_python_version()
+
+if latest_version:
+    print(f"Latest Python version: {latest_version}")
+else:
+    print("Failed to retrieve the latest version.")
+
+versions["python3"] = latest_version
+
+
+print(versions)
\ No newline at end of file
diff --git a/scripts/python/requrement.txt b/scripts/python/requrement.txt
new file mode 100644
index 0000000..1315442
--- /dev/null
+++ b/scripts/python/requrement.txt
@@ -0,0 +1 @@
+bs4

From 0c9a67245885e2807ea13ce9c5116ebeb118464d Mon Sep 17 00:00:00 2001
From: Tung Bui <tung.bquang@gmail.com>
Date: Sat, 9 Mar 2024 15:13:41 +0700
Subject: [PATCH 2/9] script: improve get latest version script

---
 scripts/python/check_latest_version.py | 86 +++++++++++++++++++++++---
 1 file changed, 79 insertions(+), 7 deletions(-)

diff --git a/scripts/python/check_latest_version.py b/scripts/python/check_latest_version.py
index c4ebf7f..c579d13 100644
--- a/scripts/python/check_latest_version.py
+++ b/scripts/python/check_latest_version.py
@@ -15,6 +15,14 @@ def fetch_html(self, url):
         except requests.exceptions.RequestException as e:
             print(f"Error fetching HTML: {e}")
             return None
+    def do_http_request(self, url):
+        try:
+            response = requests.get(url)
+            response.raise_for_status()
+            return response.json()
+        except requests.exceptions.RequestException as e:
+            print(f"Error fetching HTML: {e}")
+            return None
 
     def check_python_version(self):
         latest_python_version = None
@@ -31,18 +39,82 @@ def check_python_version(self):
             print("Version number not found.")
         return latest_python_version
 
+    def check_kubectl_version(self):
+        latest_python_version = None
+        # Define a regular expression pattern to match the version number
+        pattern = r'v(\d+\.\d+\.\d+)'
+        text = self.fetch_html("https://cdn.dl.k8s.io/release/stable.txt")
+        # Use re.search to find the first occurrence of the pattern in the text
+        match = re.search(pattern, text)
+
+        # Check if a match is found and print the version number
+        if match:
+            latest_python_version = match.group(1)
+        else:
+            print("Version number not found.")
+        return latest_python_version
+
+    def check_awscli_version(self):
+        latest_awscli_version = None
+        # Define a regular expression pattern to match the version number
+        version_pattern = re.compile(r'\b(\d+\.\d+\.\d+)\b')
+        text = self.fetch_html("https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst")
+        # Search for the version number in the text
+        match = version_pattern.search(text)
+
+        # Check if a match is found and print the version number
+        if match:
+            latest_awscli_version = match.group(1)
+            print("Parsed version number:", latest_awscli_version)
+        else:
+            print("Version number not found in the text.")
+        return latest_awscli_version
+
+    def check_github_release_version(self, repo, tag_prefix="v"):
+        print(f"Checking repo {repo}")
+        print(f"Tag prefix: {tag_prefix}")
+        latest_version = None
+        req = self.do_http_request(f"https://api.github.com/repos/{repo}/releases/latest")
+        latest_tag_name = req["tag_name"]
+        print(latest_tag_name)
+        # Only get the version number
+        # Default is vX.Y.Z
+        latest_version =  latest_tag_name.split(tag_prefix)[1]
+
+        print(f"Latest version of {repo}: {latest_version}")
+        return latest_version
+
 # Example usage
 versions = {}
-
 version_parser = VersionParser()
-latest_version = version_parser.check_python_version()
+### Python
+python_version = version_parser.check_python_version()
+versions["python3"] = python_version
+
+### Ansible
+ansible_version = version_parser.check_github_release_version("ansible/ansible")
+versions["ansible"] = ansible_version
+
+### Terraform
+terraform_version = version_parser.check_github_release_version("hashicorp/terraform")
+versions["terraform"] = terraform_version
+
+### Kubectl
+kubectl_version = version_parser.check_kubectl_version()
+versions["kubectl"] = kubectl_version
 
-if latest_version:
-    print(f"Latest Python version: {latest_version}")
-else:
-    print("Failed to retrieve the latest version.")
+### Helm
+helm_version = version_parser.check_github_release_version("helm/helm")
+versions["helm"] = helm_version
 
-versions["python3"] = latest_version
+### Awscli
+awscli_version = version_parser.check_awscli_version()
+versions["awscli"] = awscli_version
 
+### AZ CLi
+azcli_version = version_parser.check_github_release_version("Azure/azure-cli", "azure-cli-")
+versions["azurecli"] = azcli_version
 
+### Summary
+print("Summary:")
 print(versions)
\ No newline at end of file

From 3b1e4b8bcf24a5e6e4183bcf2bf893ef6150e83e Mon Sep 17 00:00:00 2001
From: Tung Bui <tung.bquang@gmail.com>
Date: Sat, 9 Mar 2024 15:15:35 +0700
Subject: [PATCH 3/9] script: improve codebase

---
 scripts/python/check_latest_version.py | 123 +++++++++++--------------
 1 file changed, 52 insertions(+), 71 deletions(-)

diff --git a/scripts/python/check_latest_version.py b/scripts/python/check_latest_version.py
index c579d13..e5c9412 100644
--- a/scripts/python/check_latest_version.py
+++ b/scripts/python/check_latest_version.py
@@ -13,108 +13,89 @@ def fetch_html(self, url):
             response.raise_for_status()
             return response.text
         except requests.exceptions.RequestException as e:
-            print(f"Error fetching HTML: {e}")
+            print(f"Error fetching HTML from {url}: {e}")
             return None
+
     def do_http_request(self, url):
         try:
             response = requests.get(url)
             response.raise_for_status()
             return response.json()
         except requests.exceptions.RequestException as e:
-            print(f"Error fetching HTML: {e}")
+            print(f"Error fetching data from {url}: {e}")
             return None
 
-    def check_python_version(self):
-        latest_python_version = None
-        # Define a regular expression pattern to match the version number
-        pattern = r'Python (\d+\.\d+\.\d+)'
-        text = self.fetch_html("https://www.python.org/downloads/")
-        # Use re.search to find the first occurrence of the pattern in the text
+    def check_version(self, name, url, pattern):
+        latest_version = None
+        text = self.fetch_html(url)
         match = re.search(pattern, text)
 
-        # Check if a match is found and print the version number
         if match:
-            latest_python_version = match.group(1)
+            latest_version = match.group(1)
+            print(f"Latest version of {name}: {latest_version}")
         else:
-            print("Version number not found.")
-        return latest_python_version
+            print(f"Version number not found for {name}.")
+
+        return latest_version
+
+    def check_python_version(self):
+        pattern = r'Python (\d+\.\d+\.\d+)'
+        return self.check_version("Python", "https://www.python.org/downloads/", pattern)
 
     def check_kubectl_version(self):
-        latest_python_version = None
-        # Define a regular expression pattern to match the version number
         pattern = r'v(\d+\.\d+\.\d+)'
-        text = self.fetch_html("https://cdn.dl.k8s.io/release/stable.txt")
-        # Use re.search to find the first occurrence of the pattern in the text
-        match = re.search(pattern, text)
-
-        # Check if a match is found and print the version number
-        if match:
-            latest_python_version = match.group(1)
-        else:
-            print("Version number not found.")
-        return latest_python_version
+        return self.check_version("kubectl", "https://cdn.dl.k8s.io/release/stable.txt", pattern)
 
     def check_awscli_version(self):
-        latest_awscli_version = None
-        # Define a regular expression pattern to match the version number
         version_pattern = re.compile(r'\b(\d+\.\d+\.\d+)\b')
-        text = self.fetch_html("https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst")
-        # Search for the version number in the text
-        match = version_pattern.search(text)
-
-        # Check if a match is found and print the version number
-        if match:
-            latest_awscli_version = match.group(1)
-            print("Parsed version number:", latest_awscli_version)
-        else:
-            print("Version number not found in the text.")
-        return latest_awscli_version
+        return self.check_version("awscli", "https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst", version_pattern)
 
-    def check_github_release_version(self, repo, tag_prefix="v"):
-        print(f"Checking repo {repo}")
+    def check_github_release_version(self, name, repo, tag_prefix="v"):
+        print(f"Checking {name} version from repo {repo}")
         print(f"Tag prefix: {tag_prefix}")
         latest_version = None
         req = self.do_http_request(f"https://api.github.com/repos/{repo}/releases/latest")
         latest_tag_name = req["tag_name"]
-        print(latest_tag_name)
-        # Only get the version number
-        # Default is vX.Y.Z
-        latest_version =  latest_tag_name.split(tag_prefix)[1]
 
-        print(f"Latest version of {repo}: {latest_version}")
+        latest_version =  latest_tag_name.split(tag_prefix)[1]
+        print(f"Latest version of {name}: {latest_version}")
         return latest_version
 
-# Example usage
-versions = {}
-version_parser = VersionParser()
-### Python
-python_version = version_parser.check_python_version()
-versions["python3"] = python_version
+def main():
+    versions = {}
+    version_parser = VersionParser()
+
+    # Python
+    python_version = version_parser.check_python_version()
+    versions["python3"] = python_version
+
+    # Ansible
+    ansible_version = version_parser.check_github_release_version("Ansible", "ansible/ansible")
+    versions["ansible"] = ansible_version
 
-### Ansible
-ansible_version = version_parser.check_github_release_version("ansible/ansible")
-versions["ansible"] = ansible_version
+    # Terraform
+    terraform_version = version_parser.check_github_release_version("Terraform", "hashicorp/terraform")
+    versions["terraform"] = terraform_version
 
-### Terraform
-terraform_version = version_parser.check_github_release_version("hashicorp/terraform")
-versions["terraform"] = terraform_version
+    # Kubectl
+    kubectl_version = version_parser.check_kubectl_version()
+    versions["kubectl"] = kubectl_version
 
-### Kubectl
-kubectl_version = version_parser.check_kubectl_version()
-versions["kubectl"] = kubectl_version
+    # Helm
+    helm_version = version_parser.check_github_release_version("Helm", "helm/helm")
+    versions["helm"] = helm_version
 
-### Helm
-helm_version = version_parser.check_github_release_version("helm/helm")
-versions["helm"] = helm_version
+    # Awscli
+    awscli_version = version_parser.check_awscli_version()
+    versions["awscli"] = awscli_version
 
-### Awscli
-awscli_version = version_parser.check_awscli_version()
-versions["awscli"] = awscli_version
+    # AZ CLi
+    azcli_version = version_parser.check_github_release_version("Azure CLI", "Azure/azure-cli", "azure-cli-")
+    versions["azurecli"] = azcli_version
 
-### AZ CLi
-azcli_version = version_parser.check_github_release_version("Azure/azure-cli", "azure-cli-")
-versions["azurecli"] = azcli_version
+    # Summary
+    print("Summary:")
+    print(versions)
 
-### Summary
-print("Summary:")
-print(versions)
\ No newline at end of file
+if __name__ == "__main__":
+    main()

From 83828f43cd7199271ec08a1b2744241213460508 Mon Sep 17 00:00:00 2001
From: Tung Bui <tung.bquang@gmail.com>
Date: Sat, 9 Mar 2024 15:18:53 +0700
Subject: [PATCH 4/9] version: improve code base

---
 scripts/python/check_latest_version.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/scripts/python/check_latest_version.py b/scripts/python/check_latest_version.py
index e5c9412..e583067 100644
--- a/scripts/python/check_latest_version.py
+++ b/scripts/python/check_latest_version.py
@@ -51,8 +51,7 @@ def check_awscli_version(self):
         return self.check_version("awscli", "https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst", version_pattern)
 
     def check_github_release_version(self, name, repo, tag_prefix="v"):
-        print(f"Checking {name} version from repo {repo}")
-        print(f"Tag prefix: {tag_prefix}")
+        print(f"Checking {name} version from repo {repo} using tag prefix: {tag_prefix}")
         latest_version = None
         req = self.do_http_request(f"https://api.github.com/repos/{repo}/releases/latest")
         latest_tag_name = req["tag_name"]

From ecb7cc49458d22bf9e958e13cc5b024da0970303 Mon Sep 17 00:00:00 2001
From: Tung Bui <tung.bquang@gmail.com>
Date: Sat, 9 Mar 2024 15:20:50 +0700
Subject: [PATCH 5/9] version: raise ex on failure

---
 scripts/python/check_latest_version.py | 62 +++++++++++++-------------
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/scripts/python/check_latest_version.py b/scripts/python/check_latest_version.py
index e583067..a72d54e 100644
--- a/scripts/python/check_latest_version.py
+++ b/scripts/python/check_latest_version.py
@@ -13,8 +13,7 @@ def fetch_html(self, url):
             response.raise_for_status()
             return response.text
         except requests.exceptions.RequestException as e:
-            print(f"Error fetching HTML from {url}: {e}")
-            return None
+            raise Exception(f"Error fetching HTML from {url}: {e}")
 
     def do_http_request(self, url):
         try:
@@ -22,8 +21,7 @@ def do_http_request(self, url):
             response.raise_for_status()
             return response.json()
         except requests.exceptions.RequestException as e:
-            print(f"Error fetching data from {url}: {e}")
-            return None
+            raise Exception(f"Error fetching data from {url}: {e}")
 
     def check_version(self, name, url, pattern):
         latest_version = None
@@ -34,8 +32,8 @@ def check_version(self, name, url, pattern):
             latest_version = match.group(1)
             print(f"Latest version of {name}: {latest_version}")
         else:
-            print(f"Version number not found for {name}.")
-
+            raise Exception(f"Version number not found for {name}.")
+        
         return latest_version
 
     def check_python_version(self):
@@ -64,37 +62,41 @@ def main():
     versions = {}
     version_parser = VersionParser()
 
-    # Python
-    python_version = version_parser.check_python_version()
-    versions["python3"] = python_version
+    try:
+        # Python
+        python_version = version_parser.check_python_version()
+        versions["python3"] = python_version
+
+        # Ansible
+        ansible_version = version_parser.check_github_release_version("Ansible", "ansible/ansible")
+        versions["ansible"] = ansible_version
 
-    # Ansible
-    ansible_version = version_parser.check_github_release_version("Ansible", "ansible/ansible")
-    versions["ansible"] = ansible_version
+        # Terraform
+        terraform_version = version_parser.check_github_release_version("Terraform", "hashicorp/terraform")
+        versions["terraform"] = terraform_version
 
-    # Terraform
-    terraform_version = version_parser.check_github_release_version("Terraform", "hashicorp/terraform")
-    versions["terraform"] = terraform_version
+        # Kubectl
+        kubectl_version = version_parser.check_kubectl_version()
+        versions["kubectl"] = kubectl_version
 
-    # Kubectl
-    kubectl_version = version_parser.check_kubectl_version()
-    versions["kubectl"] = kubectl_version
+        # Helm
+        helm_version = version_parser.check_github_release_version("Helm", "helm/helm")
+        versions["helm"] = helm_version
 
-    # Helm
-    helm_version = version_parser.check_github_release_version("Helm", "helm/helm")
-    versions["helm"] = helm_version
+        # Awscli
+        awscli_version = version_parser.check_awscli_version()
+        versions["awscli"] = awscli_version
 
-    # Awscli
-    awscli_version = version_parser.check_awscli_version()
-    versions["awscli"] = awscli_version
+        # AZ CLi
+        azcli_version = version_parser.check_github_release_version("Azure CLI", "Azure/azure-cli", "azure-cli-")
+        versions["azurecli"] = azcli_version
 
-    # AZ CLi
-    azcli_version = version_parser.check_github_release_version("Azure CLI", "Azure/azure-cli", "azure-cli-")
-    versions["azurecli"] = azcli_version
+        # Summary
+        print("Summary:")
+        print(versions)
 
-    # Summary
-    print("Summary:")
-    print(versions)
+    except Exception as e:
+        print(f"An error occurred: {e}")
 
 if __name__ == "__main__":
     main()

From 9a9f04828843f4757bb7273cbe9b60d620ba9f70 Mon Sep 17 00:00:00 2001
From: Tung Bui <tung.bquang@gmail.com>
Date: Sat, 9 Mar 2024 15:21:55 +0700
Subject: [PATCH 6/9] version: raise ex on failure.v1

---
 scripts/python/check_latest_version.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/scripts/python/check_latest_version.py b/scripts/python/check_latest_version.py
index a72d54e..d107965 100644
--- a/scripts/python/check_latest_version.py
+++ b/scripts/python/check_latest_version.py
@@ -1,6 +1,5 @@
 import requests
 import re
-from bs4 import BeautifulSoup
 
 class VersionParser:
     def __init__(self):

From bdc996986f87710465ef4ac5e3404bd3454574d4 Mon Sep 17 00:00:00 2001
From: Tung Bui <tung.bquang@gmail.com>
Date: Sat, 9 Mar 2024 15:24:16 +0700
Subject: [PATCH 7/9] version: rename

---
 scripts/{python => }/check_latest_version.py | 0
 scripts/python/requrement.txt                | 1 -
 2 files changed, 1 deletion(-)
 rename scripts/{python => }/check_latest_version.py (100%)
 delete mode 100644 scripts/python/requrement.txt

diff --git a/scripts/python/check_latest_version.py b/scripts/check_latest_version.py
similarity index 100%
rename from scripts/python/check_latest_version.py
rename to scripts/check_latest_version.py
diff --git a/scripts/python/requrement.txt b/scripts/python/requrement.txt
deleted file mode 100644
index 1315442..0000000
--- a/scripts/python/requrement.txt
+++ /dev/null
@@ -1 +0,0 @@
-bs4

From 97759e9713bf81af74ae49d541b52d5e8b867705 Mon Sep 17 00:00:00 2001
From: Tung Bui <tung.bquang@gmail.com>
Date: Sat, 9 Mar 2024 15:27:26 +0700
Subject: [PATCH 8/9] core: add toolkit info

---
 toolkit_info.json | 9 +++++++++
 1 file changed, 9 insertions(+)
 create mode 100644 toolkit_info.json

diff --git a/toolkit_info.json b/toolkit_info.json
new file mode 100644
index 0000000..7dc29c5
--- /dev/null
+++ b/toolkit_info.json
@@ -0,0 +1,9 @@
+{
+	"python3": "3.12.2",
+	"ansible": "2.16.4",
+	"terraform": "1.7.4",
+	"kubectl": "1.29.2",
+	"helm": "3.14.2",
+	"awscli": "2.15.27",
+	"azurecli": "2.58.0"
+}

From abb03480042521882871f3efdac51ab527cf9f7c Mon Sep 17 00:00:00 2001
From: Tung Bui <tung.bquang@gmail.com>
Date: Sat, 9 Mar 2024 15:34:54 +0700
Subject: [PATCH 9/9] core: add toolkit info.v1

---
 scripts/check_latest_version.py | 7 +++++++
 toolkit_info.json               | 4 ++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/scripts/check_latest_version.py b/scripts/check_latest_version.py
index d107965..81557b3 100644
--- a/scripts/check_latest_version.py
+++ b/scripts/check_latest_version.py
@@ -1,5 +1,6 @@
 import requests
 import re
+import json
 
 class VersionParser:
     def __init__(self):
@@ -94,6 +95,12 @@ def main():
         print("Summary:")
         print(versions)
 
+        ## TODO: implement auto workflow
+        # # Write version data to 'toolkit_info.json'
+        # with open('toolkit_info.json', 'w') as json_file:
+        #     json.dump(versions, json_file, indent=2)
+        # print("Version data written to 'toolkit_info.json'")
+
     except Exception as e:
         print(f"An error occurred: {e}")
 
diff --git a/toolkit_info.json b/toolkit_info.json
index 7dc29c5..b900f74 100644
--- a/toolkit_info.json
+++ b/toolkit_info.json
@@ -1,9 +1,9 @@
 {
-	"python3": "3.12.2",
+	"python3": "3.11.8",
 	"ansible": "2.16.4",
 	"terraform": "1.7.4",
 	"kubectl": "1.29.2",
 	"helm": "3.14.2",
-	"awscli": "2.15.27",
+	"awscli": "2.15.25",
 	"azurecli": "2.58.0"
 }
