Skip to content

Commit f3d3810

Browse files
alejandro.velezalejandro.velez
authored andcommitted
Fix Azure/GitHub template selection - v0.10.9
- Fixed 'unsupported operand type(s) for /: PosixPath and NoneType' error - Refactored template selection to return metadata without cloning - Updated setup methods to clone repositories with pre-selected templates - Improved error handling and user feedback
1 parent 948d2d2 commit f3d3810

3 files changed

Lines changed: 186 additions & 19 deletions

File tree

src/thothctl/commands/init/commands/project.py

Lines changed: 115 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import getpass
2+
import os
3+
import shutil
4+
import tempfile
25
from pathlib import Path
36
from typing import Optional, List, Any
47

@@ -170,7 +173,14 @@ def _select_azure_template(self, space: str, **kwargs) -> Optional[dict]:
170173
"""Select template from Azure Repos"""
171174
try:
172175
from ....utils.crypto import get_credentials_with_password, save_credentials
173-
from ....core.integrations.azure_devops.get_azure_devops import get_pattern_from_azure
176+
from ....core.integrations.azure_devops.get_azure_devops import (
177+
create_connection,
178+
get_repos_patterns,
179+
allowed_pattern_prefixes,
180+
allowed_pattern_suffixes
181+
)
182+
import inquirer
183+
from colorama import Fore
174184

175185
pat = None
176186
org_name = None
@@ -225,16 +235,66 @@ def _select_azure_template(self, space: str, **kwargs) -> Optional[dict]:
225235

226236
org_url = f"https://dev.azure.com/{org_name}/"
227237

228-
# Try to list templates
238+
# Get connection and list projects
229239
self.ui.print_info("🔍 Fetching available templates...")
230-
template_info = get_pattern_from_azure(
231-
pat=pat,
232-
org_url=org_url,
233-
directory="temp", # Dummy directory for listing
234-
action="list",
240+
conn = create_connection(personal_access_token=pat, organization_url=org_url)
241+
core_client = conn.clients.get_core_client()
242+
get_projects_response = core_client.get_projects()
243+
244+
projects = [project.name for project in get_projects_response]
245+
246+
if not projects:
247+
self.ui.print_error("No projects found in Azure DevOps organization")
248+
return None
249+
250+
# Ask user to select project
251+
questions = [
252+
inquirer.List(
253+
"project",
254+
message=f"{Fore.GREEN} What is the templates project?",
255+
choices=projects,
256+
),
257+
]
258+
tmp_project = inquirer.prompt(questions)
259+
project_name = tmp_project["project"]
260+
self.ui.print_success(f"✅ {project_name} was selected.")
261+
262+
# Get repositories from selected project
263+
git_client = conn.clients.get_git_client()
264+
repositories = get_repos_patterns(
265+
project_name=project_name,
266+
git_client=git_client,
267+
allowed_pattern_names=allowed_pattern_prefixes,
268+
allowed_pattern_names_end=allowed_pattern_suffixes,
235269
)
236270

237-
return template_info
271+
if not repositories:
272+
self.ui.print_error("No template repositories found")
273+
return None
274+
275+
# Ask user to select repository
276+
repository_names = [r["Name"] for r in repositories]
277+
questions = [
278+
inquirer.List(
279+
"repository",
280+
message=f"{Fore.GREEN} Select a pattern to reuse: {Fore.RESET} 🔍 ",
281+
choices=repository_names,
282+
),
283+
]
284+
tmp_repo = inquirer.prompt(questions)
285+
repository_name = tmp_repo["repository"]
286+
repository = [r for r in repositories if r["Name"] == repository_name][0]
287+
288+
self.ui.print_success(f"✅ Selected template: {repository_name}")
289+
290+
# Return repository metadata for later cloning
291+
return {
292+
"repo_name": repository["Name"],
293+
"repo_url": repository["RemoteUrl"],
294+
"pat": pat,
295+
"org_url": org_url,
296+
"project_name": project_name,
297+
}
238298

239299
except Exception as e:
240300
self.ui.print_error(f"Failed to select Azure template: {e}")
@@ -299,16 +359,57 @@ def _select_github_template(self, space: str, **kwargs) -> Optional[dict]:
299359
self.ui.print_error("GitHub username is required")
300360
return None
301361

302-
# Try to list templates
362+
# Get list of template repositories
303363
self.ui.print_info("🔍 Fetching available templates...")
304-
template_info = get_pattern_from_github(
305-
token=token, # Can be None for public repos
364+
365+
from ....core.integrations.github.get_github import (
366+
get_repos_patterns,
367+
allowed_pattern_prefixes,
368+
allowed_pattern_suffixes
369+
)
370+
import inquirer
371+
from colorama import Fore
372+
import requests
373+
374+
# Create session for GitHub API
375+
session = requests.Session()
376+
if token:
377+
session.headers.update({"Authorization": f"token {token}"})
378+
379+
# Get repositories matching patterns
380+
repositories = get_repos_patterns(
381+
session=session,
306382
username=username,
307-
directory="temp", # Dummy directory for listing
308-
action="list",
383+
allowed_pattern_prefixes=allowed_pattern_prefixes,
384+
allowed_pattern_suffixes=allowed_pattern_suffixes,
309385
)
310386

311-
return template_info
387+
if not repositories:
388+
self.ui.print_error("No template repositories found")
389+
return None
390+
391+
# Ask user to select repository
392+
repository_names = [r["Name"] for r in repositories]
393+
questions = [
394+
inquirer.List(
395+
"repository",
396+
message=f"{Fore.GREEN} Select a pattern to reuse: {Fore.RESET} 🔍 ",
397+
choices=repository_names,
398+
),
399+
]
400+
tmp_repo = inquirer.prompt(questions)
401+
repository_name = tmp_repo["repository"]
402+
repository = [r for r in repositories if r["Name"] == repository_name][0]
403+
404+
self.ui.print_success(f"✅ Selected template: {repository_name}")
405+
406+
# Return repository metadata for later cloning
407+
return {
408+
"repo_name": repository["Name"],
409+
"repo_url": repository["RemoteUrl"],
410+
"token": token,
411+
"username": username,
412+
}
312413

313414
except Exception as e:
314415
self.ui.print_error(f"Failed to select GitHub template: {e}")

src/thothctl/services/init/project/project.py

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,47 @@ def setup_azure_repos(
163163

164164
# Use selected template if provided, otherwise get template
165165
if selected_template:
166-
repo_meta = selected_template
166+
# Clone the pre-selected template to project directory
167+
import git
168+
from ....core.integrations.azure_devops.get_azure_devops import get_latest_tag_info
169+
170+
self.ui.print_info(f"📥 Cloning template: {selected_template['repo_name']}")
171+
172+
repo = git.Repo.clone_from(
173+
url=selected_template["repo_url"],
174+
to_path=str(project_path)
175+
)
176+
177+
# Get tag and commit info
178+
tag, sha = get_latest_tag_info(repo)
179+
180+
if tag:
181+
self.ui.print_success(f"✨ Latest tag: {tag}")
182+
else:
183+
self.ui.print_info("No tags found. Using main branch.")
184+
185+
# Clean up git metadata
186+
self.ui.print_info("🧹 Cleaning up metadata...")
187+
g_path = project_path / ".git"
188+
if g_path.exists():
189+
import shutil
190+
shutil.rmtree(g_path)
191+
git.Repo.init(path=str(project_path), mkdir=False)
192+
193+
# Create repo metadata
194+
repo_meta = {
195+
"repo_name": selected_template["repo_name"],
196+
"repo_url": selected_template["repo_url"],
197+
"commit": f"{sha}".replace('"', "'"),
198+
"tag": tag,
199+
}
167200
else:
168201
# Fallback to original behavior if no template was pre-selected
169202
org_url = f"{self.AZURE_DEVOPS_URL}/{az_org_name}/"
170203
repo_meta = get_pattern_from_azure(
171204
pat=pat,
172205
org_url=org_url,
173-
directory=project_name,
206+
directory=str(project_path),
174207
action="reuse",
175208
)
176209

@@ -285,13 +318,46 @@ def setup_github(
285318

286319
# Use selected template if provided, otherwise get template
287320
if selected_template:
288-
repo_meta = selected_template
321+
# Clone the pre-selected template to project directory
322+
import git
323+
from ....core.integrations.github.get_github import get_latest_tag_info
324+
325+
self.ui.print_info(f"📥 Cloning template: {selected_template['repo_name']}")
326+
327+
repo = git.Repo.clone_from(
328+
url=selected_template["repo_url"],
329+
to_path=str(project_path)
330+
)
331+
332+
# Get tag and commit info
333+
tag, sha = get_latest_tag_info(repo)
334+
335+
if tag:
336+
self.ui.print_success(f"✨ Latest tag: {tag}")
337+
else:
338+
self.ui.print_info("No tags found. Using main branch.")
339+
340+
# Clean up git metadata
341+
self.ui.print_info("🧹 Cleaning up metadata...")
342+
g_path = project_path / ".git"
343+
if g_path.exists():
344+
import shutil
345+
shutil.rmtree(g_path)
346+
git.Repo.init(path=str(project_path), mkdir=False)
347+
348+
# Create repo metadata
349+
repo_meta = {
350+
"repo_name": selected_template["repo_name"],
351+
"repo_url": selected_template["repo_url"],
352+
"commit": f"{sha}".replace('"', "'"),
353+
"tag": tag,
354+
}
289355
else:
290356
# Fallback to original behavior if no template was pre-selected
291357
repo_meta = get_pattern_from_github(
292358
token=token,
293359
username=github_username,
294-
directory=project_name,
360+
directory=str(project_path),
295361
action="reuse",
296362
)
297363

src/thothctl/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""Version module."""
2-
__version__ = "0.10.7"
2+
__version__ = "0.10.9"

0 commit comments

Comments
 (0)