diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 2e3fd94b..35ab4572 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,25 +1,28 @@ --- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - +name: 🐞 Bug Report +about: Report a reproducible issue or unexpected behavior +title: "[BUG] " +labels: bug --- -**Describe the bug** -A clear and concise description of what the bug is. +## Description + -**To Reproduce** -Steps to reproduce the behavior: +## Steps to Reproduce 1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error +2. Click on '...' +3. See error + +## Expected Behavior + + +## Actual Behavior + -**Expected behavior** -A clear and concise description of what you expected to happen. +## Environment +- OS: [e.g. Linux, macOS, Windows] +- Compiler/Interpreter: [e.g. GCC 13, Python 3.12] +- Version/Commit: [e.g. v1.2.3 or commit SHA] -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Version [e.g. 22] +## Additional Context + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d..88604cf9 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,20 +1,21 @@ --- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - +name: ✨ Feature Request +about: Suggest a new feature or improvement +title: "[FEATURE] " +labels: enhancement --- -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] +## Summary + + +## Motivation + -**Describe the solution you'd like** -A clear and concise description of what you want to happen. +## Proposed Solution + -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. +## Alternatives Considered + -**Additional context** -Add any other context or screenshots about the feature request here. +## Additional Context + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/security.md b/.github/ISSUE_TEMPLATE/security.md new file mode 100644 index 00000000..1ac5f676 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/security.md @@ -0,0 +1,28 @@ +--- +name: πŸ”’ Security Issue +about: Report a potential security vulnerability or concern +title: "[SECURITY] " +labels: security +--- + +⚠️ **IMPORTANT: Do NOT share sensitive details in this public issue.** +This template is for alerting maintainers about a potential security problem **without disclosing exploit details**. + +## Summary + + +## Impact + + +## Next Steps +Maintainer(s) will review this issue and contact you to discuss details privately. +If you are comfortable, please share how we can reach you: + +- **Preferred Contact:** (GitHub handle, email, X/Facebook username, etc.) + +--- + +βœ… **Guidelines for Safe Reporting:** +- Do not share exploit code or detailed steps here. +- Do not share user data or private keys. +- Wait for maintainer response before disclosing further details. \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c44fc7c8..8b086451 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,18 +1,22 @@ -# Fossil Test - Pull Request +# πŸ›  Pull Request ## Description - + -## Testing - +## Related Issue(s) + + +## Changes Made +- [ ] Code cleanup +- [ ] Bug fix +- [ ] New feature +- [ ] Documentation update +- [ ] Other (explain below) ## Checklist -- [ ] Code follows the project's coding standards. -- [ ] Tests have been added or updated to cover the changes. -- [ ] Documentation has been updated to reflect the changes. -- [ ] The code has been reviewed by team members. -- [ ] All checks and tests pass. -- [ ] The license header and notices are updated where necessary. +- [ ] Code builds and passes tests +- [ ] No breaking changes introduced +- [ ] Documentation updated if necessary -## License -This project is licensed under the Mozilla Public License - see the [LICENSE](LICENSE) file for details. +## Additional Notes + \ No newline at end of file diff --git a/.github/ciimage/Dockerfile.alpine b/.github/ciimage/Dockerfile.alpine deleted file mode 100644 index de82664c..00000000 --- a/.github/ciimage/Dockerfile.alpine +++ /dev/null @@ -1,32 +0,0 @@ -# Use a specific Alpine base image -FROM alpine:3.21 - -# Set environment variables to avoid interaction -ENV TZ=UTC \ - CC=clang \ - CXX=clang++ \ - LD_LIBRARY_PATH=/usr/local/lib - -# Install system dependencies -RUN apk add --no-cache \ - bash \ - build-base \ - clang \ - gdb \ - llvm \ - libstdc++ \ - python3 \ - py3-pip \ - git \ - wget \ - ca-certificates \ - tzdata \ - && python3 -m ensurepip \ - && pip3 install --no-cache-dir --upgrade pip \ - && pip3 install --no-cache-dir meson==1.3.0 ninja==1.10.2 - -# Set working directory -WORKDIR /workspace - -# Default command -CMD ["bash"] \ No newline at end of file diff --git a/.github/ciimage/Dockerfile.opensuse b/.github/ciimage/Dockerfile.opensuse deleted file mode 100644 index 7ea3c88b..00000000 --- a/.github/ciimage/Dockerfile.opensuse +++ /dev/null @@ -1,38 +0,0 @@ -# Use a specific openSUSE base image -FROM opensuse/leap:15.5 - -# Set environment variables to avoid interaction -ENV TZ=UTC \ - CC=clang \ - CXX=clang++ \ - LD_LIBRARY_PATH=/usr/local/lib \ - ZYPPER_ASSUME_YES=1 \ - DEBIAN_FRONTEND=noninteractive - -# Install system dependencies -RUN zypper refresh && \ - zypper install -y \ - bash \ - gcc \ - gcc-c++ \ - clang \ - gdb \ - llvm \ - libstdc++-devel \ - python3 \ - python3-pip \ - git \ - wget \ - ca-certificates \ - && zypper clean --all - -# Upgrade pip and install Meson + Ninja -RUN python3 -m ensurepip && \ - python3 -m pip install --no-cache-dir --upgrade pip && \ - python3 -m pip install --no-cache-dir meson==1.3.0 ninja==1.10.2 - -# Set working directory -WORKDIR /workspace - -# Default command -CMD ["bash"] \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..be6dc138 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,19 @@ +# Security Policy + +I take security seriously at Fossil Logic. + +## Reporting a Vulnerability + +If you find a potential vulnerability: + +1. **Do not disclose details publicly.** +2. Open a [πŸ”’ Security Issue](https://github.com/fossillogic/fossil-test/issues/new?template=security.md) and provide a high-level summary. +3. Optionally include your contact information so maintainers can follow up privately. + +Maintainers will respond as soon as possible to gather details safely and coordinate a fix. + +## Disclosure Policy + +We ask researchers and users to: +- Give us time to investigate and patch before sharing details publicly. +- Work with us in good faith to ensure users are not put at risk. \ No newline at end of file diff --git a/code/tests/meson.build b/code/tests/meson.build index 2aac0350..f3bc31f8 100644 --- a/code/tests/meson.build +++ b/code/tests/meson.build @@ -1,5 +1,5 @@ if get_option('with_test').enabled() - run_command(['python3', 'tools' / 'generate-runner.py'], check: true) + run_command(['python3', 'tools' / 'runner.py'], check: true) cards = run_command(['python3', 'tools' / 'wildcard.py'], check: true) test_cases = ['unit_runner.c', cards.stdout().strip().split('\n')] @@ -7,4 +7,4 @@ if get_option('with_test').enabled() pizza_c = executable('pizza', test_cases, include_directories: dir, dependencies: [fossil_test_dep]) test('fossil testing C', pizza_c) -endif \ No newline at end of file +endif diff --git a/code/tests/tools/generate-note.py b/code/tests/tools/generate-note.py deleted file mode 100644 index f79164b9..00000000 --- a/code/tests/tools/generate-note.py +++ /dev/null @@ -1,129 +0,0 @@ -import argparse -import requests -import os -from datetime import datetime - -GITHUB_API = "https://api.github.com" - -def fetch_milestone_issues(owner, repo, milestone_title, token=None): - headers = {"Authorization": f"token {token}"} if token else {} - - # Find milestone ID - milestone_url = f"{GITHUB_API}/repos/{owner}/{repo}/milestones" - milestone_resp = requests.get(milestone_url, headers=headers).json() - milestone_id = next((m['number'] for m in milestone_resp if m['title'] == milestone_title), None) - if milestone_id is None: - raise ValueError(f"Milestone '{milestone_title}' not found.") - - # Fetch issues - issues_url = f"{GITHUB_API}/repos/{owner}/{repo}/issues" - issues = [] - page = 1 - while True: - params = { - "milestone": milestone_id, - "state": "closed", - "per_page": 100, - "page": page - } - page_issues = requests.get(issues_url, headers=headers, params=params).json() - if not page_issues: - break - issues.extend(page_issues) - page += 1 - - return issues - -def group_issues_by_label(issues): - grouped = {"feature": [], "bug": [], "enhancement": [], "other": []} - for issue in issues: - labels = [label["name"] for label in issue["labels"]] - added = False - for key in grouped: - if key in labels: - grouped[key].append(issue) - added = True - break - if not added: - grouped["other"].append(issue) - return grouped - -def fetch_repo_description(owner, repo, token=None): - headers = {"Authorization": f"token {token}"} if token else {} - url = f"{GITHUB_API}/repos/{owner}/{repo}" - resp = requests.get(url, headers=headers).json() - return resp.get("description", "") - -def generate_markdown(milestone, grouped_issues, repo_description=""): - today = datetime.today().strftime("%Y-%m-%d") - output = [f"# πŸ“¦ Release Notes for `{milestone}`", f"_Date: {today}_"] - - if repo_description: - output.append(f"\n> {repo_description}\n") - - output.append(f"\n## [{milestone}] – {today}") - - if grouped_issues["feature"]: - output.append("\n### πŸš€ Features") - for issue in grouped_issues["feature"]: - output.append(f"- {issue['title']} (#{issue['number']})") - - if grouped_issues["bug"]: - output.append("\n### 🐞 Bug Fixes") - for issue in grouped_issues["bug"]: - output.append(f"- {issue['title']} (#{issue['number']})") - - if grouped_issues["enhancement"]: - output.append("\n### πŸ›  Enhancements") - for issue in grouped_issues["enhancement"]: - output.append(f"- {issue['title']} (#{issue['number']})") - - if grouped_issues["other"]: - output.append("\n### πŸ“¦ Other") - for issue in grouped_issues["other"]: - output.append(f"- {issue['title']} (#{issue['number']})") - - # 🧩 WrapDB Git Definition - output.append("\n### 🧩 WrapDB Git Definition") - output.append("```ini") - output.append("# ======================") - output.append("# Git Wrap package definition") - output.append("# ======================") - output.append("[wrap-git]") - output.append("url = https://github.com/fossillogic/fossil-test.git") - output.append(f"revision = v{milestone}") - output.append("") - output.append("[provide]") - output.append("fossil-test = fossil_test_dep") - output.append("```") - - return "\n".join(output) - -def save_to_file(content, filename): - with open(filename, "a") as f: - f.write("\n\n" + content.strip() + "\n") - -def main(): - parser = argparse.ArgumentParser(description="Pizza Changelog and Release Note Generator") - parser.add_argument("--owner", required=True, help="GitHub repository owner") - parser.add_argument("--repo", required=True, help="GitHub repository name") - parser.add_argument("--milestone", required=True, help="Milestone title") - parser.add_argument("--token", help="GitHub personal access token (optional)") - parser.add_argument("--out", default="CHANGELOG.md", help="Output changelog file") - parser.add_argument("--release-file", action="store_true", help="Also save to release_notes_.md") - args = parser.parse_args() - - issues = fetch_milestone_issues(args.owner, args.repo, args.milestone, args.token) - grouped = group_issues_by_label(issues) - markdown = generate_markdown(args.milestone, grouped, fetch_repo_description(args.owner, args.repo, args.token)) - - save_to_file(markdown, args.out) - print(f"βœ… Changelog updated: {args.out}") - - if args.release_file: - rel_file = f"release_notes_{args.milestone.replace('.', '_')}.md" - save_to_file(markdown, rel_file) - print(f"πŸ“ Release note saved: {rel_file}") - -if __name__ == "__main__": - main() diff --git a/code/tests/tools/generate-runner.py b/code/tests/tools/runner.py similarity index 100% rename from code/tests/tools/generate-runner.py rename to code/tests/tools/runner.py diff --git a/code/tests/tools/scan-code.py b/code/tests/tools/scan-code.py deleted file mode 100644 index baf83d32..00000000 --- a/code/tests/tools/scan-code.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import re -import argparse - -# ANSI color codes -CYAN = '\033[96m' -BLUE = '\033[94m' -YELLOW = '\033[93m' -RED = '\033[91m' -RESET = '\033[0m' - -def check_format_issues(filepath): - issues = [] - - # Pattern: enforce * next to variable name, e.g., "int* ptr", not "int * ptr" - pointer_pattern = re.compile( - r'\b(?:const\s+|volatile\s+|restrict\s+)?' - r'(?:unsigned\s+|signed\s+)?' - r'(?:int|char|float|double|void|size_t|ptrdiff_t|uint\d+_t|int\d+_t)\s+\*\s+\w+' - ) - - with open(filepath, 'r', encoding='utf-8', errors='ignore') as file: - for lineno, line in enumerate(file, start=1): - if '\t' in line: - issues.append((lineno, 'Tab character found', 'warning')) - if 'goto' in line: - issues.append((lineno, 'Usage of "goto" is not allowed', 'error')) - if pointer_pattern.search(line): - issues.append((lineno, 'Pointer symbol (*) should be adjacent to variable name (e.g., `int* ptr`)', 'error')) - if line.strip().startswith('//') and len(line.strip()) > 80: - issues.append((lineno, 'Comment exceeds 80 characters', 'warning')) - if line.strip().endswith(';') and line.strip() == ';': - issues.append((lineno, 'Empty statement found', 'warning')) - return issues - -def scan_directory_for_issues(directory): - issue_report = {} - for root, _, files in os.walk(directory): - for file in files: - if file.endswith(('.c', '.cpp', '.h', '.hpp')): - full_path = os.path.join(root, file) - issues = check_format_issues(full_path) - if issues: - issue_report[full_path] = issues - return issue_report - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description="Check C/C++ files for formatting issues.") - parser.add_argument('directory', help="Directory to scan for source files.") - args = parser.parse_args() - - report = scan_directory_for_issues(args.directory) - for filepath, issues in report.items(): - print(f"\n{BLUE}{filepath}:{RESET}") - for lineno, message, severity in issues: - color = RED if severity == 'error' else YELLOW - print(f" {CYAN}Line {lineno}:{RESET} {color}{message}{RESET}") diff --git a/code/tests/tools/scan-todos.py b/code/tests/tools/scan-todos.py deleted file mode 100644 index 14071b8c..00000000 --- a/code/tests/tools/scan-todos.py +++ /dev/null @@ -1,40 +0,0 @@ -import os -import re -import argparse - -# ANSI escape codes for colors -BLUE = '\033[94m' -CYAN = '\033[96m' -RESET = '\033[0m' - -def find_keywords_in_file(filepath): - keyword_pattern = re.compile(r'//\s*(TODO|FIX|NODE)[:\s]*(.*)', re.IGNORECASE) - items = set() - with open(filepath, 'r', encoding='utf-8', errors='ignore') as file: - for line in file: - match = keyword_pattern.search(line) - if match: - keyword = match.group(1).upper() - text = match.group(2).strip() - if text: - items.add(f"{keyword}: {text}") - return items - -def find_keywords_in_directory(directory): - all_items = set() - for root, _, files in os.walk(directory): - for file in files: - if file.endswith(('.c', '.cpp', '.h', '.hpp')): - full_path = os.path.join(root, file) - all_items.update(find_keywords_in_file(full_path)) - return all_items - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description="Extract unique TODOs, FIXes, and NODEs from C/C++ files.") - parser.add_argument('directory', help="Directory to scan for source files.") - args = parser.parse_args() - - items = find_keywords_in_directory(args.directory) - print(f"{BLUE}Extracted Items:{RESET}") - for item in sorted(items): - print(f"{CYAN}- [ ] {item}{RESET}") diff --git a/meson.build b/meson.build index d7231a5e..4ab9d12f 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,8 @@ project('Fossil Test', 'c', 'cpp', default_options: [ 'c_std=c11,c18', 'cpp_std=c++20', - 'buildtype=release' + 'buildtype=release', + 'default_library=static' ] )