-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatcher.rs
156 lines (148 loc) · 5.13 KB
/
matcher.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use std::collections::HashMap;
use crate::nix::NIX_ATTRIBUTES_REVERSED;
use crate::{deb::debian_redirect, error::DebNixError};
/// Matches the input pkgs with the output pkgs
/// The input pkgs are assumed to come from debian and the output pkgs from nix
/// Will use simple heuristics, in order to get a possible match.
pub(crate) fn match_libs(
input: Vec<String>,
output: Vec<String>,
) -> Result<HashMap<String, String>, DebNixError> {
let mut res_map = HashMap::new();
let mut input = input.to_vec();
let mut outputs = output.to_vec();
if input.is_empty() || outputs.is_empty() {
return Err(DebNixError::NoMatches(format!(
"Nothing to match, \ninput: \n{:?}, or \noutput: \n{:?} is empty!",
&input, &output
)));
}
// manual matching of the inputs
input.retain(|lib| match match_inlib(lib, &mut outputs) {
(true, None) => true,
(true, Some(_)) => true,
(false, None) => false,
(false, Some(outlib)) => {
res_map.insert(lib.clone(), outlib.clone());
outputs.retain(|lib| *lib != outlib);
false
}
});
// redirect the remaining packages and match them afterwards
input.retain(|lib| {
let redirect = debian_redirect(lib).unwrap();
match match_inlib(&redirect, &mut outputs) {
(true, None) => true,
(true, Some(_)) => true,
(false, None) => false,
(false, Some(outlib)) => {
res_map.insert(lib.to_string(), outlib.clone());
outputs.retain(|lib| lib != &outlib);
false
}
}
});
// redirect the remaining packages and match them afterwards match remaining packages against
// the full output and don't take pkgs out of the outputs (multiple binaries in one pkg)
input.retain(|lib| {
let mut outputs = output.to_vec();
let redirect = debian_redirect(lib).unwrap();
match match_inlib(&redirect, &mut outputs) {
(true, None) => true,
(true, Some(_)) => true,
(false, None) => false,
(false, Some(outlib)) => {
res_map.insert(String::from(lib), outlib);
false
}
}
});
debug!("\nInput {:?}\n", &input);
debug!("Output {:?}\n", &outputs);
// Switching matched pnames from the nix matches to their corresponding attribute paths,
// because that is how they are likely to be consumed.
for value in res_map.values_mut() {
if let Some(attr_path) = NIX_ATTRIBUTES_REVERSED.get(value) {
if let Some(attr_path) = &attr_path.attrpath {
value.clear();
value.push_str(&attr_path.clone())
}
}
}
Ok(res_map)
}
fn match_inlib(inlib: &str, outlibs: &mut Vec<String>) -> (bool, Option<String>) {
use regex::Regex;
// for version numbers
let ve = Regex::new(r"\d(.\d*)*").unwrap();
// exact match
for outlib in &mut *outlibs {
if inlib == *outlib {
debug!("{:?}", inlib);
return (false, Some(outlib.to_string()));
}
}
// replace `-dev`
for outlib in &mut *outlibs {
if inlib.replace("-dev", "") == *outlib {
debug!("{:?}", inlib);
return (false, Some(outlib.to_string()));
}
}
// replace `-dev` && lowercase
for outlib in &mut *outlibs {
if inlib.replace("-dev", "").to_lowercase() == *outlib.to_lowercase() {
debug!("{:?}", inlib);
return (false, Some(outlib.to_string()));
}
}
// replace `-dev` && lowercase && replace - _
for outlib in &mut *outlibs {
if inlib.replace("-dev", "").replace('-', "_").to_lowercase() == *outlib.to_lowercase() {
debug!("{:?}", inlib);
return (false, Some(outlib.to_string()));
}
}
// replace `-dev` && lowercase && replace - _ && replace lib
for outlib in &mut *outlibs {
if ve.replace_all(
&inlib
.replace("-dev", "")
.replace('-', "_")
.replace("lib", "")
.to_lowercase(),
"",
) == *outlib.to_lowercase()
{
debug!("{:?}", inlib);
return (false, Some(outlib.to_string()));
}
}
// replace `-dev` && lowercase && replace - _ && don't replace lib
for outlib in &mut *outlibs {
if ve.replace_all(
&inlib.replace("-dev", "").replace('-', "_").to_lowercase(),
"",
) == *outlib.to_lowercase()
{
debug!("{:?}", inlib);
return (false, Some(outlib.to_string()));
}
}
// replace `-dev` && lowercase && replace - "" && don't replace lib
for outlib in outlibs {
if ve.replace_all(
&inlib
.replace("-dev", "")
.replace('-', "")
.replace("lib", "")
.to_lowercase(),
"",
) == *outlib.to_lowercase()
{
debug!("{:?}", inlib);
return (false, Some(outlib.to_string()));
}
}
(true, None)
}