"""Project operations for JIRA."""
import logging
from typing import Any, Dict, List
from jira.exceptions import JIRAError
from mcp_jira.client import JiraClient
logger = logging.getLogger(__name__)
class ProjectOperations:
"""Handles JIRA project operations."""
def __init__(self, client: JiraClient):
"""Initialize project operations.
Args:
client: JiraClient instance
"""
self.client = client
def list_projects(self) -> List[Dict[str, Any]]:
"""Get all accessible projects.
Returns:
List of projects
Raises:
JIRAError: If retrieval fails
"""
try:
jira = self.client.jira
logger.info("Listing all projects")
projects = jira.projects()
return [
{
"key": proj.key,
"id": proj.id,
"name": proj.name,
"project_type": proj.projectTypeKey if hasattr(proj, "projectTypeKey") else None,
"lead": proj.lead.displayName if hasattr(proj, "lead") else None,
}
for proj in projects
]
except JIRAError as e:
logger.error(f"Failed to list projects: {e}")
raise
def get_project(self, project_key: str) -> Dict[str, Any]:
"""Get project details.
Args:
project_key: Project key
Returns:
Project information
Raises:
JIRAError: If project not found
"""
try:
jira = self.client.jira
logger.info(f"Getting project {project_key}")
project = jira.project(project_key)
return {
"key": project.key,
"id": project.id,
"name": project.name,
"description": project.description if hasattr(project, "description") else None,
"project_type": project.projectTypeKey if hasattr(project, "projectTypeKey") else None,
"lead": project.lead.displayName if hasattr(project, "lead") else None,
}
except JIRAError as e:
logger.error(f"Failed to get project {project_key}: {e}")
raise
def get_issue_types(self, project_key: str) -> List[Dict[str, Any]]:
"""Get issue types for a project.
Args:
project_key: Project key
Returns:
List of issue types
Raises:
JIRAError: If retrieval fails
"""
try:
jira = self.client.jira
logger.info(f"Getting issue types for project {project_key}")
project = jira.project(project_key)
issue_types = project.issueTypes if hasattr(project, "issueTypes") else []
return [
{
"id": it.id,
"name": it.name,
"description": it.description if hasattr(it, "description") else None,
"subtask": it.subtask if hasattr(it, "subtask") else False,
}
for it in issue_types
]
except JIRAError as e:
logger.error(f"Failed to get issue types for {project_key}: {e}")
raise
def get_versions(self, project_key: str) -> List[Dict[str, Any]]:
"""Get versions for a project.
Args:
project_key: Project key
Returns:
List of versions
Raises:
JIRAError: If retrieval fails
"""
try:
jira = self.client.jira
logger.info(f"Getting versions for project {project_key}")
versions = jira.project_versions(project_key)
return [
{
"id": ver.id,
"name": ver.name,
"description": ver.description if hasattr(ver, "description") else None,
"released": ver.released if hasattr(ver, "released") else False,
"archived": ver.archived if hasattr(ver, "archived") else False,
}
for ver in versions
]
except JIRAError as e:
logger.error(f"Failed to get versions for {project_key}: {e}")
raise
def get_components(self, project_key: str) -> List[Dict[str, Any]]:
"""Get components for a project.
Args:
project_key: Project key
Returns:
List of components
Raises:
JIRAError: If retrieval fails
"""
try:
jira = self.client.jira
logger.info(f"Getting components for project {project_key}")
components = jira.project_components(project_key)
return [
{
"id": comp.id,
"name": comp.name,
"description": comp.description if hasattr(comp, "description") else None,
"lead": comp.lead.displayName if hasattr(comp, "lead") and comp.lead else None,
}
for comp in components
]
except JIRAError as e:
logger.error(f"Failed to get components for {project_key}: {e}")
raise