-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathselect_orgs.py
More file actions
159 lines (127 loc) · 4.7 KB
/
select_orgs.py
File metadata and controls
159 lines (127 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python3
"""
Organization Selector - Interactive checkbox interface for selecting organizations
Creates/updates the exclude_orgs list in config.yaml
"""
import json
import subprocess
import sys
from pathlib import Path
import yaml
def display_banner():
"""Display the banner"""
banner_file = Path(__file__).parent / "banner"
if banner_file.exists():
with open(banner_file, 'r') as f:
print(f.read())
print()
def get_all_orgs():
"""Fetch all organizations using gh CLI"""
try:
result = subprocess.run(
['gh', 'api', 'user/orgs', '--paginate', '--jq', '.[].login'],
capture_output=True,
text=True,
check=True
)
orgs = [org.strip() for org in result.stdout.strip().split('\n') if org.strip()]
return sorted(orgs)
except subprocess.CalledProcessError as e:
print(f"Error fetching organizations: {e}")
sys.exit(1)
def load_config():
"""Load current config.yaml"""
config_file = Path(__file__).parent / "config.yaml"
if config_file.exists():
with open(config_file, 'r') as f:
return yaml.safe_load(f)
return {}
def save_config(config):
"""Save updated config.yaml"""
config_file = Path(__file__).parent / "config.yaml"
with open(config_file, 'w') as f:
yaml.dump(config, f, default_flow_style=False, sort_keys=False)
def interactive_select(orgs, excluded_orgs):
"""Interactive checkbox-style selection"""
# Create initial selection state (all checked except excluded)
selected = {org: org not in excluded_orgs for org in orgs}
print("=== Organization Selection ===")
print()
print("Instructions:")
print(" - All organizations are INCLUDED by default")
print(" - Enter the number to TOGGLE selection (uncheck to exclude)")
print(" - Enter 'done' when finished")
print(" - Enter 'all' to select all")
print(" - Enter 'none' to deselect all")
print()
while True:
# Display current state
print("\nOrganizations:")
print("-" * 60)
for idx, org in enumerate(orgs, 1):
checkbox = "[✓]" if selected[org] else "[ ]"
status = "INCLUDED" if selected[org] else "EXCLUDED"
print(f" {idx:2d}. {checkbox} {org:<30} ({status})")
print("-" * 60)
# Show summary
included_count = sum(1 for v in selected.values() if v)
excluded_count = len(selected) - included_count
print(f"\nSummary: {included_count} included, {excluded_count} excluded")
# Get user input
print()
choice = input("Enter number to toggle, or 'done/all/none': ").strip().lower()
if choice == 'done':
break
elif choice == 'all':
for org in orgs:
selected[org] = True
print("✓ All organizations selected")
elif choice == 'none':
for org in orgs:
selected[org] = False
print("✓ All organizations deselected")
elif choice.isdigit():
idx = int(choice)
if 1 <= idx <= len(orgs):
org = orgs[idx - 1]
selected[org] = not selected[org]
status = "INCLUDED" if selected[org] else "EXCLUDED"
print(f"✓ Toggled {org} → {status}")
else:
print(f"✗ Invalid number. Please enter 1-{len(orgs)}")
else:
print("✗ Invalid input. Enter a number, 'done', 'all', or 'none'")
# Return list of excluded orgs
return [org for org, is_selected in selected.items() if not is_selected]
def main():
display_banner()
print("Fetching your GitHub organizations...")
orgs = get_all_orgs()
if not orgs:
print("No organizations found.")
sys.exit(0)
print(f"Found {len(orgs)} organizations\n")
# Load current config
config = load_config()
current_excluded = config.get('filters', {}).get('exclude_orgs', [])
# Interactive selection
excluded_orgs = interactive_select(orgs, current_excluded)
# Update config
if 'filters' not in config:
config['filters'] = {}
config['filters']['exclude_orgs'] = excluded_orgs
# Save config
save_config(config)
print("\n" + "=" * 60)
print("✓ Configuration saved!")
print("=" * 60)
if excluded_orgs:
print(f"\nExcluded organizations ({len(excluded_orgs)}):")
for org in excluded_orgs:
print(f" - {org}")
else:
print("\nAll organizations will be included.")
print(f"\nIncluded organizations: {len(orgs) - len(excluded_orgs)}")
print("\nYou can now run: ./repo_mapper.sh")
if __name__ == "__main__":
main()