packagepurge 1.0.0 → 1.0.1
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/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1 -0
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
- package/core/src/arc_lfu.rs +0 -91
- package/core/src/cache.rs +0 -205
- package/core/src/lockfiles.rs +0 -112
- package/core/src/main.rs +0 -125
- package/core/src/ml.rs +0 -188
- package/core/src/optimization.rs +0 -314
- package/core/src/safety.rs +0 -103
- package/core/src/scanner.rs +0 -136
- package/core/src/symlink.rs +0 -223
- package/core/src/types.rs +0 -87
- package/core/src/usage_tracker.rs +0 -107
- package/src/cli/index.ts +0 -212
- package/src/core/bindings.ts +0 -157
- package/src/managers/base-manager.ts +0 -117
- package/src/managers/index.ts +0 -32
- package/src/managers/npm-manager.ts +0 -96
- package/src/managers/pnpm-manager.ts +0 -107
- package/src/managers/yarn-manager.ts +0 -112
- package/src/types/index.ts +0 -97
- package/src/utils/logger.ts +0 -50
- package/tsconfig.json +0 -22
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.js
CHANGED
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/core/src/arc_lfu.rs
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
#![allow(dead_code)]
|
|
2
|
-
use std::collections::{HashMap, VecDeque};
|
|
3
|
-
|
|
4
|
-
// SLRU: probationary and protected segments, each LRU-like (front=MRU, back=LRU)
|
|
5
|
-
pub struct SlruPolicy {
|
|
6
|
-
probationary: VecDeque<String>,
|
|
7
|
-
protected: VecDeque<String>,
|
|
8
|
-
cap_probationary: usize,
|
|
9
|
-
cap_protected: usize,
|
|
10
|
-
in_probationary: HashMap<String, bool>,
|
|
11
|
-
in_protected: HashMap<String, bool>,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
impl SlruPolicy {
|
|
15
|
-
pub fn new(capacity: usize) -> Self {
|
|
16
|
-
let cap_protected = (capacity as f32 * 0.8) as usize;
|
|
17
|
-
let cap_probationary = capacity.saturating_sub(cap_protected);
|
|
18
|
-
Self {
|
|
19
|
-
probationary: VecDeque::new(),
|
|
20
|
-
protected: VecDeque::new(),
|
|
21
|
-
cap_probationary,
|
|
22
|
-
cap_protected,
|
|
23
|
-
in_probationary: HashMap::new(),
|
|
24
|
-
in_protected: HashMap::new(),
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
pub fn record_hit(&mut self, key: &str) {
|
|
29
|
-
let k = key.to_string();
|
|
30
|
-
if self.in_protected.remove(&k).is_some() {
|
|
31
|
-
self.protected.retain(|x| x != &k);
|
|
32
|
-
self.protected.push_front(k.clone());
|
|
33
|
-
self.in_protected.insert(k, true);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if self.in_probationary.remove(&k).is_some() {
|
|
37
|
-
// promote to protected
|
|
38
|
-
self.probationary.retain(|x| x != &k);
|
|
39
|
-
self.protected.push_front(k.clone());
|
|
40
|
-
self.in_protected.insert(k.clone(), true);
|
|
41
|
-
// enforce protected capacity
|
|
42
|
-
while self.protected.len() > self.cap_protected {
|
|
43
|
-
if let Some(v) = self.protected.pop_back() { self.in_protected.remove(&v); }
|
|
44
|
-
}
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
// new entry goes to probationary
|
|
48
|
-
self.probationary.push_front(k.clone());
|
|
49
|
-
self.in_probationary.insert(k.clone(), true);
|
|
50
|
-
while self.probationary.len() > self.cap_probationary {
|
|
51
|
-
if let Some(v) = self.probationary.pop_back() { self.in_probationary.remove(&v); }
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
pub fn select_victim(&mut self) -> Option<String> {
|
|
56
|
-
if let Some(v) = self.probationary.pop_back() { self.in_probationary.remove(&v); return Some(v); }
|
|
57
|
-
if let Some(v) = self.protected.pop_back() { self.in_protected.remove(&v); return Some(v); }
|
|
58
|
-
None
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Simple LFU: key->freq, and buckets freq->VecDeque keys. Evicts from lowest freq, oldest within bucket
|
|
63
|
-
pub struct SimpleLfu {
|
|
64
|
-
freq: HashMap<String, usize>,
|
|
65
|
-
buckets: HashMap<usize, VecDeque<String>>,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
impl SimpleLfu {
|
|
69
|
-
pub fn new() -> Self { Self { freq: HashMap::new(), buckets: HashMap::new() } }
|
|
70
|
-
|
|
71
|
-
pub fn increment(&mut self, key: &str) {
|
|
72
|
-
let k = key.to_string();
|
|
73
|
-
let f = *self.freq.get(&k).unwrap_or(&0);
|
|
74
|
-
if let Some(q) = self.buckets.get_mut(&f) { q.retain(|x| x != &k); }
|
|
75
|
-
let nf = f + 1;
|
|
76
|
-
self.freq.insert(k.clone(), nf);
|
|
77
|
-
self.buckets.entry(nf).or_default().push_front(k);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
pub fn victim(&mut self) -> Option<String> {
|
|
81
|
-
if self.freq.is_empty() { return None; }
|
|
82
|
-
let minf = *self.freq.values().min().unwrap_or(&0);
|
|
83
|
-
if let Some(q) = self.buckets.get_mut(&minf) {
|
|
84
|
-
if let Some(k) = q.pop_back() {
|
|
85
|
-
self.freq.remove(&k);
|
|
86
|
-
return Some(k);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
None
|
|
90
|
-
}
|
|
91
|
-
}
|
package/core/src/cache.rs
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
use std::cell::RefCell;
|
|
2
|
-
use std::collections::HashMap;
|
|
3
|
-
use std::hash::Hash;
|
|
4
|
-
use std::rc::Rc;
|
|
5
|
-
use chrono::Utc;
|
|
6
|
-
use crate::types::PackageUsageMetrics;
|
|
7
|
-
|
|
8
|
-
// Doubly-linked list node
|
|
9
|
-
struct Node<K, V> {
|
|
10
|
-
key: K,
|
|
11
|
-
value: V,
|
|
12
|
-
prev: Option<Rc<RefCell<Node<K, V>>>>,
|
|
13
|
-
next: Option<Rc<RefCell<Node<K, V>>>>,
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
pub struct LruCache<K, V> where K: Eq + Hash + Clone {
|
|
17
|
-
capacity: usize,
|
|
18
|
-
map: HashMap<K, Rc<RefCell<Node<K, V>>>>,
|
|
19
|
-
head: Option<Rc<RefCell<Node<K, V>>>>, // MRU
|
|
20
|
-
tail: Option<Rc<RefCell<Node<K, V>>>>, // LRU
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
impl<K, V> LruCache<K, V> where K: Eq + Hash + Clone {
|
|
24
|
-
pub fn new(capacity: usize) -> Self {
|
|
25
|
-
Self { capacity, map: HashMap::new(), head: None, tail: None }
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
#[allow(dead_code)]
|
|
29
|
-
pub fn len(&self) -> usize { self.map.len() }
|
|
30
|
-
#[allow(dead_code)]
|
|
31
|
-
pub fn is_empty(&self) -> bool { self.map.is_empty() }
|
|
32
|
-
|
|
33
|
-
pub fn get(&mut self, key: &K) -> Option<V> where V: Clone {
|
|
34
|
-
if let Some(node_rc) = self.map.get(key).cloned() {
|
|
35
|
-
self.move_to_head(node_rc.clone());
|
|
36
|
-
return Some(node_rc.borrow().value.clone());
|
|
37
|
-
}
|
|
38
|
-
None
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
pub fn put(&mut self, key: K, value: V) -> Option<(K, V)> where V: Clone {
|
|
42
|
-
if let Some(node_rc) = self.map.get(&key).cloned() {
|
|
43
|
-
// Update value and move to head
|
|
44
|
-
node_rc.borrow_mut().value = value;
|
|
45
|
-
self.move_to_head(node_rc);
|
|
46
|
-
return None;
|
|
47
|
-
}
|
|
48
|
-
// Insert new
|
|
49
|
-
let node = Rc::new(RefCell::new(Node { key: key.clone(), value, prev: None, next: None }));
|
|
50
|
-
self.attach_head(node.clone());
|
|
51
|
-
self.map.insert(key.clone(), node);
|
|
52
|
-
// Evict if over capacity
|
|
53
|
-
if self.map.len() > self.capacity {
|
|
54
|
-
if let Some(lru) = self.pop_tail() {
|
|
55
|
-
let k = lru.borrow().key.clone();
|
|
56
|
-
let v = lru.borrow().value.clone();
|
|
57
|
-
self.map.remove(&k);
|
|
58
|
-
return Some((k, v));
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
None
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
fn detach(&mut self, node: Rc<RefCell<Node<K, V>>>) {
|
|
65
|
-
let prev = node.borrow().prev.clone();
|
|
66
|
-
let next = node.borrow().next.clone();
|
|
67
|
-
if let Some(p) = prev.clone() { p.borrow_mut().next = next.clone(); } else { self.head = next.clone(); }
|
|
68
|
-
if let Some(n) = next.clone() { n.borrow_mut().prev = prev.clone(); } else { self.tail = prev.clone(); }
|
|
69
|
-
node.borrow_mut().prev = None;
|
|
70
|
-
node.borrow_mut().next = None;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
fn attach_head(&mut self, node: Rc<RefCell<Node<K, V>>>) {
|
|
74
|
-
node.borrow_mut().prev = None;
|
|
75
|
-
node.borrow_mut().next = self.head.clone();
|
|
76
|
-
if let Some(h) = self.head.clone() { h.borrow_mut().prev = Some(node.clone()); }
|
|
77
|
-
self.head = Some(node.clone());
|
|
78
|
-
if self.tail.is_none() { self.tail = Some(node); }
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
fn move_to_head(&mut self, node: Rc<RefCell<Node<K, V>>>) {
|
|
82
|
-
self.detach(node.clone());
|
|
83
|
-
self.attach_head(node);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
fn pop_tail(&mut self) -> Option<Rc<RefCell<Node<K, V>>>> {
|
|
87
|
-
if let Some(t) = self.tail.clone() {
|
|
88
|
-
self.detach(t.clone());
|
|
89
|
-
return Some(t);
|
|
90
|
-
}
|
|
91
|
-
None
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/// LRU cache specialized for package versions with usage tracking
|
|
96
|
-
#[allow(dead_code)]
|
|
97
|
-
pub struct PackageLruCache {
|
|
98
|
-
cache: LruCache<String, PackageUsageMetrics>,
|
|
99
|
-
max_size_bytes: u64,
|
|
100
|
-
current_size_bytes: u64,
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
impl PackageLruCache {
|
|
104
|
-
pub fn new(max_packages: usize, max_size_bytes: u64) -> Self {
|
|
105
|
-
Self {
|
|
106
|
-
cache: LruCache::new(max_packages),
|
|
107
|
-
max_size_bytes,
|
|
108
|
-
current_size_bytes: 0,
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/// Record package access (updates atime and increments access count)
|
|
113
|
-
pub fn record_access(&mut self, package_key: &str, size_bytes: u64) {
|
|
114
|
-
let now = Utc::now();
|
|
115
|
-
if let Some(metrics) = self.cache.get(&package_key.to_string()) {
|
|
116
|
-
// Update existing metrics
|
|
117
|
-
let mut updated = metrics;
|
|
118
|
-
updated.last_access_time = now;
|
|
119
|
-
updated.access_count += 1;
|
|
120
|
-
self.cache.put(package_key.to_string(), updated);
|
|
121
|
-
} else {
|
|
122
|
-
// Create new metrics
|
|
123
|
-
let metrics = PackageUsageMetrics {
|
|
124
|
-
package_key: package_key.to_string(),
|
|
125
|
-
last_access_time: now,
|
|
126
|
-
last_script_execution: None,
|
|
127
|
-
access_count: 1,
|
|
128
|
-
script_execution_count: 0,
|
|
129
|
-
last_successful_build: None,
|
|
130
|
-
};
|
|
131
|
-
if let Some((_evicted_key, _evicted_metrics)) = self.cache.put(package_key.to_string(), metrics) {
|
|
132
|
-
// Handle eviction if needed
|
|
133
|
-
// In a full implementation, we'd track size_bytes per package
|
|
134
|
-
}
|
|
135
|
-
self.current_size_bytes += size_bytes;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/// Record successful script execution
|
|
140
|
-
#[allow(dead_code)]
|
|
141
|
-
pub fn record_script_execution(&mut self, package_key: &str) {
|
|
142
|
-
let now = Utc::now();
|
|
143
|
-
if let Some(metrics) = self.cache.get(&package_key.to_string()) {
|
|
144
|
-
let mut updated = metrics;
|
|
145
|
-
updated.last_script_execution = Some(now);
|
|
146
|
-
updated.script_execution_count += 1;
|
|
147
|
-
self.cache.put(package_key.to_string(), updated);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/// Record successful build
|
|
152
|
-
#[allow(dead_code)]
|
|
153
|
-
pub fn record_build(&mut self, package_key: &str) {
|
|
154
|
-
let now = Utc::now();
|
|
155
|
-
if let Some(metrics) = self.cache.get(&package_key.to_string()) {
|
|
156
|
-
let mut updated = metrics;
|
|
157
|
-
updated.last_successful_build = Some(now);
|
|
158
|
-
self.cache.put(package_key.to_string(), updated);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/// Get metrics for a package (updates LRU position)
|
|
163
|
-
pub fn get_metrics(&mut self, package_key: &str) -> Option<PackageUsageMetrics> {
|
|
164
|
-
self.cache.get(&package_key.to_string())
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/// Get least recently used packages (for eviction candidates)
|
|
168
|
-
#[allow(dead_code)]
|
|
169
|
-
pub fn get_lru_packages(&self, _count: usize) -> Vec<String> {
|
|
170
|
-
// This is a simplified version - in a full implementation,
|
|
171
|
-
// we'd need to iterate through the tail of the LRU cache
|
|
172
|
-
Vec::new() // Placeholder
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/// Check if package should be kept based on LRU strategy
|
|
176
|
-
pub fn should_keep_lru(&mut self, package_key: &str, days_threshold: i64) -> bool {
|
|
177
|
-
if let Some(metrics) = self.get_metrics(package_key) {
|
|
178
|
-
let days_since_access = (Utc::now() - metrics.last_access_time).num_days();
|
|
179
|
-
return days_since_access < days_threshold;
|
|
180
|
-
}
|
|
181
|
-
false
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
#[cfg(test)]
|
|
186
|
-
mod tests {
|
|
187
|
-
use super::LruCache;
|
|
188
|
-
#[test]
|
|
189
|
-
fn test_lru_basic() {
|
|
190
|
-
let mut lru = LruCache::new(2);
|
|
191
|
-
assert!(lru.get(&"a").is_none());
|
|
192
|
-
assert!(lru.put("a", 1).is_none());
|
|
193
|
-
assert_eq!(lru.get(&"a"), Some(1));
|
|
194
|
-
assert!(lru.put("b", 2).is_none());
|
|
195
|
-
assert_eq!(lru.len(), 2);
|
|
196
|
-
// Insert c -> evict LRU (which should be 'a' after accessing 'a' it's MRU; LRU is 'b'?)
|
|
197
|
-
// Access changes MRU; sequence ensures eviction is correct
|
|
198
|
-
lru.get(&"a"); // 'a' MRU, 'b' LRU
|
|
199
|
-
let evicted = lru.put("c", 3);
|
|
200
|
-
assert!(evicted.is_some());
|
|
201
|
-
let (k, v) = evicted.unwrap();
|
|
202
|
-
assert_eq!(k, "b");
|
|
203
|
-
assert_eq!(v, 2);
|
|
204
|
-
}
|
|
205
|
-
}
|
package/core/src/lockfiles.rs
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
use std::fs;
|
|
2
|
-
use std::path::Path;
|
|
3
|
-
|
|
4
|
-
pub type DepList = Vec<(String, String)>; // (name, version)
|
|
5
|
-
|
|
6
|
-
pub fn parse_npm_package_lock(path: &Path) -> DepList {
|
|
7
|
-
let mut deps_list: DepList = Vec::new();
|
|
8
|
-
let text = match fs::read_to_string(path) { Ok(t) => t, Err(_) => return deps_list };
|
|
9
|
-
let json: serde_json::Value = match serde_json::from_str(&text) { Ok(v) => v, Err(_) => return deps_list };
|
|
10
|
-
|
|
11
|
-
fn walk(node: &serde_json::Value, list: &mut DepList) {
|
|
12
|
-
if let Some(deps) = node.get("dependencies").and_then(|d| d.as_object()) {
|
|
13
|
-
for (name, dep_node) in deps {
|
|
14
|
-
if let Some(ver) = dep_node.get("version").and_then(|v| v.as_str()) {
|
|
15
|
-
list.push((name.clone(), ver.to_string()));
|
|
16
|
-
}
|
|
17
|
-
walk(dep_node, list);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
// Handle 'packages' in lockfile v2/v3
|
|
21
|
-
if let Some(packages) = node.get("packages").and_then(|d| d.as_object()) {
|
|
22
|
-
for (key, pkg_node) in packages {
|
|
23
|
-
if key.is_empty() { continue; } // Root
|
|
24
|
-
|
|
25
|
-
// Key is path like "node_modules/pkg" or "node_modules/a/node_modules/b"
|
|
26
|
-
// We want the package name, which is after the last "node_modules/"
|
|
27
|
-
let name = if let Some(idx) = key.rfind("node_modules/") {
|
|
28
|
-
key[idx + "node_modules/".len()..].to_string()
|
|
29
|
-
} else {
|
|
30
|
-
key.clone()
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
if let Some(ver) = pkg_node.get("version").and_then(|v| v.as_str()) {
|
|
34
|
-
list.push((name, ver.to_string()));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
walk(&json, &mut deps_list);
|
|
41
|
-
deps_list
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
pub fn parse_yarn_lock(path: &Path) -> DepList {
|
|
45
|
-
let mut list: DepList = Vec::new();
|
|
46
|
-
let text = match fs::read_to_string(path) { Ok(t) => t, Err(_) => return list };
|
|
47
|
-
|
|
48
|
-
let mut current_name: Option<String> = None;
|
|
49
|
-
|
|
50
|
-
for line in text.lines() {
|
|
51
|
-
let trimmed = line.trim();
|
|
52
|
-
if trimmed.is_empty() || trimmed.starts_with('#') { continue; }
|
|
53
|
-
|
|
54
|
-
if !line.starts_with(' ') {
|
|
55
|
-
// Start of a block: "pkg@ver, pkg@ver:"
|
|
56
|
-
let parts: Vec<&str> = trimmed.trim_end_matches(':').split(',').collect();
|
|
57
|
-
if let Some(first) = parts.first() {
|
|
58
|
-
// Extract name from "name@range"
|
|
59
|
-
// This is heuristic; yarn lock keys are complex.
|
|
60
|
-
// Simpler: wait for "version" line.
|
|
61
|
-
// But we need the name.
|
|
62
|
-
// Pattern: name@^1.2.3
|
|
63
|
-
// Last '@' separates name and version range, but scoped packages start with @.
|
|
64
|
-
let s = first.trim().trim_matches('"');
|
|
65
|
-
if let Some(idx) = s.rfind('@') {
|
|
66
|
-
if idx > 0 {
|
|
67
|
-
current_name = Some(s[..idx].to_string());
|
|
68
|
-
} else {
|
|
69
|
-
current_name = None;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
} else if let Some(name) = ¤t_name {
|
|
74
|
-
if trimmed.starts_with("version") {
|
|
75
|
-
// version "1.2.3"
|
|
76
|
-
let parts: Vec<&str> = trimmed.split_whitespace().collect();
|
|
77
|
-
if parts.len() >= 2 {
|
|
78
|
-
let ver = parts[1].trim_matches('"');
|
|
79
|
-
list.push((name.clone(), ver.to_string()));
|
|
80
|
-
current_name = None; // Reset so we don't duplicate
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
list
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
pub fn parse_pnpm_lock(path: &Path) -> DepList {
|
|
89
|
-
let mut list: DepList = Vec::new();
|
|
90
|
-
let text = match fs::read_to_string(path) { Ok(t) => t, Err(_) => return list };
|
|
91
|
-
|
|
92
|
-
for line in text.lines() {
|
|
93
|
-
let l = line.trim();
|
|
94
|
-
// /name/version:
|
|
95
|
-
if l.starts_with('/') && l.ends_with(':') {
|
|
96
|
-
let content = l.trim_end_matches(':');
|
|
97
|
-
// content is like /@babel/core/7.2.0
|
|
98
|
-
// extract name and version.
|
|
99
|
-
// Split by '/'
|
|
100
|
-
let parts: Vec<&str> = content.split('/').collect();
|
|
101
|
-
// parts[0] is empty
|
|
102
|
-
// if scoped: "", "@scope", "pkg", "ver" -> len 4
|
|
103
|
-
// if unscoped: "", "pkg", "ver" -> len 3
|
|
104
|
-
if parts.len() >= 3 {
|
|
105
|
-
let ver = parts.last().unwrap().to_string();
|
|
106
|
-
let name = parts[1..parts.len()-1].join("/");
|
|
107
|
-
list.push((name, ver));
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
list
|
|
112
|
-
}
|
package/core/src/main.rs
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
mod types;
|
|
2
|
-
mod scanner;
|
|
3
|
-
mod safety;
|
|
4
|
-
mod optimization;
|
|
5
|
-
mod cache;
|
|
6
|
-
mod ml;
|
|
7
|
-
mod arc_lfu;
|
|
8
|
-
mod lockfiles;
|
|
9
|
-
mod symlink;
|
|
10
|
-
mod usage_tracker;
|
|
11
|
-
|
|
12
|
-
use anyhow::Result;
|
|
13
|
-
use clap::{Parser, Subcommand};
|
|
14
|
-
use std::path::PathBuf;
|
|
15
|
-
|
|
16
|
-
use optimization::{plan_basic_cleanup, RulesConfig, OptimizationEngine};
|
|
17
|
-
|
|
18
|
-
#[derive(Parser)]
|
|
19
|
-
#[command(name = "packagepurge-core", version)]
|
|
20
|
-
struct Cli {
|
|
21
|
-
#[command(subcommand)]
|
|
22
|
-
command: Commands,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
#[derive(Subcommand)]
|
|
26
|
-
enum Commands {
|
|
27
|
-
/// Scan filesystem and output dependency/caches JSON
|
|
28
|
-
Scan { #[arg(short, long)] paths: Vec<PathBuf> },
|
|
29
|
-
/// Produce cleanup plan without mutating filesystem
|
|
30
|
-
DryRun { #[arg(short, long, default_value_t = 90)] preserve_days: i64, #[arg(short, long)] paths: Vec<PathBuf> },
|
|
31
|
-
/// Move targets to quarantine (atomic move) based on paths provided
|
|
32
|
-
Quarantine { #[arg(required=true)] targets: Vec<PathBuf> },
|
|
33
|
-
/// Rollback by id or latest
|
|
34
|
-
Rollback {
|
|
35
|
-
#[arg(long)] id: Option<String>,
|
|
36
|
-
#[arg(long)] latest: bool,
|
|
37
|
-
},
|
|
38
|
-
/// Optimize with ML/LRU and symlinking (dry run)
|
|
39
|
-
Optimize {
|
|
40
|
-
#[arg(short, long, default_value_t = 90)] preserve_days: i64,
|
|
41
|
-
#[arg(short, long)] paths: Vec<PathBuf>,
|
|
42
|
-
#[arg(long)] enable_symlinking: bool,
|
|
43
|
-
#[arg(long)] enable_ml: bool,
|
|
44
|
-
#[arg(long, default_value_t = 1000)] lru_max_packages: usize,
|
|
45
|
-
#[arg(long, default_value_t = 10_000_000_000)] lru_max_size_bytes: u64,
|
|
46
|
-
},
|
|
47
|
-
/// Execute symlinking for duplicate packages
|
|
48
|
-
Symlink {
|
|
49
|
-
#[arg(short, long)] paths: Vec<PathBuf>,
|
|
50
|
-
},
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
fn main() -> Result<()> {
|
|
54
|
-
let cli = Cli::parse();
|
|
55
|
-
match cli.command {
|
|
56
|
-
Commands::Scan { paths } => {
|
|
57
|
-
let out = scanner::scan(&paths)?;
|
|
58
|
-
println!("{}", serde_json::to_string_pretty(&out)?);
|
|
59
|
-
}
|
|
60
|
-
Commands::DryRun { preserve_days, paths } => {
|
|
61
|
-
let scan = scanner::scan(&paths)?;
|
|
62
|
-
let report = plan_basic_cleanup(&scan, &RulesConfig {
|
|
63
|
-
preserve_days,
|
|
64
|
-
enable_symlinking: false,
|
|
65
|
-
enable_ml_prediction: false,
|
|
66
|
-
lru_max_packages: 1000,
|
|
67
|
-
lru_max_size_bytes: 10_000_000_000, // 10GB default
|
|
68
|
-
})?;
|
|
69
|
-
println!("{}", serde_json::to_string_pretty(&report)?);
|
|
70
|
-
}
|
|
71
|
-
Commands::Quarantine { targets } => {
|
|
72
|
-
let mut recs = Vec::new();
|
|
73
|
-
for t in targets {
|
|
74
|
-
match safety::move_to_quarantine(&t) {
|
|
75
|
-
Ok(r) => recs.push(r),
|
|
76
|
-
Err(e) => eprintln!("Failed to quarantine {:?}: {}", t, e),
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
println!("{}", serde_json::to_string_pretty(&recs)?);
|
|
80
|
-
}
|
|
81
|
-
Commands::Rollback { id, latest } => {
|
|
82
|
-
let rec = if let Some(i) = id { safety::find_quarantine_by_id(&i) } else if latest { safety::latest_quarantine() } else { None };
|
|
83
|
-
if let Some(r) = rec {
|
|
84
|
-
if let Err(e) = safety::rollback_record(&r) {
|
|
85
|
-
eprintln!("{}", e);
|
|
86
|
-
std::process::exit(1);
|
|
87
|
-
}
|
|
88
|
-
println!("{}", serde_json::to_string_pretty(&serde_json::json!({"status":"ok","id": r.id}))?);
|
|
89
|
-
} else {
|
|
90
|
-
eprintln!("No matching quarantine record found");
|
|
91
|
-
std::process::exit(2);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
Commands::Optimize { preserve_days, paths, enable_symlinking, enable_ml, lru_max_packages, lru_max_size_bytes } => {
|
|
95
|
-
let scan = scanner::scan(&paths)?;
|
|
96
|
-
let config = RulesConfig {
|
|
97
|
-
preserve_days,
|
|
98
|
-
enable_symlinking,
|
|
99
|
-
enable_ml_prediction: enable_ml,
|
|
100
|
-
lru_max_packages,
|
|
101
|
-
lru_max_size_bytes,
|
|
102
|
-
};
|
|
103
|
-
let mut engine = OptimizationEngine::new(config)?;
|
|
104
|
-
let report = engine.plan_optimized_cleanup(&scan)?;
|
|
105
|
-
println!("{}", serde_json::to_string_pretty(&report)?);
|
|
106
|
-
}
|
|
107
|
-
Commands::Symlink { paths } => {
|
|
108
|
-
let scan = scanner::scan(&paths)?;
|
|
109
|
-
let config = RulesConfig {
|
|
110
|
-
preserve_days: 90,
|
|
111
|
-
enable_symlinking: true,
|
|
112
|
-
enable_ml_prediction: false,
|
|
113
|
-
lru_max_packages: 1000,
|
|
114
|
-
lru_max_size_bytes: 10_000_000_000,
|
|
115
|
-
};
|
|
116
|
-
let engine = OptimizationEngine::new(config)?;
|
|
117
|
-
let count = engine.execute_symlinking(&scan)?;
|
|
118
|
-
println!("{}", serde_json::to_string_pretty(&serde_json::json!({
|
|
119
|
-
"status": "ok",
|
|
120
|
-
"symlinked_count": count
|
|
121
|
-
}))?);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
Ok(())
|
|
125
|
-
}
|