tfswitch 0.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tfswitch/__init__.py
ADDED
|
File without changes
|
tfswitch/cli.py
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import platform
|
|
3
|
+
import requests
|
|
4
|
+
import zipfile
|
|
5
|
+
import shutil
|
|
6
|
+
import subprocess
|
|
7
|
+
import urllib3
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from InquirerPy import inquirer
|
|
10
|
+
from packaging import version as pkg_version
|
|
11
|
+
|
|
12
|
+
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
13
|
+
|
|
14
|
+
TERRAFORM_DIR = Path.home() / ".terraform_versions"
|
|
15
|
+
TERRAFORM_BIN = Path.home() / ".terraform_bin" / "terraform"
|
|
16
|
+
USER_BIN = Path.home() / "bin" / "terraform"
|
|
17
|
+
|
|
18
|
+
def get_os_arch():
|
|
19
|
+
system = platform.system().lower()
|
|
20
|
+
arch = platform.machine().lower()
|
|
21
|
+
|
|
22
|
+
if system == "darwin":
|
|
23
|
+
system = "darwin"
|
|
24
|
+
elif system == "linux":
|
|
25
|
+
system = "linux"
|
|
26
|
+
else:
|
|
27
|
+
raise Exception(f"Unsupported system: {system}")
|
|
28
|
+
|
|
29
|
+
if arch in ("x86_64", "amd64"):
|
|
30
|
+
arch = "amd64"
|
|
31
|
+
elif arch in ("arm64", "aarch64"):
|
|
32
|
+
arch = "arm64"
|
|
33
|
+
else:
|
|
34
|
+
raise Exception(f"Unsupported arch: {arch}")
|
|
35
|
+
|
|
36
|
+
return system, arch
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def fetch_available_versions():
|
|
40
|
+
url = "https://releases.hashicorp.com/terraform/index.json"
|
|
41
|
+
r = requests.get(url, verify=False, timeout=10)
|
|
42
|
+
data = r.json()["versions"]
|
|
43
|
+
|
|
44
|
+
versions = []
|
|
45
|
+
for v in data.keys():
|
|
46
|
+
try:
|
|
47
|
+
pkg_version.parse(v)
|
|
48
|
+
if "beta" not in v and "rc" not in v:
|
|
49
|
+
versions.append(v)
|
|
50
|
+
except Exception:
|
|
51
|
+
continue
|
|
52
|
+
|
|
53
|
+
return sorted(versions, key=pkg_version.parse, reverse=True)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def download_terraform(version: str):
|
|
57
|
+
system, arch = get_os_arch()
|
|
58
|
+
url = f"https://releases.hashicorp.com/terraform/{version}/terraform_{version}_{system}_{arch}.zip"
|
|
59
|
+
print(f"⬇️ Downloading {url} ...")
|
|
60
|
+
|
|
61
|
+
r = requests.get(url, stream=True, verify=False, timeout=60)
|
|
62
|
+
if r.status_code != 200:
|
|
63
|
+
raise Exception(f"Terraform {version} not found!")
|
|
64
|
+
|
|
65
|
+
zip_path = TERRAFORM_DIR / f"terraform_{version}.zip"
|
|
66
|
+
TERRAFORM_DIR.mkdir(parents=True, exist_ok=True)
|
|
67
|
+
|
|
68
|
+
with open(zip_path, "wb") as f:
|
|
69
|
+
shutil.copyfileobj(r.raw, f)
|
|
70
|
+
|
|
71
|
+
extract_path = TERRAFORM_DIR / version
|
|
72
|
+
with zipfile.ZipFile(zip_path, "r") as zip_ref:
|
|
73
|
+
zip_ref.extractall(extract_path)
|
|
74
|
+
|
|
75
|
+
os.remove(zip_path)
|
|
76
|
+
|
|
77
|
+
terraform_bin = extract_path / "terraform"
|
|
78
|
+
terraform_bin.chmod(0o755)
|
|
79
|
+
|
|
80
|
+
print(f"✅ Terraform {version} installed at {extract_path}")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def update_symlinks(version: str):
|
|
84
|
+
bin_path = TERRAFORM_DIR / version / "terraform"
|
|
85
|
+
|
|
86
|
+
# ~/.terraform_bin/terraform
|
|
87
|
+
target_dir = TERRAFORM_BIN.parent
|
|
88
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
89
|
+
if TERRAFORM_BIN.exists() or TERRAFORM_BIN.is_symlink():
|
|
90
|
+
TERRAFORM_BIN.unlink()
|
|
91
|
+
TERRAFORM_BIN.symlink_to(bin_path)
|
|
92
|
+
|
|
93
|
+
# ~/bin/terraform
|
|
94
|
+
user_bin_dir = USER_BIN.parent
|
|
95
|
+
user_bin_dir.mkdir(parents=True, exist_ok=True)
|
|
96
|
+
if USER_BIN.exists() or USER_BIN.is_symlink():
|
|
97
|
+
USER_BIN.unlink()
|
|
98
|
+
USER_BIN.symlink_to(bin_path)
|
|
99
|
+
USER_BIN.chmod(0o755)
|
|
100
|
+
|
|
101
|
+
# ensure ~/bin is in PATH
|
|
102
|
+
shell_rc = Path.home() / (".zshrc" if os.environ.get("SHELL", "").endswith("zsh") else ".bashrc")
|
|
103
|
+
export_line = 'export PATH="$HOME/bin:$PATH"'
|
|
104
|
+
if not shell_rc.exists() or export_line not in shell_rc.read_text():
|
|
105
|
+
with open(shell_rc, "a") as f:
|
|
106
|
+
f.write(f"\n# Added by tfswitch\n{export_line}\n")
|
|
107
|
+
print(f"⚙️ Added ~/bin to PATH in {shell_rc}, restart your shell to apply.")
|
|
108
|
+
|
|
109
|
+
print(f"🔀 Switched to Terraform {version}")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def switch_terraform(version: str):
|
|
113
|
+
bin_path = TERRAFORM_DIR / version / "terraform"
|
|
114
|
+
if not bin_path.exists():
|
|
115
|
+
download_terraform(version)
|
|
116
|
+
|
|
117
|
+
update_symlinks(version)
|
|
118
|
+
|
|
119
|
+
# check version
|
|
120
|
+
try:
|
|
121
|
+
subprocess.run([str(USER_BIN), "-v"], check=False)
|
|
122
|
+
except Exception as e:
|
|
123
|
+
print(f"⚠️ Could not run terraform: {e}")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def main():
|
|
127
|
+
available = fetch_available_versions()
|
|
128
|
+
|
|
129
|
+
choice = inquirer.select(
|
|
130
|
+
message="Select Terraform version:",
|
|
131
|
+
choices=[{"name": v, "value": v} for v in available],
|
|
132
|
+
).execute()
|
|
133
|
+
|
|
134
|
+
switch_terraform(choice)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tfswitch
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Python CLI Utility to switch between various versions of Terraform seamlessly
|
|
5
|
+
Author: Chowdhury Faizal Ahammed
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Requires-Python: >=3.7
|
|
10
|
+
Requires-Dist: requests
|
|
11
|
+
Requires-Dist: InquirerPy
|
|
12
|
+
Requires-Dist: packaging
|
|
13
|
+
Requires-Dist: urllib3
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: classifier
|
|
16
|
+
Dynamic: requires-dist
|
|
17
|
+
Dynamic: requires-python
|
|
18
|
+
Dynamic: summary
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
tfswitch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
tfswitch/cli.py,sha256=zWt9Wojq04mpgK1mPKdtGAEZ9p1i0l5BMKk0XDvmc7w,3943
|
|
3
|
+
tfswitch-0.0.0.dist-info/METADATA,sha256=RXS9iBsNatZuqQYPMqjXvbHF26IUB7qGjd8mRGklTfA,540
|
|
4
|
+
tfswitch-0.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
+
tfswitch-0.0.0.dist-info/entry_points.txt,sha256=LLfUyLrJ7Vp3R-VnbxDrdARa8rceQcVqtjQj11z4UrI,47
|
|
6
|
+
tfswitch-0.0.0.dist-info/top_level.txt,sha256=MkGtbzM-dxJfrmYkc9M8GzYlhrFuzQSyBUVu8HWx0VU,9
|
|
7
|
+
tfswitch-0.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tfswitch
|