@utarid/cryo 1.0.0
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.
- package/LICENSE +21 -0
- package/README.md +151 -0
- package/bin/cryo.js +2 -0
- package/dist/core/Archiver.js +79 -0
- package/dist/core/Builder.js +112 -0
- package/dist/core/Cleaner.js +112 -0
- package/dist/core/ConfigManager.js +115 -0
- package/dist/core/Prompt.js +77 -0
- package/dist/core/Scanner.js +150 -0
- package/dist/index.js +752 -0
- package/dist/types.js +3 -0
- package/package.json +54 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/core/Scanner.ts
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.Scanner = void 0;
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
class Scanner {
|
|
13
|
+
constructor() {
|
|
14
|
+
// Fixed indicators
|
|
15
|
+
this.indicators = {
|
|
16
|
+
'package.json': 'nodejs',
|
|
17
|
+
'pubspec.yaml': 'flutter',
|
|
18
|
+
'pom.xml': 'java-maven',
|
|
19
|
+
'build.gradle': 'java-gradle',
|
|
20
|
+
'requirements.txt': 'python', // Python
|
|
21
|
+
'Pipfile': 'python', // Python (Pipenv)
|
|
22
|
+
'pyproject.toml': 'python', // Python (Modern)
|
|
23
|
+
'Cargo.toml': 'rust', // Rust
|
|
24
|
+
'composer.json': 'php', // PHP
|
|
25
|
+
'Podfile': 'swift', // iOS (CocoaPods)
|
|
26
|
+
'Package.swift': 'swift', // iOS (SPM)
|
|
27
|
+
};
|
|
28
|
+
// Build/Artifact folders (For existence check)
|
|
29
|
+
this.buildFolders = {
|
|
30
|
+
'nodejs': ['dist', 'build', '.next', '.nuxt', 'coverage'],
|
|
31
|
+
'flutter': ['build', '.dart_tool'],
|
|
32
|
+
'java-maven': ['target'],
|
|
33
|
+
'java-gradle': ['build'],
|
|
34
|
+
'python': ['venv', '.venv', 'env', '__pycache__', 'dist', 'build'],
|
|
35
|
+
'rust': ['target'],
|
|
36
|
+
'dotnet': ['bin', 'obj'],
|
|
37
|
+
'php': ['vendor'],
|
|
38
|
+
'swift': ['Pods', 'build', 'DerivedData']
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async scan(scanPaths, ignorePatterns = []) {
|
|
42
|
+
let rawProjects = [];
|
|
43
|
+
for (const rootPath of scanPaths) {
|
|
44
|
+
// Expanded glob patterns
|
|
45
|
+
const entries = await (0, fast_glob_1.default)([
|
|
46
|
+
'**/package.json', '**/pubspec.yaml', '**/pom.xml', '**/build.gradle', // Existing
|
|
47
|
+
'**/requirements.txt', '**/Pipfile', '**/pyproject.toml', // Python
|
|
48
|
+
'**/Cargo.toml', // Rust
|
|
49
|
+
'**/*.csproj', '**/*.sln', // .NET (Wildcard)
|
|
50
|
+
'**/composer.json', // PHP
|
|
51
|
+
'**/Podfile', '**/Package.swift' // Swift
|
|
52
|
+
], {
|
|
53
|
+
cwd: rootPath,
|
|
54
|
+
ignore: [
|
|
55
|
+
'**/node_modules/**', '**/.git/**', '**/build/**', '**/dist/**', '**/target/**',
|
|
56
|
+
'**/vendor/**', '**/Pods/**', '**/bin/**', '**/obj/**', '**/venv/**', // Ignore list expanded
|
|
57
|
+
...ignorePatterns
|
|
58
|
+
],
|
|
59
|
+
absolute: true,
|
|
60
|
+
deep: 5 // Increased depth slightly
|
|
61
|
+
});
|
|
62
|
+
for (const entryPath of entries) {
|
|
63
|
+
const projectDir = path_1.default.dirname(entryPath);
|
|
64
|
+
const fileName = path_1.default.basename(entryPath);
|
|
65
|
+
// Do not add the same project again (different indicator)
|
|
66
|
+
if (rawProjects.some(p => p.path === projectDir))
|
|
67
|
+
continue;
|
|
68
|
+
// TYPE DETECTION (Advanced)
|
|
69
|
+
let type = 'unknown';
|
|
70
|
+
// 1. Fixed name check
|
|
71
|
+
if (this.indicators[fileName]) {
|
|
72
|
+
type = this.indicators[fileName];
|
|
73
|
+
}
|
|
74
|
+
// 2. Extension check (.csproj, .sln)
|
|
75
|
+
else if (fileName.endsWith('.csproj') || fileName.endsWith('.sln')) {
|
|
76
|
+
type = 'dotnet';
|
|
77
|
+
}
|
|
78
|
+
if (type === 'unknown')
|
|
79
|
+
continue;
|
|
80
|
+
const lastModified = await this.getRealModificationDate(projectDir, type, entryPath);
|
|
81
|
+
const buildInfo = await this.checkBuildStatus(projectDir, type);
|
|
82
|
+
rawProjects.push({
|
|
83
|
+
path: projectDir,
|
|
84
|
+
name: path_1.default.basename(projectDir),
|
|
85
|
+
type: type,
|
|
86
|
+
lastModified: lastModified,
|
|
87
|
+
buildInfo: buildInfo
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const cleanProjects = this.filterNestedProjects(rawProjects);
|
|
92
|
+
return cleanProjects.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
|
|
93
|
+
}
|
|
94
|
+
async getRealModificationDate(projectDir, type, indicatorFile) {
|
|
95
|
+
// Source code folders
|
|
96
|
+
const srcMap = {
|
|
97
|
+
'nodejs': 'src',
|
|
98
|
+
'java-maven': 'src',
|
|
99
|
+
'java-gradle': 'src',
|
|
100
|
+
'flutter': 'lib',
|
|
101
|
+
'rust': 'src',
|
|
102
|
+
'php': 'app', // Laravel usually uses app
|
|
103
|
+
'swift': 'Sources', // SPM usually uses Sources
|
|
104
|
+
// Python and Dotnet can be at root or complex, default fallback
|
|
105
|
+
};
|
|
106
|
+
const sourceFolder = srcMap[type];
|
|
107
|
+
if (sourceFolder) {
|
|
108
|
+
const sourcePath = path_1.default.join(projectDir, sourceFolder);
|
|
109
|
+
try {
|
|
110
|
+
if (await fs_extra_1.default.pathExists(sourcePath)) {
|
|
111
|
+
const stats = await fs_extra_1.default.stat(sourcePath);
|
|
112
|
+
return stats.mtime;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
console.warn(chalk_1.default.yellow(`\n[WARNING] Scan warning (Date): ${sourcePath} - ${e.message}`));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const stats = await fs_extra_1.default.stat(indicatorFile);
|
|
120
|
+
return stats.mtime;
|
|
121
|
+
}
|
|
122
|
+
async checkBuildStatus(projectPath, type) {
|
|
123
|
+
const potentialFolders = this.buildFolders[type] || [];
|
|
124
|
+
for (const folderName of potentialFolders) {
|
|
125
|
+
const fullPath = path_1.default.join(projectPath, folderName);
|
|
126
|
+
try {
|
|
127
|
+
if (await fs_extra_1.default.pathExists(fullPath)) {
|
|
128
|
+
const stats = await fs_extra_1.default.stat(fullPath);
|
|
129
|
+
return { exists: true, path: folderName, lastBuilt: stats.mtime };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
console.warn(chalk_1.default.yellow(`\n[WARNING] Scan warning (Build): ${fullPath} - ${e.message}`));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return { exists: false };
|
|
137
|
+
}
|
|
138
|
+
filterNestedProjects(projects) {
|
|
139
|
+
projects.sort((a, b) => a.path.length - b.path.length);
|
|
140
|
+
const result = [];
|
|
141
|
+
for (const p of projects) {
|
|
142
|
+
const isNested = result.some(parent => p.path.startsWith(parent.path + path_1.default.sep) || p.path === parent.path);
|
|
143
|
+
if (!isNested)
|
|
144
|
+
result.push(p);
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
exports.Scanner = Scanner;
|
|
150
|
+
exports.default = new Scanner();
|