Compare commits
No commits in common. "8a6bb487552e267a224c50edfe2f1dd8f68ec2e9" and "80b70edcaafdb64a14711883aa3404976ff1686a" have entirely different histories.
8a6bb48755
...
80b70edcaa
@ -42,7 +42,6 @@
|
|||||||
"nvim-ts-context-commentstring": { "branch": "main", "commit": "1b212c2eee76d787bbea6aa5e92a2b534e7b4f8f" },
|
"nvim-ts-context-commentstring": { "branch": "main", "commit": "1b212c2eee76d787bbea6aa5e92a2b534e7b4f8f" },
|
||||||
"nvim-ufo": { "branch": "main", "commit": "61463090a4f55f5d080236ea62f09d1cd8976ff3" },
|
"nvim-ufo": { "branch": "main", "commit": "61463090a4f55f5d080236ea62f09d1cd8976ff3" },
|
||||||
"nvim-window-picker": { "branch": "main", "commit": "6382540b2ae5de6c793d4aa2e3fe6dbb518505ec" },
|
"nvim-window-picker": { "branch": "main", "commit": "6382540b2ae5de6c793d4aa2e3fe6dbb518505ec" },
|
||||||
"pendulum-nvim": { "branch": "main", "commit": "b884353d7c3e7a6fde477d8adcf0d0acf5ed077d" },
|
|
||||||
"plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" },
|
"plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" },
|
||||||
"promise-async": { "branch": "main", "commit": "38a4575da9497326badd3995e768b4ccf0bb153e" },
|
"promise-async": { "branch": "main", "commit": "38a4575da9497326badd3995e768b4ccf0bb153e" },
|
||||||
"resession.nvim": { "branch": "master", "commit": "cc819b0489938d03e4f3532a583354f0287c015b" },
|
"resession.nvim": { "branch": "master", "commit": "cc819b0489938d03e4f3532a583354f0287c015b" },
|
||||||
|
|||||||
@ -6,6 +6,6 @@
|
|||||||
return {
|
return {
|
||||||
"AstroNvim/astrocommunity",
|
"AstroNvim/astrocommunity",
|
||||||
{ import = "astrocommunity.pack.lua" },
|
{ import = "astrocommunity.pack.lua" },
|
||||||
{ import = "astrocommunity.completion.avante-nvim" },
|
-- { import = "astrocommunity.completion.avante-nvim" },
|
||||||
-- import/override with your plugins folder
|
-- import/override with your plugins folder
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
-- if true then return {} end -- WARN: REMOVE THIS LINE TO ACTIVATE THIS FILE
|
if true then return {} end -- WARN: REMOVE THIS LINE TO ACTIVATE THIS FILE
|
||||||
|
|
||||||
return {
|
return {
|
||||||
{ -- further customize the options set by the community
|
{ -- further customize the options set by the community
|
||||||
@ -13,7 +13,7 @@ return {
|
|||||||
endpoint = "https://api.deepseek.com",
|
endpoint = "https://api.deepseek.com",
|
||||||
model = "deepseek-coder",
|
model = "deepseek-coder",
|
||||||
max_tokens = 8192,
|
max_tokens = 8192,
|
||||||
-- disable_tools = true,
|
disable_tools = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Path to the branch_time_calculator.py script
|
|
||||||
CALCULATOR_PATH="$HOME/.config/nvim/lua/plugins/pendulum/branch_time_calculator.py"
|
|
||||||
|
|
||||||
# Check if the calculator script exists
|
|
||||||
if [ ! -f "$CALCULATOR_PATH" ]; then
|
|
||||||
echo "Error: The branch_time_calculator.py script was not found at $CALCULATOR_PATH."
|
|
||||||
echo "Please ensure the 'pendulum' plugin is installed in your Neovim configuration."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Execute the calculator script
|
|
||||||
python3 "$CALCULATOR_PATH" "$@"
|
|
||||||
@ -1,182 +0,0 @@
|
|||||||
import csv
|
|
||||||
import datetime
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
|
||||||
from typing import Optional, Dict, List
|
|
||||||
|
|
||||||
|
|
||||||
class BranchTimeCalculator:
|
|
||||||
"""
|
|
||||||
A class to calculate time spent on a Git branch with exact project matching.
|
|
||||||
Handles lowercase 'true' for active status and flexible CSV parsing.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, csv_file: Optional[str] = None, target_branch: Optional[str] = None, debug: bool = False):
|
|
||||||
"""
|
|
||||||
Initialize the calculator with optional CSV file, target branch and debug mode.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
csv_file (Optional[str]): Path to CSV log file. Defaults to ~/pendulum-log.csv.
|
|
||||||
target_branch (Optional[str]): Name of the target branch. Defaults to current branch.
|
|
||||||
debug (bool): If True, prints debug information. Defaults to False.
|
|
||||||
"""
|
|
||||||
self.csv_file = csv_file or os.path.expanduser("~/pendulum-log.csv")
|
|
||||||
self.target_branch = target_branch
|
|
||||||
self.debug = debug
|
|
||||||
self.current_project = self._get_project_name()
|
|
||||||
|
|
||||||
def _get_project_name(self) -> str:
|
|
||||||
"""
|
|
||||||
Get the project name from Git config or fall back to directory name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The project name.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return subprocess.check_output(
|
|
||||||
["git", "config", "--get", "remote.origin.url"],
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
text=True
|
|
||||||
).strip().split('/')[-1].replace('.git', '')
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
return os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
|
|
||||||
def _get_current_branch(self) -> Optional[str]:
|
|
||||||
"""
|
|
||||||
Get the current Git branch name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Optional[str]: The branch name or None if not in a Git repo.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return subprocess.check_output(
|
|
||||||
["git", "branch", "--show-current"],
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
text=True
|
|
||||||
).strip()
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
print("Error: Not a Git repository or branch not found.")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _parse_log_entry(self, row: List[str]) -> Dict[str, str]:
|
|
||||||
"""
|
|
||||||
Parse a CSV row into a log entry dictionary.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
row (List[str]): A row from the CSV log file.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict[str, str]: A dictionary representing the log entry.
|
|
||||||
"""
|
|
||||||
return {
|
|
||||||
'active': row[0].lower().strip(),
|
|
||||||
'branch': row[1].strip(),
|
|
||||||
'directory': row[2].strip(),
|
|
||||||
'file': row[3].strip(),
|
|
||||||
'filetype': row[4].strip(),
|
|
||||||
'project': row[5].strip(),
|
|
||||||
'time': row[6].strip()
|
|
||||||
}
|
|
||||||
|
|
||||||
def _calculate_time_deltas(self, log_entries: List[Dict[str, str]]) -> Dict[str, datetime.timedelta]:
|
|
||||||
"""
|
|
||||||
Calculate total and active time from log entries.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
log_entries (List[Dict[str, str]]): List of parsed log entries.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict[str, datetime.timedelta]: A dictionary with 'total_time' and 'active_time'.
|
|
||||||
"""
|
|
||||||
total_time = datetime.timedelta()
|
|
||||||
active_time = datetime.timedelta()
|
|
||||||
prev_time = None
|
|
||||||
|
|
||||||
for entry in log_entries:
|
|
||||||
try:
|
|
||||||
current_time = datetime.datetime.strptime(entry['time'], '%Y-%m-%d %H:%M:%S')
|
|
||||||
except ValueError as e:
|
|
||||||
print(f"[ERROR] Time parse failed: {entry['time']}. Error: {e}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if prev_time is not None:
|
|
||||||
time_diff = current_time - prev_time
|
|
||||||
total_time += time_diff
|
|
||||||
if entry['active'] == 'true':
|
|
||||||
active_time += time_diff
|
|
||||||
|
|
||||||
prev_time = current_time
|
|
||||||
|
|
||||||
return {'total_time': total_time, 'active_time': active_time}
|
|
||||||
|
|
||||||
def calculate(self) -> Optional[Dict[str, any]]:
|
|
||||||
"""
|
|
||||||
Calculate time spent on the target branch.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Optional[Dict[str, any]]: A dictionary with branch, project, total_time, active_time, and active_percentage.
|
|
||||||
Returns None if calculation fails.
|
|
||||||
"""
|
|
||||||
if self.target_branch is None:
|
|
||||||
self.target_branch = self._get_current_branch()
|
|
||||||
if self.target_branch is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
log_entries = []
|
|
||||||
try:
|
|
||||||
with open(self.csv_file, mode='r') as file:
|
|
||||||
for line in file:
|
|
||||||
row = list(csv.reader([line.strip()], delimiter=',', quotechar='"'))[0]
|
|
||||||
if len(row) != 7:
|
|
||||||
if self.debug:
|
|
||||||
print(f"[DEBUG] Skipping malformed line: {line}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
log_entry = self._parse_log_entry(row)
|
|
||||||
if log_entry['branch'] == self.target_branch and log_entry['project'] == self.current_project:
|
|
||||||
log_entries.append(log_entry)
|
|
||||||
|
|
||||||
except FileNotFoundError:
|
|
||||||
print(f"Error: Log file not found at {self.csv_file}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
time_deltas = self._calculate_time_deltas(log_entries)
|
|
||||||
total_seconds = time_deltas['total_time'].total_seconds()
|
|
||||||
active_percentage = (time_deltas['active_time'].total_seconds() / total_seconds) * 100 if total_seconds > 0 else 0
|
|
||||||
|
|
||||||
if self.debug:
|
|
||||||
print(f"\nTime spent on branch '{self.target_branch}' in project '{self.current_project}':")
|
|
||||||
print(f"- Total time: {time_deltas['total_time']}")
|
|
||||||
print(f"- Active time: {time_deltas['active_time']}")
|
|
||||||
print(f"- Active percentage: {active_percentage:.2f}%")
|
|
||||||
else:
|
|
||||||
print(f"In project '{self.current_project}' on branch '{self.target_branch}' you spent actively working: {time_deltas['active_time']}")
|
|
||||||
|
|
||||||
return {
|
|
||||||
'branch': self.target_branch,
|
|
||||||
'project': self.current_project,
|
|
||||||
'total_time': time_deltas['total_time'],
|
|
||||||
'active_time': time_deltas['active_time'],
|
|
||||||
'active_percentage': active_percentage
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Main function to parse arguments and run the calculator."""
|
|
||||||
parser = argparse.ArgumentParser(description='Calculate branch activity time.')
|
|
||||||
parser.add_argument('--csv-file', type=str, help='Path to CSV log (default: ~/pendulum-log.csv)')
|
|
||||||
parser.add_argument('--branch', type=str, help='Branch name (default: current)')
|
|
||||||
parser.add_argument('--debug', action='store_true', help='Enable debug output')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
calculator = BranchTimeCalculator(args.csv_file, args.branch, args.debug)
|
|
||||||
result = calculator.calculate()
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
print("\nCalculation failed - check debug output above.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
---@type LazySpec
|
|
||||||
return {
|
|
||||||
"ptdewey/pendulum-nvim",
|
|
||||||
version = "1.1.0",
|
|
||||||
config = function()
|
|
||||||
require("pendulum").setup {
|
|
||||||
time_zone = "Europe/Moscow",
|
|
||||||
gen_reports = false,
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user