maturin 1.7.7__tar.gz → 1.7.8__tar.gz

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.

Potentially problematic release.


This version of maturin might be problematic. Click here for more details.

Files changed (60) hide show
  1. {maturin-1.7.7 → maturin-1.7.8}/.pre-commit-config.yaml +1 -1
  2. {maturin-1.7.7 → maturin-1.7.8}/Cargo.lock +1 -1
  3. {maturin-1.7.7 → maturin-1.7.8}/Cargo.toml +1 -1
  4. {maturin-1.7.7 → maturin-1.7.8}/PKG-INFO +1 -1
  5. maturin-1.7.8/src/bridge.rs +115 -0
  6. {maturin-1.7.7 → maturin-1.7.8}/src/build_context.rs +2 -117
  7. {maturin-1.7.7 → maturin-1.7.8}/src/build_options.rs +1 -2
  8. {maturin-1.7.7 → maturin-1.7.8}/src/compile.rs +32 -17
  9. {maturin-1.7.7 → maturin-1.7.8}/src/cross_compile.rs +0 -15
  10. {maturin-1.7.7 → maturin-1.7.8}/src/lib.rs +3 -1
  11. {maturin-1.7.7 → maturin-1.7.8}/src/project_layout.rs +10 -1
  12. {maturin-1.7.7 → maturin-1.7.8}/.cirrus.yml +0 -0
  13. {maturin-1.7.7 → maturin-1.7.8}/.codespellrc +0 -0
  14. {maturin-1.7.7 → maturin-1.7.8}/.config/nextest.toml +0 -0
  15. {maturin-1.7.7 → maturin-1.7.8}/.gitignore +0 -0
  16. {maturin-1.7.7 → maturin-1.7.8}/Changelog.md +0 -0
  17. {maturin-1.7.7 → maturin-1.7.8}/MANIFEST.in +0 -0
  18. {maturin-1.7.7 → maturin-1.7.8}/README.md +0 -0
  19. {maturin-1.7.7 → maturin-1.7.8}/clippy.toml +0 -0
  20. {maturin-1.7.7 → maturin-1.7.8}/license-apache +0 -0
  21. {maturin-1.7.7 → maturin-1.7.8}/license-mit +0 -0
  22. {maturin-1.7.7 → maturin-1.7.8}/maturin/__init__.py +0 -0
  23. {maturin-1.7.7 → maturin-1.7.8}/maturin/__main__.py +0 -0
  24. {maturin-1.7.7 → maturin-1.7.8}/maturin.schema.json +0 -0
  25. {maturin-1.7.7 → maturin-1.7.8}/netlify.toml +0 -0
  26. {maturin-1.7.7 → maturin-1.7.8}/pyproject.toml +0 -0
  27. {maturin-1.7.7 → maturin-1.7.8}/setup.py +0 -0
  28. {maturin-1.7.7 → maturin-1.7.8}/src/auditwheel/audit.rs +0 -0
  29. {maturin-1.7.7 → maturin-1.7.8}/src/auditwheel/manylinux-policy.json +0 -0
  30. {maturin-1.7.7 → maturin-1.7.8}/src/auditwheel/mod.rs +0 -0
  31. {maturin-1.7.7 → maturin-1.7.8}/src/auditwheel/musllinux-policy.json +0 -0
  32. {maturin-1.7.7 → maturin-1.7.8}/src/auditwheel/musllinux.rs +0 -0
  33. {maturin-1.7.7 → maturin-1.7.8}/src/auditwheel/patchelf.rs +0 -0
  34. {maturin-1.7.7 → maturin-1.7.8}/src/auditwheel/platform_tag.rs +0 -0
  35. {maturin-1.7.7 → maturin-1.7.8}/src/auditwheel/policy.rs +0 -0
  36. {maturin-1.7.7 → maturin-1.7.8}/src/auditwheel/repair.rs +0 -0
  37. {maturin-1.7.7 → maturin-1.7.8}/src/cargo_toml.rs +0 -0
  38. {maturin-1.7.7 → maturin-1.7.8}/src/ci.rs +0 -0
  39. {maturin-1.7.7 → maturin-1.7.8}/src/develop.rs +0 -0
  40. {maturin-1.7.7 → maturin-1.7.8}/src/generate_json_schema.rs +0 -0
  41. {maturin-1.7.7 → maturin-1.7.8}/src/main.rs +0 -0
  42. {maturin-1.7.7 → maturin-1.7.8}/src/metadata.rs +0 -0
  43. {maturin-1.7.7 → maturin-1.7.8}/src/module_writer.rs +0 -0
  44. {maturin-1.7.7 → maturin-1.7.8}/src/new_project.rs +0 -0
  45. {maturin-1.7.7 → maturin-1.7.8}/src/pyproject_toml.rs +0 -0
  46. {maturin-1.7.7 → maturin-1.7.8}/src/python_interpreter/config.rs +0 -0
  47. {maturin-1.7.7 → maturin-1.7.8}/src/python_interpreter/get_interpreter_metadata.py +0 -0
  48. {maturin-1.7.7 → maturin-1.7.8}/src/python_interpreter/mod.rs +0 -0
  49. {maturin-1.7.7 → maturin-1.7.8}/src/source_distribution.rs +0 -0
  50. {maturin-1.7.7 → maturin-1.7.8}/src/target.rs +0 -0
  51. {maturin-1.7.7 → maturin-1.7.8}/src/templates/.gitignore.j2 +0 -0
  52. {maturin-1.7.7 → maturin-1.7.8}/src/templates/Cargo.toml.j2 +0 -0
  53. {maturin-1.7.7 → maturin-1.7.8}/src/templates/__init__.py.j2 +0 -0
  54. {maturin-1.7.7 → maturin-1.7.8}/src/templates/build.rs.j2 +0 -0
  55. {maturin-1.7.7 → maturin-1.7.8}/src/templates/example.udl.j2 +0 -0
  56. {maturin-1.7.7 → maturin-1.7.8}/src/templates/lib.rs.j2 +0 -0
  57. {maturin-1.7.7 → maturin-1.7.8}/src/templates/main.rs.j2 +0 -0
  58. {maturin-1.7.7 → maturin-1.7.8}/src/templates/pyproject.toml.j2 +0 -0
  59. {maturin-1.7.7 → maturin-1.7.8}/src/templates/test_all.py.j2 +0 -0
  60. {maturin-1.7.7 → maturin-1.7.8}/src/upload.rs +0 -0
@@ -56,7 +56,7 @@ repos:
56
56
  )
57
57
  - id: mixed-line-ending
58
58
  - repo: https://github.com/astral-sh/ruff-pre-commit
59
- rev: v0.8.0
59
+ rev: v0.8.1
60
60
  hooks:
61
61
  - id: ruff-format
62
62
  - id: ruff
@@ -1253,7 +1253,7 @@ dependencies = [
1253
1253
 
1254
1254
  [[package]]
1255
1255
  name = "maturin"
1256
- version = "1.7.7"
1256
+ version = "1.7.8"
1257
1257
  dependencies = [
1258
1258
  "anyhow",
1259
1259
  "base64 0.21.7",
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  authors = ["konstin <konstin@mailbox.org>", "messense <messense@icloud.com>"]
3
3
  name = "maturin"
4
- version = "1.7.7"
4
+ version = "1.7.8"
5
5
  description = "Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages"
6
6
  exclude = [
7
7
  "test-crates/**/*",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maturin
3
- Version: 1.7.7
3
+ Version: 1.7.8
4
4
  Classifier: Topic :: Software Development :: Build Tools
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -0,0 +1,115 @@
1
+ use std::fmt::{Display, Formatter};
2
+
3
+ /// The name and version of the bindings crate
4
+ #[derive(Clone, Debug, PartialEq, Eq)]
5
+ pub struct Bindings {
6
+ /// The name of the bindings crate, `pyo3`, `rust-cpython` or `uniffi`
7
+ pub name: String,
8
+ /// bindings crate version
9
+ pub version: semver::Version,
10
+ }
11
+
12
+ impl Bindings {
13
+ /// Returns the minimum python minor version supported
14
+ pub fn minimal_python_minor_version(&self) -> usize {
15
+ use crate::python_interpreter::MINIMUM_PYTHON_MINOR;
16
+
17
+ match self.name.as_str() {
18
+ "pyo3" | "pyo3-ffi" => {
19
+ let major_version = self.version.major;
20
+ let minor_version = self.version.minor;
21
+ // N.B. must check large minor versions first
22
+ if (major_version, minor_version) >= (0, 16) {
23
+ 7
24
+ } else {
25
+ MINIMUM_PYTHON_MINOR
26
+ }
27
+ }
28
+ _ => MINIMUM_PYTHON_MINOR,
29
+ }
30
+ }
31
+
32
+ /// Returns the minimum PyPy minor version supported
33
+ pub fn minimal_pypy_minor_version(&self) -> usize {
34
+ use crate::python_interpreter::MINIMUM_PYPY_MINOR;
35
+
36
+ match self.name.as_str() {
37
+ "pyo3" | "pyo3-ffi" => {
38
+ let major_version = self.version.major;
39
+ let minor_version = self.version.minor;
40
+ // N.B. must check large minor versions first
41
+ if (major_version, minor_version) >= (0, 23) {
42
+ 9
43
+ } else if (major_version, minor_version) >= (0, 14) {
44
+ 7
45
+ } else {
46
+ MINIMUM_PYPY_MINOR
47
+ }
48
+ }
49
+ _ => MINIMUM_PYPY_MINOR,
50
+ }
51
+ }
52
+ }
53
+
54
+ /// The way the rust code is used in the wheel
55
+ #[derive(Clone, Debug, PartialEq, Eq)]
56
+ pub enum BridgeModel {
57
+ /// A rust binary to be shipped a python package
58
+ Bin(Option<Bindings>),
59
+ /// A native module with pyo3 or rust-cpython bindings.
60
+ Bindings(Bindings),
61
+ /// `Bindings`, but specifically for pyo3 with feature flags that allow building a single wheel
62
+ /// for all cpython versions (pypy & graalpy still need multiple versions).
63
+ /// The numbers are the minimum major and minor version
64
+ BindingsAbi3(u8, u8),
65
+ /// A native module with c bindings, i.e. `#[no_mangle] extern "C" <some item>`
66
+ Cffi,
67
+ /// A native module generated from uniffi
68
+ UniFfi,
69
+ }
70
+
71
+ impl BridgeModel {
72
+ /// Returns the bindings
73
+ pub fn bindings(&self) -> Option<&Bindings> {
74
+ match self {
75
+ BridgeModel::Bin(Some(bindings)) => Some(bindings),
76
+ BridgeModel::Bindings(bindings) => Some(bindings),
77
+ _ => None,
78
+ }
79
+ }
80
+
81
+ /// Returns the name of the bindings crate
82
+ pub fn unwrap_bindings_name(&self) -> &str {
83
+ match self {
84
+ BridgeModel::Bindings(bindings) => &bindings.name,
85
+ _ => panic!("Expected Bindings"),
86
+ }
87
+ }
88
+
89
+ /// Test whether this is using a specific bindings crate
90
+ pub fn is_bindings(&self, name: &str) -> bool {
91
+ match self {
92
+ BridgeModel::Bin(Some(bindings)) => bindings.name == name,
93
+ BridgeModel::Bindings(bindings) => bindings.name == name,
94
+ _ => false,
95
+ }
96
+ }
97
+
98
+ /// Test whether this is bin bindings
99
+ pub fn is_bin(&self) -> bool {
100
+ matches!(self, BridgeModel::Bin(_))
101
+ }
102
+ }
103
+
104
+ impl Display for BridgeModel {
105
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
106
+ match self {
107
+ BridgeModel::Bin(Some(bindings)) => write!(f, "{} bin", bindings.name),
108
+ BridgeModel::Bin(None) => write!(f, "bin"),
109
+ BridgeModel::Bindings(bindings) => write!(f, "{}", bindings.name),
110
+ BridgeModel::BindingsAbi3(..) => write!(f, "pyo3"),
111
+ BridgeModel::Cffi => write!(f, "cffi"),
112
+ BridgeModel::UniFfi => write!(f, "uniffi"),
113
+ }
114
+ }
115
+ }
@@ -10,8 +10,8 @@ use crate::project_layout::ProjectLayout;
10
10
  use crate::source_distribution::source_distribution;
11
11
  use crate::target::{Arch, Os};
12
12
  use crate::{
13
- compile, pyproject_toml::Format, BuildArtifact, Metadata23, ModuleWriter, PyProjectToml,
14
- PythonInterpreter, Target,
13
+ compile, pyproject_toml::Format, BridgeModel, BuildArtifact, Metadata23, ModuleWriter,
14
+ PyProjectToml, PythonInterpreter, Target,
15
15
  };
16
16
  use anyhow::{anyhow, bail, Context, Result};
17
17
  use cargo_metadata::CrateType;
@@ -26,126 +26,11 @@ use platform_info::*;
26
26
  use sha2::{Digest, Sha256};
27
27
  use std::collections::{BTreeMap, HashSet};
28
28
  use std::env;
29
- use std::fmt::{Display, Formatter};
30
29
  use std::io;
31
30
  use std::path::{Path, PathBuf};
32
31
  use std::str::FromStr;
33
32
  use tracing::instrument;
34
33
 
35
- /// The name and version of the bindings crate
36
- #[derive(Clone, Debug, PartialEq, Eq)]
37
- pub struct Bindings {
38
- /// The name of the bindings crate, `pyo3`, `rust-cpython` or `uniffi`
39
- pub name: String,
40
- /// bindings crate version
41
- pub version: semver::Version,
42
- }
43
-
44
- impl Bindings {
45
- /// Returns the minimum python minor version supported
46
- pub fn minimal_python_minor_version(&self) -> usize {
47
- use crate::python_interpreter::MINIMUM_PYTHON_MINOR;
48
-
49
- match self.name.as_str() {
50
- "pyo3" | "pyo3-ffi" => {
51
- let major_version = self.version.major;
52
- let minor_version = self.version.minor;
53
- // N.B. must check large minor versions first
54
- if (major_version, minor_version) >= (0, 16) {
55
- 7
56
- } else {
57
- MINIMUM_PYTHON_MINOR
58
- }
59
- }
60
- _ => MINIMUM_PYTHON_MINOR,
61
- }
62
- }
63
-
64
- /// Returns the minimum PyPy minor version supported
65
- pub fn minimal_pypy_minor_version(&self) -> usize {
66
- use crate::python_interpreter::MINIMUM_PYPY_MINOR;
67
-
68
- match self.name.as_str() {
69
- "pyo3" | "pyo3-ffi" => {
70
- let major_version = self.version.major;
71
- let minor_version = self.version.minor;
72
- // N.B. must check large minor versions first
73
- if (major_version, minor_version) >= (0, 23) {
74
- 9
75
- } else if (major_version, minor_version) >= (0, 14) {
76
- 7
77
- } else {
78
- MINIMUM_PYPY_MINOR
79
- }
80
- }
81
- _ => MINIMUM_PYPY_MINOR,
82
- }
83
- }
84
- }
85
-
86
- /// The way the rust code is used in the wheel
87
- #[derive(Clone, Debug, PartialEq, Eq)]
88
- pub enum BridgeModel {
89
- /// A rust binary to be shipped a python package
90
- Bin(Option<Bindings>),
91
- /// A native module with pyo3 or rust-cpython bindings.
92
- Bindings(Bindings),
93
- /// `Bindings`, but specifically for pyo3 with feature flags that allow building a single wheel
94
- /// for all cpython versions (pypy & graalpy still need multiple versions).
95
- /// The numbers are the minimum major and minor version
96
- BindingsAbi3(u8, u8),
97
- /// A native module with c bindings, i.e. `#[no_mangle] extern "C" <some item>`
98
- Cffi,
99
- /// A native module generated from uniffi
100
- UniFfi,
101
- }
102
-
103
- impl BridgeModel {
104
- /// Returns the bindings
105
- pub fn bindings(&self) -> Option<&Bindings> {
106
- match self {
107
- BridgeModel::Bin(Some(bindings)) => Some(bindings),
108
- BridgeModel::Bindings(bindings) => Some(bindings),
109
- _ => None,
110
- }
111
- }
112
-
113
- /// Returns the name of the bindings crate
114
- pub fn unwrap_bindings_name(&self) -> &str {
115
- match self {
116
- BridgeModel::Bindings(bindings) => &bindings.name,
117
- _ => panic!("Expected Bindings"),
118
- }
119
- }
120
-
121
- /// Test whether this is using a specific bindings crate
122
- pub fn is_bindings(&self, name: &str) -> bool {
123
- match self {
124
- BridgeModel::Bin(Some(bindings)) => bindings.name == name,
125
- BridgeModel::Bindings(bindings) => bindings.name == name,
126
- _ => false,
127
- }
128
- }
129
-
130
- /// Test whether this is bin bindings
131
- pub fn is_bin(&self) -> bool {
132
- matches!(self, BridgeModel::Bin(_))
133
- }
134
- }
135
-
136
- impl Display for BridgeModel {
137
- fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
138
- match self {
139
- BridgeModel::Bin(Some(bindings)) => write!(f, "{} bin", bindings.name),
140
- BridgeModel::Bin(None) => write!(f, "bin"),
141
- BridgeModel::Bindings(bindings) => write!(f, "{}", bindings.name),
142
- BridgeModel::BindingsAbi3(..) => write!(f, "pyo3"),
143
- BridgeModel::Cffi => write!(f, "cffi"),
144
- BridgeModel::UniFfi => write!(f, "uniffi"),
145
- }
146
- }
147
- }
148
-
149
34
  /// Insert wasm launcher scripts as entrypoints and the wasmtime dependency
150
35
  fn bin_wasi_helper(
151
36
  artifacts_and_files: &[(&BuildArtifact, String)],
@@ -1,11 +1,10 @@
1
1
  use crate::auditwheel::{AuditWheelMode, PlatformTag};
2
- use crate::build_context::BridgeModel;
3
2
  use crate::compile::{CompileTarget, LIB_CRATE_TYPES};
4
3
  use crate::cross_compile::{find_sysconfigdata, parse_sysconfigdata};
5
4
  use crate::project_layout::ProjectResolver;
6
5
  use crate::pyproject_toml::ToolMaturin;
7
6
  use crate::python_interpreter::{InterpreterConfig, InterpreterKind};
8
- use crate::{Bindings, BuildContext, PythonInterpreter, Target};
7
+ use crate::{Bindings, BridgeModel, BuildContext, PythonInterpreter, Target};
9
8
  use anyhow::{bail, format_err, Context, Result};
10
9
  use cargo_metadata::{CrateType, TargetKind};
11
10
  use cargo_metadata::{Metadata, Node};
@@ -1,8 +1,7 @@
1
- use crate::build_context::BridgeModel;
2
1
  use crate::target::RUST_1_64_0;
3
2
  #[cfg(feature = "zig")]
4
3
  use crate::PlatformTag;
5
- use crate::{BuildContext, PythonInterpreter, Target};
4
+ use crate::{BridgeModel, BuildContext, PythonInterpreter, Target};
6
5
  use anyhow::{anyhow, bail, Context, Result};
7
6
  use cargo_metadata::CrateType;
8
7
  use fat_macho::FatWriter;
@@ -287,24 +286,40 @@ fn cargo_build_command(
287
286
  .extend(["-C".to_string(), "strip=symbols".to_string()]);
288
287
  }
289
288
 
290
- let mut build_command = if target.is_msvc()
291
- && (target.cross_compiling() || env::var("MATURIN_USE_XWIN").ok().as_deref() == Some("1"))
292
- {
289
+ let mut build_command = if target.is_msvc() && target.cross_compiling() {
293
290
  #[cfg(feature = "xwin")]
294
291
  {
295
- println!("🛠️ Using xwin for cross-compiling to {target_triple}");
296
- let xwin_options = {
297
- use clap::Parser;
298
-
299
- // This will populate the default values for the options
300
- // and then override them with cargo-xwin environment variables.
301
- cargo_xwin::XWinOptions::parse_from(Vec::<&str>::new())
302
- };
292
+ // Don't use xwin if the Windows MSVC compiler can compile to the target
293
+ let native_compile = cc::Build::new()
294
+ .opt_level(0)
295
+ .host(target.host_triple())
296
+ .target(target_triple)
297
+ .cargo_metadata(false)
298
+ .cargo_warnings(false)
299
+ .cargo_output(false)
300
+ .try_get_compiler()
301
+ .is_ok();
302
+ let force_xwin = env::var("MATURIN_USE_XWIN").ok().as_deref() == Some("1");
303
+ if !native_compile || force_xwin {
304
+ println!("🛠️ Using xwin for cross-compiling to {target_triple}");
305
+ let xwin_options = {
306
+ use clap::Parser;
307
+
308
+ // This will populate the default values for the options
309
+ // and then override them with cargo-xwin environment variables.
310
+ cargo_xwin::XWinOptions::parse_from(Vec::<&str>::new())
311
+ };
303
312
 
304
- let mut build = cargo_xwin::Rustc::from(cargo_rustc);
305
- build.target = vec![target_triple.to_string()];
306
- build.xwin = xwin_options;
307
- build.build_command()?
313
+ let mut build = cargo_xwin::Rustc::from(cargo_rustc);
314
+ build.target = vec![target_triple.to_string()];
315
+ build.xwin = xwin_options;
316
+ build.build_command()?
317
+ } else {
318
+ if target.user_specified {
319
+ cargo_rustc.target = vec![target_triple.to_string()];
320
+ }
321
+ cargo_rustc.command()
322
+ }
308
323
  }
309
324
  #[cfg(not(feature = "xwin"))]
310
325
  {
@@ -27,21 +27,6 @@ pub fn is_cross_compiling(target: &Target) -> Result<bool> {
27
27
  // Not cross-compiling to compile for 32-bit Python from windows 64-bit
28
28
  return Ok(false);
29
29
  }
30
- if (target_triple == "aarch64-pc-windows-msvc" && host == "x86_64-pc-windows-msvc")
31
- || (target_triple == "x86_64-pc-windows-msvc" && host == "aarch64-pc-windows-msvc")
32
- {
33
- // Not cross-compiling if the Windows MSVC compiler can compile to the target
34
- let native_compile = cc::Build::new()
35
- .opt_level(0)
36
- .host(host)
37
- .target(target_triple)
38
- .cargo_metadata(false)
39
- .cargo_warnings(false)
40
- .cargo_output(false)
41
- .try_get_compiler()
42
- .is_ok();
43
- return Ok(!native_compile);
44
- }
45
30
  if target_triple.ends_with("windows-gnu") && host.ends_with("windows-msvc") {
46
31
  // Not cross-compiling to compile for Windows GNU from Windows MSVC host
47
32
  return Ok(false);
@@ -23,7 +23,8 @@
23
23
 
24
24
  #![deny(missing_docs)]
25
25
 
26
- pub use crate::build_context::{Bindings, BridgeModel, BuildContext, BuiltWheelMetadata};
26
+ pub use crate::bridge::{Bindings, BridgeModel};
27
+ pub use crate::build_context::{BuildContext, BuiltWheelMetadata};
27
28
  pub use crate::build_options::{BuildOptions, CargoOptions};
28
29
  pub use crate::cargo_toml::CargoToml;
29
30
  pub use crate::compile::{compile, BuildArtifact};
@@ -44,6 +45,7 @@ pub use crate::upload::{upload, upload_ui, PublishOpt, Registry, UploadError};
44
45
  pub use auditwheel::PlatformTag;
45
46
 
46
47
  mod auditwheel;
48
+ mod bridge;
47
49
  mod build_context;
48
50
  mod build_options;
49
51
  mod cargo_toml;
@@ -144,7 +144,16 @@ impl ProjectResolver {
144
144
  .unwrap_or_default()
145
145
  .to_vec();
146
146
  let py_root = match pyproject.and_then(|x| x.python_source()) {
147
- Some(py_src) => project_root.join(py_src).normalize()?.into_path_buf(),
147
+ Some(py_src) => project_root
148
+ .join(py_src)
149
+ .normalize()
150
+ .with_context(|| {
151
+ format!(
152
+ "Failed to normalize python source path `{}`",
153
+ py_src.display()
154
+ )
155
+ })?
156
+ .into_path_buf(),
148
157
  None => match pyproject.and_then(|x| x.project_name()) {
149
158
  Some(project_name) => {
150
159
  // Detect src layout
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes