Skip to content

Commit c23b56c

Browse files
authored
make componentize-py.toml selection smarter (#70)
If multiple versions of a give module appear in `PYTHON_PATH`, each with a componentize-py.toml, we'll now use the first one and ignore any others. Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent c7b0031 commit c23b56c

1 file changed

Lines changed: 40 additions & 11 deletions

File tree

src/lib.rs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -632,18 +632,47 @@ fn search_directory(
632632
let path = path.canonicalize()?;
633633
let existing_path = existing_path.join("componentize-py.toml").canonicalize()?;
634634
if path != existing_path {
635-
bail!(
636-
"multiple componentize-py.toml files found, \
637-
which is not yet supported: {} and {}",
638-
existing_path.display(),
639-
path.display()
640-
);
635+
// If we find a componentize-py.toml file under a Python module which will not be used because
636+
// we already found a version of that module in an earlier `PYTHON_PATH` directory, we'll
637+
// ignore the latest one.
638+
//
639+
// For example, if the module `foo_sdk` appears twice in `PYTHON_PATH`, and both versions have
640+
// a componentize-py.toml file, we'll ignore the second one just as Python will ignore the
641+
// second module.
642+
let superseded = if let (Ok(relative), Ok(existing_relative)) = (
643+
path.strip_prefix(root.canonicalize()?),
644+
existing_path.strip_prefix(existing_root.canonicalize()?),
645+
) {
646+
matches!(
647+
(
648+
&relative.iter().collect::<Vec<_>>()[..],
649+
&existing_relative.iter().collect::<Vec<_>>()[..]
650+
),
651+
(
652+
[first, _, ..],
653+
[existing_first, _, ..]
654+
) if first == existing_first
655+
)
656+
} else {
657+
false
658+
};
659+
660+
if superseded {
661+
false
662+
} else {
663+
bail!(
664+
"multiple componentize-py.toml files found, \
665+
which is not yet supported: {} and {}",
666+
existing_path.display(),
667+
path.display()
668+
);
669+
}
670+
} else {
671+
// When one directory in `PYTHON_PATH` is a subdirectory of the other, we consider the
672+
// subdirectory to be the true owner of the file. This is important later, when we derive a
673+
// package name by stripping the root directory from the file path.
674+
root.canonicalize()? > existing_root.canonicalize()?
641675
}
642-
643-
// When one directory in `PYTHON_PATH` is a subdirectory of the other, we consider the subdirectory
644-
// to be the true owner of the file. This is important later, when we derive a package name by
645-
// stripping the root directory from the file path.
646-
root.canonicalize()? > existing_root.canonicalize()?
647676
} else {
648677
true
649678
};

0 commit comments

Comments
 (0)