Skip to content

Commit 7fe07ab

Browse files
authored
Merge pull request #66 from P4X-ng/Q-DEV-issue-60-1765732036
Python round 2
2 parents f9c9764 + d2c0cbb commit 7fe07ab

27 files changed

+1567
-511
lines changed

.github/workflows/auto-copilot-functionality-docs-review.yml

Lines changed: 104 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,31 @@ jobs:
153153
echo "" >> /tmp/doc-analysis.md
154154
echo "### Additional Documentation:" >> /tmp/doc-analysis.md
155155
156-
# Find all markdown files
157-
find . -name "*.md" \
156+
# Find markdown files (limit to first 20 to avoid excessive output)
157+
md_files=$(find . -name "*.md" \
158158
! -path "*/node_modules/*" \
159159
! -path "*/.venv/*" \
160160
! -path "*/vendor/*" \
161-
-type f | while read -r file; do
162-
echo "- $file" >> /tmp/doc-analysis.md
163-
done || echo "No additional markdown files found" >> /tmp/doc-analysis.md
161+
-type f | head -20)
162+
163+
if [ -n "$md_files" ]; then
164+
echo "$md_files" | while read -r file; do
165+
echo "- $file" >> /tmp/doc-analysis.md
166+
done
167+
168+
# Count total markdown files
169+
total_md=$(find . -name "*.md" \
170+
! -path "*/node_modules/*" \
171+
! -path "*/.venv/*" \
172+
! -path "*/vendor/*" \
173+
-type f | wc -l)
174+
175+
if [ "$total_md" -gt 20 ]; then
176+
echo "- ... and $((total_md - 20)) more markdown files" >> /tmp/doc-analysis.md
177+
fi
178+
else
179+
echo "No additional markdown files found" >> /tmp/doc-analysis.md
180+
fi
164181
165182
echo "" >> /tmp/doc-analysis.md
166183
echo "### Code with Missing Documentation:" >> /tmp/doc-analysis.md
@@ -176,14 +193,22 @@ jobs:
176193
! -path "*/dist/*" \
177194
! -name "__init__.py" \
178195
-type f | while read -r file; do
179-
# Count functions and classes
196+
# Count functions and classes with proper error handling
180197
func_count=$(grep -c "^def " "$file" 2>/dev/null || echo 0)
181198
class_count=$(grep -c "^class " "$file" 2>/dev/null || echo 0)
182199
docstring_count=$(grep -c '"""' "$file" 2>/dev/null || echo 0)
183200
184-
total=$((func_count + class_count))
185-
if [ $total -gt 0 ] && [ $docstring_count -eq 0 ]; then
186-
echo "⚠️ $file: $total definitions, no docstrings" >> /tmp/doc-analysis.md
201+
# Sanitize variables to ensure they contain only integers
202+
func_count=$(echo "$func_count" | tr -d '\n\r' | grep -E '^[0-9]+$' || echo 0)
203+
class_count=$(echo "$class_count" | tr -d '\n\r' | grep -E '^[0-9]+$' || echo 0)
204+
docstring_count=$(echo "$docstring_count" | tr -d '\n\r' | grep -E '^[0-9]+$' || echo 0)
205+
206+
# Ensure variables are valid integers before arithmetic
207+
if [ "$func_count" -eq "$func_count" ] 2>/dev/null && [ "$class_count" -eq "$class_count" ] 2>/dev/null; then
208+
total=$((func_count + class_count))
209+
if [ $total -gt 0 ] && [ "$docstring_count" -eq "$docstring_count" ] 2>/dev/null && [ $docstring_count -eq 0 ]; then
210+
echo "⚠️ $file: $total definitions, no docstrings" >> /tmp/doc-analysis.md
211+
fi
187212
fi
188213
done
189214
fi
@@ -197,14 +222,22 @@ jobs:
197222
! -path "*/dist/*" \
198223
! -path "*/build/*" \
199224
-type f | while read -r file; do
200-
# Count functions and classes
225+
# Count functions and classes with proper error handling
201226
func_count=$(grep -cE "(^function |^export function |^const .* = .*=>)" "$file" 2>/dev/null || echo 0)
202227
class_count=$(grep -c "^class " "$file" 2>/dev/null || echo 0)
203228
jsdoc_count=$(grep -c '/\*\*' "$file" 2>/dev/null || echo 0)
204229
205-
total=$((func_count + class_count))
206-
if [ $total -gt 5 ] && [ $jsdoc_count -eq 0 ]; then
207-
echo "⚠️ $file: ~$total definitions, no JSDoc comments" >> /tmp/doc-analysis.md
230+
# Sanitize variables to ensure they contain only integers
231+
func_count=$(echo "$func_count" | tr -d '\n\r' | grep -E '^[0-9]+$' || echo 0)
232+
class_count=$(echo "$class_count" | tr -d '\n\r' | grep -E '^[0-9]+$' || echo 0)
233+
jsdoc_count=$(echo "$jsdoc_count" | tr -d '\n\r' | grep -E '^[0-9]+$' || echo 0)
234+
235+
# Ensure variables are valid integers before arithmetic
236+
if [ "$func_count" -eq "$func_count" ] 2>/dev/null && [ "$class_count" -eq "$class_count" ] 2>/dev/null; then
237+
total=$((func_count + class_count))
238+
if [ $total -gt 5 ] && [ "$jsdoc_count" -eq "$jsdoc_count" ] 2>/dev/null && [ $jsdoc_count -eq 0 ]; then
239+
echo "⚠️ $file: ~$total definitions, no JSDoc comments" >> /tmp/doc-analysis.md
240+
fi
208241
fi
209242
done
210243
fi
@@ -220,7 +253,7 @@ jobs:
220253
github-token: ${{ secrets.GITHUB_TOKEN }}
221254
script: |
222255
const fs = require('fs');
223-
const analysis = fs.readFileSync('/tmp/doc-analysis.md', 'utf8');
256+
let analysis = fs.readFileSync('/tmp/doc-analysis.md', 'utf8');
224257
225258
const date = new Date().toISOString().split('T')[0];
226259
const title = `Code Functionality & Documentation Review - ${date}`;
@@ -229,6 +262,12 @@ jobs:
229262
const buildEmoji = buildStatus === 'success' ? '✅' :
230263
buildStatus === 'failed' ? '❌' : '⚠️';
231264
265+
// Truncate analysis if it's too long to prevent GitHub API errors
266+
const maxAnalysisLength = 40000; // Leave room for the rest of the content
267+
if (analysis.length > maxAnalysisLength) {
268+
analysis = analysis.substring(0, maxAnalysisLength) + '\n\n... (output truncated due to length)';
269+
}
270+
232271
const body = `# Code Functionality and Documentation Review
233272
234273
## Build Status: ${buildEmoji} ${buildStatus}
@@ -268,6 +307,14 @@ jobs:
268307
*This issue was automatically generated by the Functionality & Documentation Review workflow.*
269308
`;
270309
310+
// Final check to ensure body is within GitHub's limits
311+
const maxBodyLength = 65000; // Slightly under the 65536 limit for safety
312+
let finalBody = body;
313+
if (body.length > maxBodyLength) {
314+
const truncateAt = maxBodyLength - 200; // Leave room for truncation message
315+
finalBody = body.substring(0, truncateAt) + '\n\n... (content truncated to fit GitHub limits)';
316+
}
317+
271318
// Check for existing issues
272319
const issues = await github.rest.issues.listForRepo({
273320
owner: context.repo.owner,
@@ -285,20 +332,55 @@ jobs:
285332
286333
if (recentIssue) {
287334
console.log(`Recent issue found: #${recentIssue.number}, updating`);
335+
336+
// Truncate comment if needed
337+
let commentBody = `## Updated Analysis (${date})\n\nBuild Status: ${buildEmoji} ${buildStatus}\n\n${analysis}`;
338+
if (commentBody.length > maxBodyLength) {
339+
const truncateAt = maxBodyLength - 200;
340+
commentBody = commentBody.substring(0, truncateAt) + '\n\n... (content truncated to fit GitHub limits)';
341+
}
342+
288343
await github.rest.issues.createComment({
289344
owner: context.repo.owner,
290345
repo: context.repo.repo,
291346
issue_number: recentIssue.number,
292-
body: `## Updated Analysis (${date})\n\nBuild Status: ${buildEmoji} ${buildStatus}\n\n${analysis}`
347+
body: commentBody
293348
});
294349
} else {
295-
await github.rest.issues.create({
296-
owner: context.repo.owner,
297-
repo: context.repo.repo,
298-
title: title,
299-
body: body,
300-
labels: ['documentation', 'functionality', 'automated', 'needs-review']
301-
});
350+
try {
351+
await github.rest.issues.create({
352+
owner: context.repo.owner,
353+
repo: context.repo.repo,
354+
title: title,
355+
body: finalBody,
356+
labels: ['documentation', 'functionality', 'automated', 'needs-review']
357+
});
358+
} catch (error) {
359+
console.error('Failed to create issue:', error.message);
360+
// Create a minimal issue if the full one fails
361+
const minimalBody = `# Code Functionality and Documentation Review
362+
363+
## Build Status: ${buildEmoji} ${buildStatus}
364+
365+
Documentation analysis completed but output was too large for GitHub issue.
366+
Please check the workflow logs for detailed analysis.
367+
368+
## Action Items
369+
- [ ] Review workflow logs for detailed documentation analysis
370+
- [ ] Address any build issues if status is failed
371+
- [ ] Improve documentation coverage
372+
373+
---
374+
*This is a minimal issue due to content size limitations.*`;
375+
376+
await github.rest.issues.create({
377+
owner: context.repo.owner,
378+
repo: context.repo.repo,
379+
title: title,
380+
body: minimalBody,
381+
labels: ['documentation', 'functionality', 'automated', 'needs-review']
382+
});
383+
}
302384
}
303385
env:
304386
BUILD_STATUS: ${{ steps.build.outputs.BUILD_STATUS }}

count_ruby_files.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env python3
2+
import os
3+
from pathlib import Path
4+
5+
workspace = Path("/workspace")
6+
ruby_count = 0
7+
python_count = 0
8+
9+
# Count files in key directories
10+
for root, dirs, files in os.walk(workspace):
11+
# Skip certain directories
12+
if any(skip in root for skip in ['legacy', '.git', 'spec', 'test', 'vendor']):
13+
continue
14+
15+
for file in files:
16+
if file.endswith('.rb'):
17+
ruby_count += 1
18+
elif file.endswith('.py'):
19+
python_count += 1
20+
21+
print(f"Current file counts:")
22+
print(f"Ruby files (.rb): {ruby_count}")
23+
print(f"Python files (.py): {python_count}")
24+
25+
# Check specific exploit directory
26+
exploits_dir = workspace / "modules" / "exploits" / "linux" / "http"
27+
if exploits_dir.exists():
28+
rb_files = list(exploits_dir.glob("*.rb"))
29+
py_files = list(exploits_dir.glob("*.py"))
30+
print(f"\nIn modules/exploits/linux/http:")
31+
print(f"Ruby files: {len(rb_files)}")
32+
print(f"Python files: {len(py_files)}")
33+
34+
if rb_files:
35+
print(f"First few Ruby files to convert:")
36+
for i, rb_file in enumerate(rb_files[:5]):
37+
print(f" {i+1}. {rb_file.name}")

direct_migration.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Direct execution of Python Round 2 migration
4+
"""
5+
6+
import os
7+
import sys
8+
from pathlib import Path
9+
10+
# Change to workspace directory
11+
os.chdir("/workspace")
12+
13+
# Import and run the migrator
14+
sys.path.insert(0, '/workspace')
15+
16+
try:
17+
from migrate_ruby_to_python import RubyToPythonMigrator
18+
19+
print("🐍 PYTHON ROUND 2: GRAB ALL THE RUBY AND PYTHON IT! 🐍")
20+
print("=" * 60)
21+
22+
# First, let's see what we're working with
23+
workspace = Path("/workspace")
24+
ruby_files = []
25+
26+
# Find Ruby files in key directories
27+
key_dirs = ["modules/exploits", "modules/auxiliary", "modules/post", "lib", "tools", "scripts"]
28+
29+
for dir_name in key_dirs:
30+
dir_path = workspace / dir_name
31+
if dir_path.exists():
32+
for rb_file in dir_path.rglob("*.rb"):
33+
if "legacy" not in str(rb_file) and "spec" not in str(rb_file) and "test" not in str(rb_file):
34+
ruby_files.append(rb_file)
35+
36+
print(f"Found {len(ruby_files)} Ruby files to process")
37+
38+
if len(ruby_files) == 0:
39+
print("No Ruby files found to convert. Migration may already be complete!")
40+
sys.exit(0)
41+
42+
# Show some examples
43+
print("\nSample Ruby files to convert:")
44+
for i, rb_file in enumerate(ruby_files[:10]):
45+
rel_path = rb_file.relative_to(workspace)
46+
print(f" {i+1:2d}. {rel_path}")
47+
48+
if len(ruby_files) > 10:
49+
print(f" ... and {len(ruby_files) - 10} more files")
50+
51+
# Run the migration
52+
print(f"\n=== STARTING MIGRATION ===")
53+
54+
migrator = RubyToPythonMigrator(
55+
workspace_dir="/workspace",
56+
dry_run=False, # Actually do the conversion
57+
verbose=True
58+
)
59+
60+
migrator.migrate_files()
61+
migrator.print_summary()
62+
63+
print("\n🎉 PYTHON ROUND 2 COMPLETE! 🎉")
64+
print("Ruby files have been PYTHON-ed as requested!")
65+
66+
except ImportError as e:
67+
print(f"Could not import migration script: {e}")
68+
sys.exit(1)
69+
except Exception as e:
70+
print(f"Migration failed: {e}")
71+
import traceback
72+
traceback.print_exc()
73+
sys.exit(1)

0 commit comments

Comments
 (0)