Skip to content
6 changes: 3 additions & 3 deletions penify_hook/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ def generate_commit_summary(self, git_diff, instruction: str = "", repo_details

Args:
git_diff (str): The git diff of the commit.
instruction (str??): Additional instruction for the commit. Defaults to "".
repo_details (dict??): Details of the git repository. Defaults to None.
jira_context (dict??): JIRA issue details to enhance the commit summary. Defaults to None.
instruction (str?): Additional instruction for the commit. Defaults to "".
repo_details (dict?): Details of the git repository. Defaults to None.
jira_context (dict?): JIRA issue details to enhance the commit summary. Defaults to None.

Returns:
dict: The response from the API if the request is successful, None otherwise.
Expand Down
9 changes: 8 additions & 1 deletion penify_hook/commands/auth_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ def save_credentials(api_key):
"""Save or update the API keys in the .penify file in the user's home
directory.

This function checks if the .penify file exists in the user's home
directory. If it does, it loads the existing credentials and updates the
API key. If the file does not exist, it creates a new file with the
provided API key. The function attempts to write the updated credentials
back to the file and returns a boolean indicating whether the operation
was successful.

Args:
api_key (str): The new API key to be saved or updated.

Returns:
bool: if the credentials were successfully saved, False otherwise.
bool: True if the credentials were successfully saved, False otherwise.
"""
home_dir = Path.home()
penify_file = home_dir / '.penify'
Expand Down
16 changes: 9 additions & 7 deletions penify_hook/commands/commit_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ def setup_commit_parser(parser):
This function sets up an argument parser that can be used to generate
commit messages with contextual information. It allows users to specify
options such as including a message, opening an edit terminal before
committing, and generating a detailed commit message.
committing, and generating a detailed commit message. The parser is
configured to provide helpful descriptions and usage information for
each argument.

Args:
parser (argparse.ArgumentParser): The ArgumentParser object to be configured.
Expand All @@ -127,12 +129,12 @@ def setup_commit_parser(parser):

def handle_commit(args):
"""Handle the commit functionality by processing arguments and invoking the
appropriate commands.

This function processes the provided command-line arguments to configure
settings for commit operations, including LLM (Language Model) and Jira
configurations. It then calls the `commit_code` function with these
configurations to perform the actual commit operation.
appropriate commands. This function processes the provided command-line
arguments to configure settings for commit operations, including
Language Model (LLM) and Jira configurations. It retrieves the necessary
configurations from the respective commands and then calls the
`commit_code` function with these configurations to perform the actual
commit operation.

Args:
args (argparse.Namespace): The parsed command-line arguments containing options like terminal,
Expand Down
58 changes: 40 additions & 18 deletions penify_hook/commands/config_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ def get_penify_config() -> Path:

This function searches for the `.penify` file in the current directory
and its parent directories until it finds it or reaches the home
directory. If not found, it creates the `.penify` directory and an empty
`config.json` file.
directory. If the `.penify` directory does not exist, it creates the
directory and an empty `config.json` file within it. This is useful for
applications that require a configuration file to store user-specific
settings.

Returns:
Path: The path to the `config.json` file within the `.penify` directory.
Expand Down Expand Up @@ -95,7 +97,9 @@ def save_jira_config(url, username, api_token):

This function reads existing JIRA configuration from the .penify file,
updates or adds new JIRA configuration details, and writes it back to
the file.
the file. It handles the case where the .penify file may not exist or
may contain invalid JSON. If the configuration is successfully saved, it
returns True; otherwise, it returns False.

Args:
url (str): The URL of the JIRA instance.
Expand Down Expand Up @@ -139,7 +143,8 @@ def get_llm_config():

This function reads the .penify configuration file and extracts the LLM
settings. If the file does not exist or contains invalid JSON, it
returns an empty dictionary.
returns an empty dictionary. The function handles potential errors that
may arise during the reading and parsing of the configuration file.

Returns:
dict: A dictionary containing the LLM configuration, or an empty dictionary if
Expand All @@ -160,9 +165,11 @@ def get_jira_config():
"""Get JIRA configuration from the .penify file.

This function reads the JIRA configuration from a JSON file specified in
the .penify file. If the .penify file exists and contains valid JSON
with a 'jira' key, it returns the corresponding configuration.
Otherwise, it returns an empty dictionary.
the .penify file. It checks for the existence of the .penify file and
attempts to load its contents. If the file contains valid JSON and has a
'jira' key, the function returns the corresponding configuration. If the
file does not exist, is invalid, or does not contain the 'jira' key, it
returns an empty dictionary.

Returns:
dict: The JIRA configuration or an empty dictionary if not found or invalid.
Expand All @@ -184,7 +191,7 @@ def config_llm_web():
This function starts a temporary HTTP server that serves an HTML
template for configuring Large Language Model (LLM) settings. It handles
GET and POST requests to retrieve the current configuration, save new
configurations, and suppress log messages. The server runs on a random
configurations, and suppress log messages. The server runs on a random
port between 30000 and 50000, and it is accessible via a URL like
http://localhost:<redirect_port>. The function opens this URL in the
default web browser for configuration. Once configured, the server shuts
Expand Down Expand Up @@ -252,10 +259,11 @@ def do_POST(self):
This method processes incoming POST requests to save language model
configuration data. It extracts the necessary parameters from the
request body, saves the configuration using the provided details, and
then schedules the server to shut down after a successful save.
then schedules the server to shut down after a successful save. If the
request path is not "/save", it responds with a 404 error.

Args:
self (HTTPRequestHandler): The instance of the HTTPRequestHandler class handling the request.
self (HTTPRequestHandler): The instance of the HTTPRequestHandler
"""

if self.path == "/save":
Expand Down Expand Up @@ -315,7 +323,11 @@ def config_jira_web():
`http.server` module to handle GET and POST requests. The server serves
an HTML page for configuration and handles saving the JIRA configuration
details through API tokens and URLs. Upon successful configuration, it
shuts down the server gracefully.
shuts down the server gracefully. The GET requests are processed to
serve the configuration HTML page or return the current JIRA
configuration in JSON format. The POST requests are used to save the
configuration details provided by the user. If an error occurs during
the saving process, a 500 Internal Server Error response is returned.
"""
redirect_port = random.randint(30000, 50000)
server_url = f"http://localhost:{redirect_port}"
Expand All @@ -326,10 +338,12 @@ class ConfigHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
"""Handle GET requests for different paths.

This function processes GET requests based on the path requested. It
serves an HTML template for the root path, returns a JSON configuration
for a specific endpoint, and handles any other paths by returning a 404
error.
This function processes GET requests based on the requested path. It
serves an HTML template for the root path ("/"), returns a JSON
configuration for the "/get_config" endpoint, and handles any other
paths by returning a 404 error. The function reads the HTML template
from the specified resource and retrieves the current JIRA configuration
when requested.
"""

if self.path == "/":
Expand Down Expand Up @@ -380,7 +394,8 @@ def do_POST(self):
parameters (URL, username, API token, and verify), saves the
configuration using the `save_jira_config` function, and responds with
success or error messages. If an exception occurs during the process, it
sends a 500 Internal Server Error response.
sends a 500 Internal Server Error response. If the request path is not
recognized, it sends a 404 Not Found response.
"""

if self.path == "/save":
Expand Down Expand Up @@ -437,8 +452,15 @@ def log_message(self, format, *args):
print("Configuration completed.")

def get_token():
"""Get the token based on priority from environment variables or
configuration files.
"""Retrieve the API token from environment variables or configuration
files.

This function checks for the presence of an API token in the environment
variable 'PENIFY_API_TOKEN'. If it is not found, the function attempts
to read the token from a configuration file located at '~/.penify'. If
the configuration file exists and is successfully read, the function
extracts the token from the JSON content. If any errors occur during
file reading or JSON decoding, an error message is printed.

Returns:
str: The API token if found, otherwise None.
Expand Down
11 changes: 7 additions & 4 deletions penify_hook/commands/doc_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def generate_doc(api_url, token, location=None):
Args:
api_url (str): The URL of the API to connect to for documentation generation.
token (str): The authentication token for accessing the API.
location (str?): The path to a specific file or folder to analyze. If not provided, the
current working directory is used.
location (str?): The path to a specific file or folder to analyze.
If not provided, the current working directory is used.
"""

import os
Expand Down Expand Up @@ -86,7 +86,8 @@ def setup_docgen_parser(parser):
This function configures a parser with various subcommands and arguments
necessary for generating documentation for Git diffs, files, or folders.
It also installs and uninstalls commit hooks to automate documentation
generation on commits.
generation on commits. The parser will provide options for specifying
locations for documentation generation and for managing Git hooks.

Args:
parser (argparse.ArgumentParser): The parser to configure.
Expand Down Expand Up @@ -127,7 +128,9 @@ def handle_docgen(args):

This function processes different subcommands such as installing or
uninstalling git hooks, and directly generating documentation based on
provided arguments.
provided arguments. It first retrieves an authentication token and
checks if the token is valid. Depending on the specified subcommand, it
either installs or uninstalls a git hook or generates documentation.

Args:
args (Namespace): Parsed command-line arguments containing the subcommand and location
Expand Down
11 changes: 8 additions & 3 deletions penify_hook/commands/hook_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@
"""

def install_git_hook(location, token):
"""Install a post-commit hook in the specified location that generates
documentation
for changed files after each commit.
"""Install a post-commit hook in a Git repository to generate
documentation.

This function sets up a post-commit hook in the specified Git repository
location. The hook is designed to automatically generate documentation
for any files that have changed after each commit. It ensures that the
hooks directory exists before attempting to create the hook file and
makes the hook executable.

Args:
location (str): The path to the Git repository where the hook should be installed.
Expand Down
7 changes: 5 additions & 2 deletions penify_hook/config_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,16 @@ def handle_config(args):

This function processes different types of configurations such as LLM
(Language Model) and JIRA. It saves configurations, sets up web-based
configurations, and verifies JIRA connections.
configurations, and verifies JIRA connections based on the provided
command-line arguments. The function ensures that the appropriate
configuration is applied and provides feedback on the success or failure
of the operations performed.

Args:
args (argparse.Namespace): Command-line arguments containing the type of configuration to handle.

Returns:
int: Exit code indicating success or failure.
int: Exit code indicating success (0) or failure (1).
"""

# Only import dependencies needed for config functionality here
Expand Down
3 changes: 2 additions & 1 deletion penify_hook/file_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ def process_file(self, file_path, pbar):
This function validates the provided file extension, reads the content
of the file, and sends it to an API client for further processing. If
the API responds successfully, the original file content is replaced
with the response.
with the response. The function also updates a progress bar to reflect
the current processing stage.

Args:
file_path (str): The relative path to the file that needs to be processed.
Expand Down
46 changes: 30 additions & 16 deletions penify_hook/jira_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ def is_connected(self) -> bool:
"""Check if the JIRA client is connected.

This function verifies whether the JIRA client has successfully
established a connection. It returns `True` if the client is connected,
and `False` otherwise.
established a connection. It checks the state of the `jira_client`
attribute and returns `True` if the client is connected, and `False`
otherwise.

Returns:
bool: True if the JIRA client is connected, False otherwise
bool: True if the JIRA client is connected, False otherwise.
"""
return self.jira_client is not None

Expand Down Expand Up @@ -167,6 +168,13 @@ def add_comment(self, issue_key: str, comment: str) -> bool:
def update_issue_status(self, issue_key: str, transition_name: str) -> bool:
"""Update the status of a JIRA issue.

This function updates the status of a specified JIRA issue by performing
a transition based on the provided transition name. It first checks if
the JIRA client is connected, retrieves the available transitions for
the issue, and then attempts to find and execute the specified
transition. If successful, it logs the update; otherwise, it logs a
warning or an error if an exception occurs.

Args:
issue_key (str): The key of the JIRA issue to be updated.
transition_name (str): The name of the desired transition.
Expand Down Expand Up @@ -204,16 +212,24 @@ def update_issue_status(self, issue_key: str, transition_name: str) -> bool:
def format_commit_message_with_jira_info(self, commit_title: str, commit_description: str, issue_keys: List[str] = None) -> tuple:
"""Format commit message with JIRA issue information.

This function formats a commit message by incorporating relevant JIRA
issue information. It takes the original commit title and description,
and if no issue keys are provided, it extracts them from both the title
and description. If the system is connected to JIRA and valid issue keys
are found, it updates the commit title to include the first issue key
and appends a section to the description with details about the related
JIRA issues.

Args:
commit_title (str): The original commit title.
commit_description (str): The original commit description.
issue_keys (List[str]?): A list of JIRA issue keys to include in the commit message. If not
provided, issue keys will be extracted from both the title and the
description.
issue_keys (List[str]?): A list of JIRA issue keys to include in
the commit message. If not provided, issue keys will be extracted from
both the title and the description.

Returns:
tuple: A tuple containing the updated commit title and description with JIRA
information included.
tuple: A tuple containing the updated commit title and description with
JIRA information included.
"""
# If no issue keys provided, extract them from title and description
if not issue_keys:
Expand Down Expand Up @@ -253,14 +269,12 @@ def format_commit_message_with_jira_info(self, commit_title: str, commit_descrip

def get_detailed_issue_context(self, issue_key: str) -> Dict[str, Any]:
"""Retrieve comprehensive details about a JIRA issue including context for
better commit messages.

This function fetches detailed information from a specified JIRA issue
and constructs a dictionary containing various context fields such as
the issue summary, description, type, status, priority, comments, URL,
and additional custom fields like acceptance criteria and sprint
information. If any errors occur during the fetching process,
appropriate warnings or errors are logged.
better commit messages. This function fetches detailed information from
a specified JIRA issue and constructs a dictionary containing various
context fields such as the issue summary, description, type, status,
priority, comments, URL, and additional custom fields like acceptance
criteria and sprint information. If any errors occur during the fetching
process, appropriate warnings or errors are logged.

Args:
issue_key (str): The JIRA issue key (e.g., "PROJECT-123").
Expand Down
Loading