-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgittycat.py
executable file
·176 lines (145 loc) · 6.37 KB
/
gittycat.py
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env python3
import os.path
import shutil
import sys
from datetime import datetime, timezone
from pathlib import Path
from git import Repo, GitCommandError
import argh
from argh import arg
from tqdm import tqdm
from cat import Cat
def _commit_changes(message: str, author='Gittycat <gittycat@example.com>'):
repo = Repo('.')
git = repo.git
try:
git.add('.gittycat/*')
except GitCommandError:
# Did not match any files
return
git.commit(message=message, author=author)
assert not repo.bare
def _has_changes_since(repo: Repo, timestamp: datetime) -> bool:
for commit in repo.iter_commits('HEAD'):
if commit.committed_datetime > timestamp:
return True
return False
@arg('name', type=str, help='Name of your new cat')
@arg('--personality', type=str, help='Personality of the cat to adopt')
def adopt(name: str, personality: str = 'default', **kwargs) -> None:
"""Adopts a cat into the Git Repository associated with the current working directory"""
try:
Path(os.path.join('.gittycat', 'cats')).mkdir(parents=True)
except FileExistsError:
raise FileExistsError(
".gittycat folder already exists for this repository! Delete the folder or use " +
"'gittycat release' to get rid of any remaining cats.")
cat = Cat.create_with_personality(name, personality)
cat.save()
print(f'Successfully adopted {cat.name}, your new best friend!')
cat.ascii_plot("adoption")
_commit_changes(f'Gittycat | Adopted new Cat "{cat.name}"')
@arg('name', type=str, help='Name of new cat')
def status(name: str) -> None:
"""
Gives back an overview of the current needs of your cat.
"""
cat = Cat.load(name)
repo = Repo('.')
print('==========')
print('Cat needs:')
print('==========')
meter_format = '{desc} |{bar}| ({n:06.2f}/{total:06.2f})'
with tqdm(total=cat.max_food, desc='Food ', file=sys.stdout, ncols=100, bar_format=meter_format) as bar:
bar.update(cat.food)
with tqdm(total=cat.max_food, desc='Energy ', file=sys.stdout, ncols=100, bar_format=meter_format) as bar:
bar.update(cat.energy)
with tqdm(total=cat.max_food, desc='Excitement', file=sys.stdout, ncols=100, bar_format=meter_format) as bar:
bar.update(cat.excitement)
print(f'Current evolution stage: {cat.get_evolution_stage()}')
print(f'Evolution: {cat.evolution:.2f} (Stage Thresholds: {cat.evolution_thresholds})')
if cat.food < 33:
cat.ascii_plot("bored")
print('Your cat is hungry! Feed it some commits!')
elif cat.excitement < 33:
cat.ascii_plot("bored")
print('Your cat is bored! Give it some new lines of code as a treat!')
elif cat.energy < 33:
cat.ascii_plot("tired")
print('Your cat is tired! Wait for its energy to recharge or let it take a nap!')
elif cat.excitement > 66:
cat.ascii_plot("excited")
print('Your cat is excited! It loves all the attention it\'s been getting!')
else:
cat.ascii_plot("normal")
print('Your cat is feeling normal.')
if _has_changes_since(repo, cat.last_update):
print('\nYou have unprocessed commits since the last time you used Gittycat!'
' Use "gittycat update" to process them.')
@arg('name', type=str, help='Name of new cat')
def update(name: str) -> None:
"""Processes any commits made since this command was last used and updates the cat's needs accordingly."""
cat = Cat.load(name)
repo = Repo('.')
# Get days since last update, including partial days
days_since_last_update = (datetime.now(timezone.utc) - cat.last_update).total_seconds() / 86400.0
# Update cat state based on time passed
new_evolution_reached: bool = cat.update_by_time_passed(days_since_last_update)
# Iterate through all commits since last update
print('Processing commits since last update...')
for commit in repo.iter_commits('HEAD'):
# Terminate once we reach a commit older than the last update
if commit.committed_datetime < cat.last_update:
break
# Exclude commits made by Gittycat itself
if 'Gittycat' in commit.author.name:
continue
# Process commit
print(f' Processing commit {commit.hexsha} by {commit.author.name} ({commit.message.strip()})')
# Every commit feeds the cat
cat.feed(1)
# Every file touched makes the cat more tired
cat.exhaust(len(commit.stats.files.keys()))
# Every line added to the repository make the cat more excited
cat.excite(commit.stats.total['insertions'])
print('Done!\n')
cat.last_update = datetime.now(timezone.utc)
cat.save()
_commit_changes(f'Gittycat | Updated my needs', f'{cat.name} (via Gittycat) <gittycat@example.com>')
if new_evolution_reached:
print(f'What?')
print(f'{cat.name} is evolving! They have now reached evolution stage {cat.get_evolution_stage()}!')
status(name)
@arg('name', type=str, help='Name of your new cat')
def pet(name: str) -> None:
"""
Pets your cat. Very important.
"""
cat = Cat.load(name)
cat.pet()
_commit_changes(f'Gittycat | I got some pets. Happy times!', f'{cat.name} (via Gittycat)')
print(f'You pet your cat {name}. It purrs happily.')
@arg('name', type=str, help='Name of your cat')
def nap(name: str) -> None:
"""
Lets your cat take a quick nap as a manual way to recover energy for those busy coding days
"""
cat = Cat.load(name)
cat.nap()
_commit_changes(f'Gittycat | I took a nap and recovered some energy', f'{cat.name} (via Gittycat)')
print(f'Time for {name} to take a nap and recover some energy! Zzzz...')
@arg('name', type=str, help='Name of your cat')
def release(**kwargs) -> None:
"""
Releases your cat into the wilds of the cloud. Use this command to remove Gittycat from your repository again.
"""
print('Releasing your cat into the wild!')
# plot the ascii
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ascii", "cat1", "0", "release.txt")
with open(path, 'r') as file:
content = file.read()
print(content)
shutil.rmtree('.gittycat', ignore_errors=True)
_commit_changes('Gittycat | Released all Cats and removed Gittycat from Repo')
if __name__ == '__main__':
argh.dispatch_commands([adopt, status, update, pet, nap, release])