Skip to content

Commit 4dd680b

Browse files
committed
feat: check for exposing multiple modules on publish
1 parent 962f3df commit 4dd680b

File tree

8 files changed

+87
-0
lines changed

8 files changed

+87
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,3 +419,7 @@ jobs:
419419
- name: Test running modules
420420
run: make test
421421
working-directory: ./test/running_modules
422+
423+
- name: test/multi_namespace
424+
run: ./test.sh
425+
working-directory: ./test/multi_namespace

compiler-cli/src/publish.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ impl PublishCommand {
5656
} = do_build_hex_tarball(&paths, &mut config)?;
5757

5858
check_for_name_squatting(&compile_result)?;
59+
check_for_multiple_top_level_modules(&compile_result, i_am_sure)?;
5960

6061
// Build HTML documentation
6162
let docs_tarball = fs::create_tar_archive(docs::build_documentation(
@@ -123,6 +124,42 @@ fn check_for_name_squatting(package: &Package) -> Result<(), Error> {
123124
Ok(())
124125
}
125126

127+
fn check_for_multiple_top_level_modules(package: &Package, i_am_sure: bool) -> Result<(), Error> {
128+
// Collect top-level module names
129+
let mut top_level_module_names = package
130+
.modules
131+
.iter()
132+
.filter_map(|module| module.name.split('/').next())
133+
.collect::<Vec<_>>();
134+
135+
// Remove duplicates
136+
top_level_module_names.sort_unstable();
137+
top_level_module_names.dedup();
138+
139+
// If more than one top-level module name is found, prompt for confirmation
140+
if top_level_module_names.len() > 1 {
141+
println!(
142+
"Your package defines multiple top-level modules: {}",
143+
top_level_module_names.join(", ")
144+
);
145+
println!(
146+
"Defining multiple top-level modules can lead to namespace pollution \
147+
and potential conflicts for consumers."
148+
);
149+
150+
let should_publish =
151+
i_am_sure || cli::confirm("\nDo you wish to continue publishing this package?")?;
152+
println!();
153+
154+
if !should_publish {
155+
println!("Not publishing.");
156+
std::process::exit(0);
157+
}
158+
}
159+
160+
Ok(())
161+
}
162+
126163
fn check_repo_url(config: &PackageConfig, i_am_sure: bool) -> Result<bool, Error> {
127164
let Some(url) = config.repository.url() else {
128165
return Ok(true);

test/multi_namespace/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.beam
2+
*.ez
3+
build

test/multi_namespace/gleam.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name = "multi_namespace"
2+
version = "1.0.0"
3+
description = "Test project for multi namespace"
4+
licences = ["Apache-2.0"]

test/multi_namespace/manifest.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# This file was generated by Gleam
2+
# You typically do not need to edit this file
3+
4+
packages = [
5+
]
6+
7+
[requirements]

test/multi_namespace/src/foo.gleam

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn main() {
2+
"Hello from foo!"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn main() {
2+
"Hello from multi_namespace!"
3+
}

test/multi_namespace/test.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/sh
2+
3+
set -eu
4+
5+
GLEAM_COMMAND=${GLEAM_COMMAND:-"cargo run --quiet --"}
6+
7+
g() {
8+
echo "Running: $GLEAM_COMMAND $@"
9+
$GLEAM_COMMAND "$@"
10+
}
11+
12+
echo Resetting the build directory to get to a known state
13+
rm -fr build
14+
15+
echo Running publish should not publish anything
16+
output=$(yes "n" | g publish)
17+
if echo "$output" | grep -q "Your package defines multiple top-level modules"; then
18+
echo "Publish was correctly prevented with warning"
19+
else
20+
echo "Expected publish to be aborted"
21+
exit 1
22+
fi
23+
24+
echo
25+
echo Success! 💖
26+
echo

0 commit comments

Comments
 (0)