|
7 | 7 | use { |
8 | 8 | crate::project_building::find_pyoxidizer_config_file_env, |
9 | 9 | crate::project_layout::{initialize_project, write_new_pyoxidizer_config_file}, |
10 | | - crate::py_packaging::standalone_distribution::StandaloneDistribution, |
| 10 | + crate::py_packaging::{ |
| 11 | + distribution::{default_distribution_location, resolve_distribution, DistributionFlavor}, |
| 12 | + standalone_distribution::StandaloneDistribution, |
| 13 | + }, |
11 | 14 | crate::starlark::eval::{eval_starlark_config_file, EvalResult}, |
12 | 15 | anyhow::{anyhow, Result}, |
13 | | - std::fs::create_dir_all, |
14 | | - std::io::{Cursor, Read}, |
15 | | - std::path::Path, |
| 16 | + python_packaging::{ |
| 17 | + filesystem_scanning::find_python_resources, |
| 18 | + resource::{DataLocation, PythonResource}, |
| 19 | + wheel::WheelArchive, |
| 20 | + }, |
| 21 | + std::{ |
| 22 | + fs::create_dir_all, |
| 23 | + io::{Cursor, Read}, |
| 24 | + path::Path, |
| 25 | + }, |
16 | 26 | }; |
17 | 27 |
|
18 | 28 | /// Attempt to resolve the default Rust target for a build. |
@@ -146,6 +156,117 @@ pub fn run( |
146 | 156 | res.context.run_target(target) |
147 | 157 | } |
148 | 158 |
|
| 159 | +/// Find resources given a source path. |
| 160 | +pub fn find_resources( |
| 161 | + logger: &slog::Logger, |
| 162 | + path: Option<&Path>, |
| 163 | + distributions_dir: Option<&Path>, |
| 164 | + scan_distribution: bool, |
| 165 | + target_triple: &str, |
| 166 | +) -> Result<()> { |
| 167 | + let distribution_location = |
| 168 | + default_distribution_location(&DistributionFlavor::Standalone, target_triple, None)?; |
| 169 | + |
| 170 | + let mut temp_dir = None; |
| 171 | + |
| 172 | + let extract_path = if let Some(path) = distributions_dir { |
| 173 | + path |
| 174 | + } else { |
| 175 | + temp_dir.replace(tempdir::TempDir::new("python-distribution")?); |
| 176 | + temp_dir.as_ref().unwrap().path() |
| 177 | + }; |
| 178 | + |
| 179 | + let dist = resolve_distribution(logger, &distribution_location, extract_path)?; |
| 180 | + |
| 181 | + if scan_distribution { |
| 182 | + println!("scanning distribution"); |
| 183 | + |
| 184 | + for ext in dist.iter_extension_modules() { |
| 185 | + print_resource(&PythonResource::from(ext)); |
| 186 | + } |
| 187 | + for source in dist.source_modules()? { |
| 188 | + print_resource(&PythonResource::from(source)); |
| 189 | + } |
| 190 | + for data in dist.resource_datas()? { |
| 191 | + print_resource(&PythonResource::from(data)); |
| 192 | + } |
| 193 | + } else if let Some(path) = path { |
| 194 | + if path.is_dir() { |
| 195 | + println!("scanning directory {}", path.display()); |
| 196 | + for resource in |
| 197 | + find_python_resources(path, dist.cache_tag(), &dist.python_module_suffixes()?) |
| 198 | + { |
| 199 | + print_resource(&resource?); |
| 200 | + } |
| 201 | + } else if path.is_file() { |
| 202 | + if let Some(extension) = path.extension() { |
| 203 | + if extension.to_string_lossy() == "whl" { |
| 204 | + println!("parsing {} as a wheel archive", path.display()); |
| 205 | + let wheel = WheelArchive::from_path(path)?; |
| 206 | + |
| 207 | + for resource in |
| 208 | + wheel.python_resources(dist.cache_tag(), &dist.python_module_suffixes()?)? |
| 209 | + { |
| 210 | + print_resource(&resource) |
| 211 | + } |
| 212 | + |
| 213 | + return Ok(()); |
| 214 | + } |
| 215 | + } |
| 216 | + |
| 217 | + println!("do not know how to find resources in {}", path.display()); |
| 218 | + } else { |
| 219 | + println!("do not know how to find resources in {}", path.display()); |
| 220 | + } |
| 221 | + } else { |
| 222 | + println!("do not know what to scan"); |
| 223 | + } |
| 224 | + |
| 225 | + Ok(()) |
| 226 | +} |
| 227 | + |
| 228 | +fn print_resource(r: &PythonResource) { |
| 229 | + match r { |
| 230 | + PythonResource::ModuleSource(m) => println!( |
| 231 | + "PythonModuleSource {{ name: {}, is_package: {}, is_stdlib: {}, is_test: {} }}", |
| 232 | + m.name, m.is_package, m.is_stdlib, m.is_test |
| 233 | + ), |
| 234 | + PythonResource::ModuleBytecode(m) => println!( |
| 235 | + "PythonModuleBytecode {{ name: {}, is_package: {}, is_stdlib: {}, is_test: {}, bytecode_level: {} }}", |
| 236 | + m.name, m.is_package, m.is_stdlib, m.is_test, i32::from(m.optimize_level) |
| 237 | + ), |
| 238 | + PythonResource::ModuleBytecodeRequest(_) => println!( |
| 239 | + "PythonModuleBytecodeRequest {{ you should never see this }}" |
| 240 | + ), |
| 241 | + PythonResource::PackageResource(r) => println!( |
| 242 | + "PythonPackageResource {{ package: {}, name: {}, is_stdlib: {}, is_test: {} }}", r.leaf_package, r.relative_name, r.is_stdlib, r.is_test |
| 243 | + ), |
| 244 | + PythonResource::PackageDistributionResource(r) => println!( |
| 245 | + "PythonPackageDistributionResource {{ package: {}, version: {}, name: {} }}", r.package, r.version, r.name |
| 246 | + ), |
| 247 | + PythonResource::ExtensionModule(em) => { |
| 248 | + println!( |
| 249 | + "PythonExtensionModule {{" |
| 250 | + ); |
| 251 | + println!(" name: {}", em.name); |
| 252 | + println!(" is_builtin: {}", em.builtin_default); |
| 253 | + println!(" has_shared_library: {}", em.shared_library.is_some()); |
| 254 | + println!(" has_object_files: {}", !em.object_file_data.is_empty()); |
| 255 | + println!(" link_libraries: {:?}", em.link_libraries); |
| 256 | + println!("}}"); |
| 257 | + }, |
| 258 | + PythonResource::EggFile(e) => println!( |
| 259 | + "PythonEggFile {{ path: {} }}", match &e.data { |
| 260 | + DataLocation::Path(p) => p.display().to_string(), |
| 261 | + DataLocation::Memory(_) => "memory".to_string(), |
| 262 | + } |
| 263 | + ), |
| 264 | + PythonResource::PathExtension(_pe) => println!( |
| 265 | + "PythonPathExtension", |
| 266 | + ), |
| 267 | + } |
| 268 | +} |
| 269 | + |
149 | 270 | /// Initialize a PyOxidizer configuration file in a given directory. |
150 | 271 | pub fn init_config_file( |
151 | 272 | project_dir: &Path, |
|
0 commit comments