Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: check for exposing multiple modules on publish #3838

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,10 @@ jobs:
run: make test
working-directory: ./test/running_modules

- name: test/multi_namespace
run: ./test.sh
working-directory: ./test/multi_namespace

- name: Test FFI in subdirectories
run: make
working-directory: ./test/subdir_ffi
48 changes: 48 additions & 0 deletions compiler-cli/src/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl PublishCommand {
} = do_build_hex_tarball(&paths, &mut config)?;

check_for_name_squatting(&compile_result)?;
check_for_multiple_top_level_modules(&compile_result, i_am_sure)?;

// Build HTML documentation
let docs_tarball = fs::create_tar_archive(docs::build_documentation(
Expand Down Expand Up @@ -123,6 +124,53 @@ fn check_for_name_squatting(package: &Package) -> Result<(), Error> {
Ok(())
}

fn check_for_multiple_top_level_modules(package: &Package, i_am_sure: bool) -> Result<(), Error> {
// Collect top-level module names
let mut top_level_module_names = package
.modules
.iter()
.filter_map(|module| module.name.split('/').next())
.collect::<Vec<_>>();

// Remove duplicates
top_level_module_names.sort_unstable();
top_level_module_names.dedup();

// If more than one top-level module name is found, prompt for confirmation
if top_level_module_names.len() > 1 {
println!(
"Your package defines multiple top-level modules: {}",
top_level_module_names.join(", ")
);
println!(
"Defining multiple top-level modules can lead to namespace pollution \
and potential conflicts for consumers."
);
println!();
println!(
"To fix this, move all your modules under a single top-level module of your choice."
);
println!();
println!("For example:");
println!(
" src/{}.gleam\n src/{}/module1.gleam\n src/{}/module2.gleam",
&package.config.name, &package.config.name, &package.config.name
);
println!();

let should_publish =
i_am_sure || cli::confirm("\nDo you wish to continue publishing this package?")?;
println!();
Guria marked this conversation as resolved.
Show resolved Hide resolved

if !should_publish {
println!("Not publishing.");
std::process::exit(0);
}
}

Ok(())
}

fn check_repo_url(config: &PackageConfig, i_am_sure: bool) -> Result<bool, Error> {
let Some(url) = config.repository.url() else {
return Ok(true);
Expand Down
3 changes: 3 additions & 0 deletions test/multi_namespace/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.beam
*.ez
build
4 changes: 4 additions & 0 deletions test/multi_namespace/gleam.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name = "multi_namespace"
version = "1.0.0"
description = "Test project for multi namespace"
licences = ["Apache-2.0"]
7 changes: 7 additions & 0 deletions test/multi_namespace/manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This file was generated by Gleam
# You typically do not need to edit this file

packages = [
]

[requirements]
3 changes: 3 additions & 0 deletions test/multi_namespace/src/multi_namespace.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn main() {
"Hello from multi_namespace!"
}
3 changes: 3 additions & 0 deletions test/multi_namespace/src/second.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub fn main() {
"Hello from second!"
}
26 changes: 26 additions & 0 deletions test/multi_namespace/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh

set -eu

GLEAM_COMMAND=${GLEAM_COMMAND:-"cargo run --quiet --"}

g() {
echo "Running: $GLEAM_COMMAND $@"
$GLEAM_COMMAND "$@"
}

echo Resetting the build directory to get to a known state
rm -fr build

echo Running publish should not publish anything
output=$(yes "n" | g publish)
if echo "$output" | grep -q "Your package defines multiple top-level modules"; then
echo "Publish was correctly prevented with warning"
else
echo "Expected publish to be aborted"
exit 1
fi

echo
echo Success! 💖
echo