roastbuddy 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,201 @@
1
+ """Git utilities for analyzing repositories."""
2
+
3
+ import os
4
+ from pathlib import Path
5
+ from typing import Optional, Dict, Any, List
6
+ from datetime import datetime
7
+ from git import Repo, InvalidGitRepositoryError, GitCommandError
8
+
9
+
10
+ def find_git_repo(path: str = ".") -> Optional[Repo]:
11
+ """Find and return a git repository."""
12
+ try:
13
+ repo = Repo(path, search_parent_directories=True)
14
+ return repo
15
+ except InvalidGitRepositoryError:
16
+ return None
17
+
18
+
19
+ def get_repo_path(repo: Optional[Repo] = None) -> str:
20
+ """Get the absolute path of a git repository."""
21
+ if repo is None:
22
+ repo = find_git_repo()
23
+
24
+ if repo:
25
+ return str(Path(repo.working_dir).resolve())
26
+ return str(Path.cwd().resolve())
27
+
28
+
29
+ def is_clean_commit_message(message: str) -> bool:
30
+ """Determine if a commit message is 'clean' (descriptive)."""
31
+ message_lower = message.strip().lower()
32
+
33
+ # Too short
34
+ if len(message_lower) < 10:
35
+ return False
36
+
37
+ # Common WIP indicators (stricter matching)
38
+ wip_indicators = [
39
+ "wip", "fixup", "tmp", "temp", "asdf", "qwer",
40
+ "fuck", "shit", "damn", "wtf", "lol",
41
+ ]
42
+
43
+ # Check for whole word matches or at word boundaries
44
+ for indicator in wip_indicators:
45
+ if indicator == message_lower or f" {indicator} " in f" {message_lower} ":
46
+ return False
47
+
48
+ # Bad patterns
49
+ bad_patterns = ["fixed stuff", "fix stuff", "did stuff", "stuff", "things"]
50
+ if any(pattern == message_lower or f" {pattern} " in f" {message_lower} " for pattern in bad_patterns):
51
+ return False
52
+
53
+ # Single word commits (except meaningful ones)
54
+ meaningful_singles = ["initial", "refactor", "merge", "rebase", "release"]
55
+ if " " not in message_lower and message_lower not in meaningful_singles:
56
+ return False
57
+
58
+ return True
59
+
60
+
61
+ def get_last_commit(repo: Optional[Repo] = None) -> Optional[Dict[str, Any]]:
62
+ """Get information about the last commit."""
63
+ if repo is None:
64
+ repo = find_git_repo()
65
+
66
+ if not repo or not repo.head.is_valid():
67
+ return None
68
+
69
+ try:
70
+ commit = repo.head.commit
71
+
72
+ # Get diff stats
73
+ stats = commit.stats.total
74
+
75
+ return {
76
+ "hash": commit.hexsha,
77
+ "short_hash": commit.hexsha[:7],
78
+ "message": commit.message.strip(),
79
+ "author": commit.author.name,
80
+ "email": commit.author.email,
81
+ "timestamp": datetime.fromtimestamp(commit.committed_date).isoformat(),
82
+ "files_changed": stats.get("files", 0),
83
+ "lines_added": stats.get("insertions", 0),
84
+ "lines_deleted": stats.get("deletions", 0),
85
+ "is_clean": is_clean_commit_message(commit.message),
86
+ "repo_path": get_repo_path(repo),
87
+ }
88
+ except Exception as e:
89
+ print(f"Error getting last commit: {e}")
90
+ return None
91
+
92
+
93
+ def get_recent_commits(repo: Optional[Repo] = None, count: int = 10) -> List[Dict[str, Any]]:
94
+ """Get recent commits."""
95
+ if repo is None:
96
+ repo = find_git_repo()
97
+
98
+ if not repo or not repo.head.is_valid():
99
+ return []
100
+
101
+ commits = []
102
+ try:
103
+ for commit in repo.iter_commits(max_count=count):
104
+ stats = commit.stats.total
105
+ commits.append({
106
+ "hash": commit.hexsha,
107
+ "short_hash": commit.hexsha[:7],
108
+ "message": commit.message.strip(),
109
+ "author": commit.author.name,
110
+ "email": commit.author.email,
111
+ "timestamp": datetime.fromtimestamp(commit.committed_date).isoformat(),
112
+ "files_changed": stats.get("files", 0),
113
+ "lines_added": stats.get("insertions", 0),
114
+ "lines_deleted": stats.get("deletions", 0),
115
+ "is_clean": is_clean_commit_message(commit.message),
116
+ "repo_path": get_repo_path(repo),
117
+ })
118
+ except Exception as e:
119
+ print(f"Error getting recent commits: {e}")
120
+
121
+ return commits
122
+
123
+
124
+ def get_diff_stats(repo: Optional[Repo] = None) -> Dict[str, Any]:
125
+ """Get current diff statistics (unstaged changes)."""
126
+ if repo is None:
127
+ repo = find_git_repo()
128
+
129
+ if not repo:
130
+ return {"files_changed": 0, "lines_added": 0, "lines_deleted": 0}
131
+
132
+ try:
133
+ # Get diff between HEAD and working directory
134
+ diff_index = repo.head.commit.diff(None, create_patch=True)
135
+
136
+ files_changed = len(diff_index)
137
+ lines_added = 0
138
+ lines_deleted = 0
139
+
140
+ for diff_item in diff_index:
141
+ if diff_item.diff:
142
+ diff_text = diff_item.diff.decode("utf-8", errors="ignore")
143
+ for line in diff_text.split("\n"):
144
+ if line.startswith("+") and not line.startswith("+++"):
145
+ lines_added += 1
146
+ elif line.startswith("-") and not line.startswith("---"):
147
+ lines_deleted += 1
148
+
149
+ return {
150
+ "files_changed": files_changed,
151
+ "lines_added": lines_added,
152
+ "lines_deleted": lines_deleted,
153
+ }
154
+ except Exception as e:
155
+ print(f"Error getting diff stats: {e}")
156
+ return {"files_changed": 0, "lines_added": 0, "lines_deleted": 0}
157
+
158
+
159
+ def analyze_commit_patterns(repo: Optional[Repo] = None, days: int = 30) -> Dict[str, Any]:
160
+ """Analyze commit patterns over time."""
161
+ if repo is None:
162
+ repo = find_git_repo()
163
+
164
+ if not repo or not repo.head.is_valid():
165
+ return {
166
+ "total_commits": 0,
167
+ "clean_commits": 0,
168
+ "avg_files_per_commit": 0,
169
+ "avg_lines_per_commit": 0,
170
+ }
171
+
172
+ try:
173
+ commits = get_recent_commits(repo, count=100)
174
+
175
+ if not commits:
176
+ return {
177
+ "total_commits": 0,
178
+ "clean_commits": 0,
179
+ "avg_files_per_commit": 0,
180
+ "avg_lines_per_commit": 0,
181
+ }
182
+
183
+ clean_count = sum(1 for c in commits if c["is_clean"])
184
+ total_files = sum(c["files_changed"] for c in commits)
185
+ total_lines = sum(c["lines_added"] + c["lines_deleted"] for c in commits)
186
+
187
+ return {
188
+ "total_commits": len(commits),
189
+ "clean_commits": clean_count,
190
+ "clean_ratio": clean_count / len(commits) if commits else 0,
191
+ "avg_files_per_commit": total_files / len(commits) if commits else 0,
192
+ "avg_lines_per_commit": total_lines / len(commits) if commits else 0,
193
+ }
194
+ except Exception as e:
195
+ print(f"Error analyzing commit patterns: {e}")
196
+ return {
197
+ "total_commits": 0,
198
+ "clean_commits": 0,
199
+ "avg_files_per_commit": 0,
200
+ "avg_lines_per_commit": 0,
201
+ }
@@ -0,0 +1,303 @@
1
+ Metadata-Version: 2.4
2
+ Name: roastbuddy
3
+ Version: 0.1.0
4
+ Summary: A fun, interactive CLI companion that roasts and praises your code
5
+ Author: RoastBuddy Team
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/roastbuddy/roastbuddy
8
+ Project-URL: Repository, https://github.com/roastbuddy/roastbuddy
9
+ Project-URL: Issues, https://github.com/roastbuddy/roastbuddy/issues
10
+ Keywords: cli,git,developer-tools,fun,roast,coding-companion
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Requires-Python: >=3.8
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: click>=8.1.0
24
+ Requires-Dist: gitpython>=3.1.0
25
+ Requires-Dist: pyyaml>=6.0
26
+ Requires-Dist: rich>=13.0.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
29
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
30
+ Requires-Dist: black>=23.0.0; extra == "dev"
31
+ Requires-Dist: flake8>=6.0.0; extra == "dev"
32
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # ๐Ÿ”ฅ RoastBuddy
36
+
37
+ **Your witty coding companion that roasts, praises, and tracks your development journey!**
38
+
39
+ RoastBuddy is a fun, interactive CLI tool that observes your git activity and gives you humorous roasts and genuine praise. It tracks your coding streaks, monitors code quality, and helps you generate shareable brag content for social media.
40
+
41
+ ## โœจ Features
42
+
43
+ - ๐ŸŽญ **Smart Roasts & Praise**: Context-aware commentary on your commits using GitHub Copilot CLI or built-in templates
44
+ - ๐Ÿ”ฅ **Streak Tracking**: Monitor clean commits, daily coding habits, and test pass rates *(coming soon)*
45
+ - ๐Ÿ“Š **Code Quality Insights**: Track your coding trends and improvements over time
46
+ - ๐ŸŽจ **Beautiful CLI**: Rich, colorful terminal output with emojis and ASCII art
47
+ - ๐Ÿ“œ **History Tracking**: View all your past roasts and praises
48
+ - โš™๏ธ **Configurable**: Customize roast intensity, AI usage, and more
49
+ - ๐Ÿš€ **Shareable Content**: Generate LinkedIn, Twitter, and GitHub-ready summaries *(coming soon)*
50
+ - ๐Ÿช **Git Hooks**: Optional auto-roast on every commit *(coming soon)*
51
+ - ๐Ÿ”’ **Privacy First**: All data stays local, no telemetry
52
+
53
+ ## ๐Ÿš€ Quick Start
54
+
55
+ ### Installation
56
+
57
+ ```bash
58
+ # Clone the repository
59
+ git clone https://github.com/yourusername/roastbuddy.git
60
+ cd roastbuddy
61
+
62
+ # Install in development mode
63
+ python3 -m venv venv
64
+ source venv/bin/activate # On Windows: venv\Scripts\activate
65
+ pip install -e .
66
+ ```
67
+
68
+ ### Initialize in Your Repository
69
+
70
+ ```bash
71
+ cd your-project
72
+ roastbuddy init
73
+ ```
74
+
75
+ ### Get Your First Roast!
76
+
77
+ ```bash
78
+ # Make a commit first
79
+ git commit -m "your commit message"
80
+
81
+ # Then get roasted!
82
+ roastbuddy roast
83
+
84
+ # Or get some praise
85
+ roastbuddy praise
86
+
87
+ # Check your stats
88
+ roastbuddy status
89
+
90
+ # View history
91
+ roastbuddy history
92
+ ```
93
+
94
+ ## ๐Ÿ“– Commands
95
+
96
+ ### `roastbuddy init`
97
+ Initialize RoastBuddy in a git repository. Creates configuration and database files.
98
+
99
+ ```bash
100
+ roastbuddy init
101
+ ```
102
+
103
+ ### `roastbuddy roast`
104
+ Get a witty roast based on your last commit!
105
+
106
+ ```bash
107
+ roastbuddy roast
108
+ ```
109
+
110
+ Example output:
111
+ ```
112
+ ๐Ÿ”ฅ Your Roast
113
+
114
+ ๐Ÿ™„ 'fixed stuff' - ah yes, the ancient art of commit message poetry.
115
+ Shakespeare would be proud... NOT! Try being specific next time. ๐Ÿ“
116
+ ```
117
+
118
+ ### `roastbuddy praise`
119
+ Receive well-deserved praise for your work!
120
+
121
+ ```bash
122
+ roastbuddy praise
123
+ ```
124
+
125
+ Example output:
126
+ ```
127
+ โœจ Your Praise
128
+
129
+ โœจ Beautiful commit! Clear message, focused changes, and just the right size.
130
+ You're a git wizard! ๐Ÿง™โ€โ™‚๏ธ
131
+ ```
132
+
133
+ ### `roastbuddy status`
134
+ View repository statistics and activity summary.
135
+
136
+ ```bash
137
+ roastbuddy status
138
+ ```
139
+
140
+ Shows:
141
+ - Last commit information
142
+ - Total commits analyzed
143
+ - Clean commit ratio
144
+ - Average files and lines per commit
145
+ - GitHub Copilot availability
146
+
147
+ ### `roastbuddy history`
148
+ View your roast and praise history.
149
+
150
+ ```bash
151
+ roastbuddy history --limit 20
152
+ ```
153
+
154
+ ### `roastbuddy config`
155
+ Manage RoastBuddy configuration.
156
+
157
+ ```bash
158
+ # Show current configuration
159
+ roastbuddy config --show
160
+
161
+ # Set a configuration value
162
+ roastbuddy config --set roast_intensity spicy
163
+ roastbuddy config --set use_copilot never
164
+ ```
165
+
166
+ Configuration options:
167
+ - `roast_intensity`: `light`, `medium`, or `spicy`
168
+ - `use_copilot`: `auto`, `always`, or `never`
169
+ - `enable_streaks`: `true` or `false`
170
+ - `show_emojis`: `true` or `false`
171
+ - `auto_roast_on_commit`: `true` or `false` *(git hooks, coming soon)*
172
+
173
+ ## ๐Ÿค– GitHub Copilot Integration
174
+
175
+ RoastBuddy works with or without GitHub Copilot CLI:
176
+
177
+ - **With Copilot**: Get dynamic, AI-powered roasts and praise tailored to your specific commits
178
+ - **Without Copilot**: Use built-in template system with dozens of witty responses
179
+
180
+ ### Installing GitHub Copilot CLI (Optional)
181
+
182
+ 1. Install GitHub CLI: https://cli.github.com/
183
+ 2. Install Copilot extension:
184
+ ```bash
185
+ gh extension install github/gh-copilot
186
+ ```
187
+
188
+ RoastBuddy will automatically detect and use Copilot when available!
189
+
190
+ ## ๐ŸŽฏ What Makes a "Clean" Commit?
191
+
192
+ RoastBuddy evaluates commits based on:
193
+
194
+ โœ… **Good Commits:**
195
+ - Descriptive message (>10 characters)
196
+ - Reasonable size (<200 lines)
197
+ - Focused changes (โ‰ค5 files)
198
+ - Clear intent and purpose
199
+
200
+ โŒ **Roast-worthy Commits:**
201
+ - Vague messages ("fix", "update", "stuff")
202
+ - WIP indicators in message
203
+ - Massive changes (>500 lines)
204
+ - Too many files changed (>15)
205
+
206
+ ## ๐Ÿ“Š Example Session
207
+
208
+ ```bash
209
+ $ roastbuddy init
210
+ ๐Ÿ”ฅ Initializing RoastBuddy...
211
+ โœ… RoastBuddy is ready to roast!
212
+
213
+ $ git commit -m "wip"
214
+ [main 1a2b3c4] wip
215
+ 1 file changed, 2 insertions(+)
216
+
217
+ $ roastbuddy roast
218
+ ๐Ÿ”ฅ Your Roast
219
+
220
+ ๐ŸŽญ 'WIP' - Working In Progress? More like 'Why Is Perfection'
221
+ so hard to achieve! Clean up that message! โœจ
222
+
223
+ $ git commit -m "Implement user authentication with JWT tokens and refresh logic"
224
+ [main 5d6e7f8] Implement user authentication...
225
+
226
+ $ roastbuddy praise
227
+ โœจ Your Praise
228
+
229
+ โœจ Beautiful commit! Clear message, focused changes, and just the
230
+ right size. You're a git wizard! ๐Ÿง™โ€โ™‚๏ธ
231
+
232
+ $ roastbuddy status
233
+ ๐Ÿ“Š Repository Status
234
+
235
+ Last Commit: 5d6e7f8 - Implement user authentication with JWT...
236
+ Files: 3 | Lines: +145 -12
237
+
238
+ Statistics (last 10 commits):
239
+ Total Commits 10
240
+ Clean Commits 7 (70%)
241
+ Avg Files/Commit 3.2
242
+ Avg Lines/Commit 87
243
+ GitHub Copilot โœ… Available
244
+ ```
245
+
246
+ ## ๐Ÿงช Running Tests
247
+
248
+ ```bash
249
+ # Install development dependencies
250
+ pip install -r requirements-dev.txt
251
+
252
+ # Run tests
253
+ pytest
254
+
255
+ # Run with coverage
256
+ pytest --cov=roastbuddy
257
+ ```
258
+
259
+ ## ๐Ÿ“‹ Requirements
260
+
261
+ - Python 3.8+
262
+ - Git repository
263
+ - (Optional) GitHub Copilot CLI for AI-powered roasts
264
+
265
+ ## ๐Ÿ›ฃ๏ธ Roadmap
266
+
267
+ - โœ… Phase 1: Core CLI and configuration
268
+ - โœ… Phase 2: Git integration and analysis
269
+ - โœ… Phase 3: Copilot CLI integration
270
+ - โœ… Phase 4: Fallback template system
271
+ - ๐Ÿšง Phase 5: Streak tracking
272
+ - ๐Ÿšง Phase 6: Git hooks integration
273
+ - ๐Ÿšง Phase 7: Shareable social media content
274
+ - ๐Ÿšง Phase 8: Extended testing and polish
275
+ - ๐Ÿšง Phase 9: PyPI package distribution
276
+
277
+ ## ๐Ÿค Contributing
278
+
279
+ Contributions welcome! Please feel free to submit a Pull Request.
280
+
281
+ ### Development Setup
282
+
283
+ ```bash
284
+ git clone https://github.com/yourusername/roastbuddy.git
285
+ cd roastbuddy
286
+ python3 -m venv venv
287
+ source venv/bin/activate
288
+ pip install -e ".[dev]"
289
+ ```
290
+
291
+ ## ๐Ÿ“œ License
292
+
293
+ MIT License - See LICENSE file for details
294
+
295
+ ## ๐ŸŽ‰ Credits
296
+
297
+ Built with love, Python, and a healthy dose of sarcasm by developers who believe coding should be fun!
298
+
299
+ ---
300
+
301
+ **Made with โค๏ธ and a healthy dose of sarcasm**
302
+
303
+ *Remember: RoastBuddy roasts your code, not you! All feedback is meant to be fun and educational.* ๐Ÿ˜Š
@@ -0,0 +1,24 @@
1
+ roastbuddy/__init__.py,sha256=OX3iGicNpVFWhThnrGV85IH7VbEC25ks94hA5xgUblE,189
2
+ roastbuddy/cli.py,sha256=OVh1WPmt9Y-hjkq6llihqMYesvD7ZWccXaoh0GpOxWA,3488
3
+ roastbuddy/core/__init__.py,sha256=yBro9-GBG_VNNWjb7uTIzYNdBkv-f3uTcweXGacbO4Q,54
4
+ roastbuddy/core/config.py,sha256=qPpUL9sQwwOOA3OBep3hwS68QjmlTiCs9O_vw2X7DDI,2589
5
+ roastbuddy/core/database.py,sha256=_jSVmpKAmqhyl716J5AqorPWY6HwjCy3qTqSzFlHQA8,5724
6
+ roastbuddy/core/history.py,sha256=H7yHxag-EM4q1Nj1Lntu3v1Qy-DRs05aEB38BPiz4Kg,1538
7
+ roastbuddy/core/initializer.py,sha256=lmRgFv1mpY_YsUHFmP4ZQzJpNZa9ur4E5uv_8KBiny8,2191
8
+ roastbuddy/core/roaster.py,sha256=HTBULWLabXUTL9DVrJRssAW3HpaVbzOBR1x62AUq8yc,4721
9
+ roastbuddy/core/share.py,sha256=N7Z-4v2olEk_MRCRN72K0QQpdluj6cRnQ8GQqjBU3zA,567
10
+ roastbuddy/core/status.py,sha256=2dse6Xlc0ELqpIx8yJN_hbF5uznlKtKR7hkAMQkW-zk,2252
11
+ roastbuddy/core/streaks.py,sha256=kM3gUDs2HfId9PwSCaseibK109E5ALzpowOTbI5rAUA,636
12
+ roastbuddy/templates/__init__.py,sha256=KxRP-tqE-YftEZvBzy4aPV2ZTbER-SchfgAieGU9-No,64
13
+ roastbuddy/templates/praise_templates.py,sha256=2qvauHJMrJAQaFE2BnamdwkJfxfFOUNp3gjwK3JIdHY,4891
14
+ roastbuddy/templates/roast_templates.py,sha256=dV7w1nM8U8ac-huTxSRQotInaWHSoXmpxfAc6THRjuU,4288
15
+ roastbuddy/utils/__init__.py,sha256=C5B3Wjo8hu8lfNzvGwd1L-mTH7CdDFngi9s4APsoY_U,56
16
+ roastbuddy/utils/code_analysis.py,sha256=0aCDwOoowHo8jj4N_j9I7lkJCK393g3l4Kx4IYjBLRc,5420
17
+ roastbuddy/utils/copilot_utils.py,sha256=AvM_u5Q4ktI0UE-rvOduIyZJdZJP80pbTnIICf1N8Vc,3874
18
+ roastbuddy/utils/git_utils.py,sha256=z_UYQOrfc6sg9EJS2TQszZi0i1apEcqjUKBQwBjrJwc,6851
19
+ roastbuddy-0.1.0.dist-info/licenses/LICENSE,sha256=3H3Ije4ZHtEx9kQF6IvEj76QqMEz4l4QmopbPvSLRVM,1072
20
+ roastbuddy-0.1.0.dist-info/METADATA,sha256=cMIRWbcyazpBEwTiR5k7fW3b5KPo2bkoV37lz0cdnFo,7770
21
+ roastbuddy-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
22
+ roastbuddy-0.1.0.dist-info/entry_points.txt,sha256=QRjgz55rq4SctJMJVJYfTSce1xNoMIwqxlEkut2b4-g,51
23
+ roastbuddy-0.1.0.dist-info/top_level.txt,sha256=A2ayGwnGgCUnsiEkEkfm4AdR6PgNHW29AYRjFBg5fcU,11
24
+ roastbuddy-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ roastbuddy = roastbuddy.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 RoastBuddy Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ roastbuddy