From 567464e620ef7b705c67391f77ce40684891c5ed Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Sun, 15 Feb 2026 14:49:29 +0100 Subject: [PATCH 1/3] do not allow publishing with default readme --- CHANGELOG.md | 8 ++- compiler-cli/src/new.rs | 59 ++++++++++--------- compiler-cli/src/publish.rs | 25 +++++++- compiler-core/src/error.rs | 24 ++++++++ test/publishing_default_readme/.gitignore | 3 + test/publishing_default_readme/README.md | 24 ++++++++ test/publishing_default_readme/gleam.toml | 7 +++ test/publishing_default_readme/manifest.toml | 9 +++ .../src/default_readme.gleam | 21 +++++++ test/publishing_default_readme/test.sh | 23 ++++++++ 10 files changed, 172 insertions(+), 31 deletions(-) create mode 100644 test/publishing_default_readme/.gitignore create mode 100644 test/publishing_default_readme/README.md create mode 100644 test/publishing_default_readme/gleam.toml create mode 100644 test/publishing_default_readme/manifest.toml create mode 100644 test/publishing_default_readme/src/default_readme.gleam create mode 100755 test/publishing_default_readme/test.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index db04eb99410..c9fcd8a649b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ ([Louis Pilfold](https://github.com/lpil)) - The build tool now emits errors for unknown fields in package config, - except ones under `[tools]`. For example, with this: + except for the ones under `[tools]`. For example, with this: ```toml name = "hello" @@ -58,7 +58,7 @@ my-awesome-setting = true ``` - Building the project will emit error. + Building the project will emit an error. ([Andrey Kozhev](https://github.com/ankddev)) @@ -70,6 +70,10 @@ arguments by taking into account, whether it's a function or a constructor. ([Andrey Kozhev](https://github.com/ankddev)) +- The build tool will now refuse to publish any package that has the default + README generated by the `gleam new` command. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + ### Language server - The language server now allows extracting the start of a pipeline into a diff --git a/compiler-cli/src/new.rs b/compiler-cli/src/new.rs index 75abf7c24b0..bbdeeec7a18 100644 --- a/compiler-cli/src/new.rs +++ b/compiler-cli/src/new.rs @@ -84,34 +84,7 @@ impl FileToCreate { }; match self { - Self::Readme => Some(format!( - r#"# {project_name} - -[![Package Version](https://img.shields.io/hexpm/v/{project_name})](https://hex.pm/packages/{project_name}) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/{project_name}/) - -```sh -gleam add {project_name}@1 -``` -```gleam -import {project_name} - -pub fn main() -> Nil {{ - // TODO: An example of the project in use -}} -``` - -Further documentation can be found at . - -## Development - -```sh -gleam run # Run the project -gleam test # Run the tests -``` -"#, - )), - + Self::Readme => Some(default_readme(project_name)), Self::Gitignore if !skip_git => Some( "*.beam *.ez @@ -202,6 +175,36 @@ jobs: } } +pub fn default_readme(project_name: &str) -> String { + format!( + r#"# {project_name} + +[![Package Version](https://img.shields.io/hexpm/v/{project_name})](https://hex.pm/packages/{project_name}) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/{project_name}/) + +```sh +gleam add {project_name}@1 +``` +```gleam +import {project_name} + +pub fn main() -> Nil {{ + // TODO: An example of the project in use +}} +``` + +Further documentation can be found at . + +## Development + +```sh +gleam run # Run the project +gleam test # Run the tests +``` +"#, + ) +} + impl Creator { fn new(options: NewOptions, gleam_version: &'static str) -> Result { Self::new_with_confirmation(options, gleam_version, crate::cli::confirm) diff --git a/compiler-cli/src/publish.rs b/compiler-cli/src/publish.rs index ff8d4eae054..e135be2771a 100644 --- a/compiler-cli/src/publish.rs +++ b/compiler-cli/src/publish.rs @@ -20,7 +20,7 @@ use itertools::Itertools; use sha2::Digest; use std::{collections::HashMap, io::Write, path::PathBuf, time::Instant}; -use crate::{build, cli, docs, fs, http::HttpClient}; +use crate::{build, cli, docs, fs, http::HttpClient, new::default_readme}; const CORE_TEAM_PUBLISH_PASSWORD: &str = "Trans rights are human rights"; @@ -31,6 +31,8 @@ pub fn command(paths: &ProjectPaths, replace: bool, i_am_sure: bool) -> Result<( && check_for_version_zero(&config)? && check_repo_url(&config, i_am_sure)?; + check_for_default_readme(&config, paths)?; + if !should_publish { println!("Not publishing."); return Ok(()); @@ -130,6 +132,27 @@ HTML documentation will work: Ok(()) } +fn check_for_default_readme(config: &PackageConfig, paths: &ProjectPaths) -> Result<(), Error> { + let default_readme = default_readme(config.name.as_str()); + let project_readme = fs::read(paths.readme())?; + + // We consider the two READMEs equal modulo whitespace, otherwise it would + // be pretty trivial to trick this check by just formatting the default + // README differently. + let normalise = |string: String| { + string + .replace("\r\n", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", "") + }; + if normalise(project_readme) == normalise(default_readme) { + Err(Error::CannotPublishWithDefaultReadme) + } else { + Ok(()) + } +} + fn check_for_name_squatting(package: &Package) -> Result<(), Error> { if package.modules.len() > 1 { return Ok(()); diff --git a/compiler-core/src/error.rs b/compiler-core/src/error.rs index 1a751875c66..037617553ae 100644 --- a/compiler-core/src/error.rs +++ b/compiler-core/src/error.rs @@ -312,6 +312,9 @@ file_names.iter().map(|x| x.as_str()).join(", "))] #[error("The modules {unfinished:?} are empty and so cannot be published")] CannotPublishEmptyModules { unfinished: Vec }, + #[error("Publishing a package with the default README is not permitted")] + CannotPublishWithDefaultReadme, + #[error("Publishing packages to reserve names is not permitted")] HexPackageSquatting, @@ -862,6 +865,27 @@ package deletion or account suspension. }] } + Error::CannotPublishWithDefaultReadme => { + let text = + "You appear to be attempting to publish a package with the default README +generated by the `gleam new` command. That is meant as a placeholder and a +published package should have its own carefully written README. +" + .into(); + + vec![Diagnostic { + title: "Cannot publish with default README".into(), + text, + level: Level::Error, + location: None, + hint: Some( + "Update your project's README to describe it before publishing".into(), + ), + }] + } + }] + } + Error::CannotPublishWithDefaultMain { package_name } => { let text = wrap_format!( "Packages with the default main function cannot be published diff --git a/test/publishing_default_readme/.gitignore b/test/publishing_default_readme/.gitignore new file mode 100644 index 00000000000..c1dc9b0dd00 --- /dev/null +++ b/test/publishing_default_readme/.gitignore @@ -0,0 +1,3 @@ +*.beam +*.ez +build diff --git a/test/publishing_default_readme/README.md b/test/publishing_default_readme/README.md new file mode 100644 index 00000000000..bf7a3b0c07e --- /dev/null +++ b/test/publishing_default_readme/README.md @@ -0,0 +1,24 @@ +# default_readme + +[![Package Version](https://img.shields.io/hexpm/v/default_readme)](https://hex.pm/packages/default_readme) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/default_readme/) + +```sh +gleam add default_readme@1 +``` +```gleam +import default_readme + +pub fn main() -> Nil { + // TODO: An example of the project in use +} +``` + +Further documentation can be found at . + +## Development + +```sh +gleam run # Run the project +gleam test # Run the tests +``` diff --git a/test/publishing_default_readme/gleam.toml b/test/publishing_default_readme/gleam.toml new file mode 100644 index 00000000000..76042ba249a --- /dev/null +++ b/test/publishing_default_readme/gleam.toml @@ -0,0 +1,7 @@ +name = "default_readme" +version = "1.0.0" +description = "Test project for default readme" +licences = ["Apache-2.0"] + +[dependencies] +gleam_stdlib = ">= 0.44.0 and < 2.0.0" diff --git a/test/publishing_default_readme/manifest.toml b/test/publishing_default_readme/manifest.toml new file mode 100644 index 00000000000..88377adc600 --- /dev/null +++ b/test/publishing_default_readme/manifest.toml @@ -0,0 +1,9 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "gleam_stdlib", version = "0.62.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "0080706D3A5A9A36C40C68481D1D231D243AF602E6D2A2BE67BA8F8F4DFF45EC" }, +] + +[requirements] +gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" } diff --git a/test/publishing_default_readme/src/default_readme.gleam b/test/publishing_default_readme/src/default_readme.gleam new file mode 100644 index 00000000000..85abef09193 --- /dev/null +++ b/test/publishing_default_readme/src/default_readme.gleam @@ -0,0 +1,21 @@ +import gleam/io + +/// This tests that a project with a default readme doesn't get published. +/// +pub fn main() -> Nil { + greeting() + first_line() + second_line() +} + +fn greeting() { + io.println("Hello from default_readme!") +} + +fn first_line() { + io.println("Here we have some additional code so that this is not mistaken") +} + +fn second_line() { + io.println("for a default main project, that would be rejected as well!") +} diff --git a/test/publishing_default_readme/test.sh b/test/publishing_default_readme/test.sh new file mode 100755 index 00000000000..d534ee4793e --- /dev/null +++ b/test/publishing_default_readme/test.sh @@ -0,0 +1,23 @@ +#!/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 +if yes "n" | g publish; then + echo "Expected publish to fail, but it succeeded" + exit 1 +fi + +echo +echo Success! 💖 +echo From 2a24d0b78b2a7ec9df71c26c507e9da70365c70f Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Sun, 15 Feb 2026 15:36:28 +0100 Subject: [PATCH 2/3] refuse to publish packages with no readme --- CHANGELOG.md | 3 +++ compiler-cli/src/publish.rs | 10 +++++++- compiler-core/src/error.rs | 16 +++++++++++++ test/publishing_no_readme/.gitignore | 3 +++ test/publishing_no_readme/gleam.toml | 7 ++++++ test/publishing_no_readme/manifest.toml | 9 ++++++++ test/publishing_no_readme/src/no_readme.gleam | 21 +++++++++++++++++ test/publishing_no_readme/test.sh | 23 +++++++++++++++++++ 8 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 test/publishing_no_readme/.gitignore create mode 100644 test/publishing_no_readme/gleam.toml create mode 100644 test/publishing_no_readme/manifest.toml create mode 100644 test/publishing_no_readme/src/no_readme.gleam create mode 100755 test/publishing_no_readme/test.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index c9fcd8a649b..33e3327a9e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,9 @@ README generated by the `gleam new` command. ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) +- The build tool will now refuse to publish any package that has no README. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + ### Language server - The language server now allows extracting the start of a pipeline into a diff --git a/compiler-cli/src/publish.rs b/compiler-cli/src/publish.rs index e135be2771a..c1f99bcf707 100644 --- a/compiler-cli/src/publish.rs +++ b/compiler-cli/src/publish.rs @@ -134,7 +134,15 @@ HTML documentation will work: fn check_for_default_readme(config: &PackageConfig, paths: &ProjectPaths) -> Result<(), Error> { let default_readme = default_readme(config.name.as_str()); - let project_readme = fs::read(paths.readme())?; + let project_readme = match fs::read(paths.readme()) { + Err(Error::FileIo { + err: Some(message), .. + }) if message.contains("No such file or directory") => { + return Err(Error::CannotPublishWithNoReadme); + } + Err(error) => return Err(error), + Ok(project_readme) => project_readme, + }; // We consider the two READMEs equal modulo whitespace, otherwise it would // be pretty trivial to trick this check by just formatting the default diff --git a/compiler-core/src/error.rs b/compiler-core/src/error.rs index 037617553ae..d5ef70bdb2e 100644 --- a/compiler-core/src/error.rs +++ b/compiler-core/src/error.rs @@ -315,6 +315,9 @@ file_names.iter().map(|x| x.as_str()).join(", "))] #[error("Publishing a package with the default README is not permitted")] CannotPublishWithDefaultReadme, + #[error("Publishing a package with no README is not permitted")] + CannotPublishWithNoReadme, + #[error("Publishing packages to reserve names is not permitted")] HexPackageSquatting, @@ -883,6 +886,19 @@ published package should have its own carefully written README. ), }] } + + Error::CannotPublishWithNoReadme => { + let text = "You appear to be attempting to publish a package with no README. +All published packages should have one. +" + .into(); + + vec![Diagnostic { + title: "Cannot publish with no README".into(), + text, + level: Level::Error, + location: None, + hint: Some("Add a README to your project before publishing.".into()), }] } diff --git a/test/publishing_no_readme/.gitignore b/test/publishing_no_readme/.gitignore new file mode 100644 index 00000000000..c1dc9b0dd00 --- /dev/null +++ b/test/publishing_no_readme/.gitignore @@ -0,0 +1,3 @@ +*.beam +*.ez +build diff --git a/test/publishing_no_readme/gleam.toml b/test/publishing_no_readme/gleam.toml new file mode 100644 index 00000000000..4e33df4fe8a --- /dev/null +++ b/test/publishing_no_readme/gleam.toml @@ -0,0 +1,7 @@ +name = "no_readme" +version = "1.0.0" +description = "Test project for no readme" +licences = ["Apache-2.0"] + +[dependencies] +gleam_stdlib = ">= 0.44.0 and < 2.0.0" diff --git a/test/publishing_no_readme/manifest.toml b/test/publishing_no_readme/manifest.toml new file mode 100644 index 00000000000..88377adc600 --- /dev/null +++ b/test/publishing_no_readme/manifest.toml @@ -0,0 +1,9 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "gleam_stdlib", version = "0.62.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "0080706D3A5A9A36C40C68481D1D231D243AF602E6D2A2BE67BA8F8F4DFF45EC" }, +] + +[requirements] +gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" } diff --git a/test/publishing_no_readme/src/no_readme.gleam b/test/publishing_no_readme/src/no_readme.gleam new file mode 100644 index 00000000000..65db7252dc3 --- /dev/null +++ b/test/publishing_no_readme/src/no_readme.gleam @@ -0,0 +1,21 @@ +import gleam/io + +/// This tests that a project with no readme doesn't get published. +/// +pub fn main() -> Nil { + greeting() + first_line() + second_line() +} + +fn greeting() { + io.println("Hello from no_readme!") +} + +fn first_line() { + io.println("Here we have some additional code so that this is not mistaken") +} + +fn second_line() { + io.println("for a default main project, that would be rejected as well!") +} diff --git a/test/publishing_no_readme/test.sh b/test/publishing_no_readme/test.sh new file mode 100755 index 00000000000..d534ee4793e --- /dev/null +++ b/test/publishing_no_readme/test.sh @@ -0,0 +1,23 @@ +#!/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 +if yes "n" | g publish; then + echo "Expected publish to fail, but it succeeded" + exit 1 +fi + +echo +echo Success! 💖 +echo From 150112cc74ff53c1d6c1af2fab5121602b69feb1 Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Sun, 15 Feb 2026 15:59:57 +0100 Subject: [PATCH 3/3] refuse to publish empty READMEs --- .github/workflows/ci.yaml | 4 +- CHANGELOG.md | 3 +- compiler-cli/src/publish.rs | 48 +++++++++++-------- compiler-core/src/error.rs | 41 +++++++++++++--- test/multi_namespace/README.md | 3 ++ test/multi_namespace_not_top_level/README.md | 3 ++ test/publishing_empty_readme/.gitignore | 3 ++ test/publishing_empty_readme/README.md | 0 test/publishing_empty_readme/gleam.toml | 7 +++ test/publishing_empty_readme/manifest.toml | 9 ++++ .../src/empty_readme.gleam | 21 ++++++++ test/publishing_empty_readme/test.sh | 23 +++++++++ 12 files changed, 136 insertions(+), 29 deletions(-) create mode 100644 test/multi_namespace/README.md create mode 100644 test/multi_namespace_not_top_level/README.md create mode 100644 test/publishing_empty_readme/.gitignore create mode 100644 test/publishing_empty_readme/README.md create mode 100644 test/publishing_empty_readme/gleam.toml create mode 100644 test/publishing_empty_readme/manifest.toml create mode 100644 test/publishing_empty_readme/src/empty_readme.gleam create mode 100755 test/publishing_empty_readme/test.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7e39dc45137..4e0bdb4a188 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -474,7 +474,7 @@ jobs: run: make test working-directory: ./test/hextarball - - name: Test running modules + - name: test/running_modules run: make test-all working-directory: ./test/running_modules @@ -482,7 +482,7 @@ jobs: run: ./test.sh working-directory: ./test/multi_namespace - - name: Test multi namespace bug + - name: test/multi_namespace_not_top_level run: ./test.sh working-directory: ./test/multi_namespace_not_top_level diff --git a/CHANGELOG.md b/CHANGELOG.md index 33e3327a9e8..7534e6cace5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,7 +74,8 @@ README generated by the `gleam new` command. ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) -- The build tool will now refuse to publish any package that has no README. +- The build tool will now refuse to publish any package that has no README, or + an empty README. ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) ### Language server diff --git a/compiler-cli/src/publish.rs b/compiler-cli/src/publish.rs index c1f99bcf707..f70bed8c5d8 100644 --- a/compiler-cli/src/publish.rs +++ b/compiler-cli/src/publish.rs @@ -8,7 +8,7 @@ use gleam_core::{ build::{Codegen, Compile, Mode, Options, Package, Target}, config::{GleamVersion, PackageConfig, SpdxLicense}, docs::{Dependency, DependencyKind, DocContext}, - error::{SmallVersion, wrap}, + error::{InvalidReadmeReason, SmallVersion, wrap}, hex, manifest::ManifestPackageSource, paths::{self, ProjectPaths}, @@ -31,7 +31,7 @@ pub fn command(paths: &ProjectPaths, replace: bool, i_am_sure: bool) -> Result<( && check_for_version_zero(&config)? && check_repo_url(&config, i_am_sure)?; - check_for_default_readme(&config, paths)?; + check_for_invalid_readme(&config, paths)?; if !should_publish { println!("Not publishing."); @@ -132,33 +132,43 @@ HTML documentation will work: Ok(()) } -fn check_for_default_readme(config: &PackageConfig, paths: &ProjectPaths) -> Result<(), Error> { - let default_readme = default_readme(config.name.as_str()); +fn check_for_invalid_readme(config: &PackageConfig, paths: &ProjectPaths) -> Result<(), Error> { + let normalise = |string: String| { + string + .trim() + .replace("\r\n", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", "") + }; + let project_readme = match fs::read(paths.readme()) { Err(Error::FileIo { err: Some(message), .. }) if message.contains("No such file or directory") => { - return Err(Error::CannotPublishWithNoReadme); + return Err(Error::CannotPublishWithInvalidReadme { + reason: InvalidReadmeReason::Missing, + }); } Err(error) => return Err(error), Ok(project_readme) => project_readme, }; - // We consider the two READMEs equal modulo whitespace, otherwise it would - // be pretty trivial to trick this check by just formatting the default - // README differently. - let normalise = |string: String| { - string - .replace("\r\n", "") - .replace("\n", "") - .replace("\t", "") - .replace(" ", "") - }; - if normalise(project_readme) == normalise(default_readme) { - Err(Error::CannotPublishWithDefaultReadme) - } else { - Ok(()) + let normalised_project_readme = normalise(project_readme); + if normalised_project_readme.is_empty() { + return Err(Error::CannotPublishWithInvalidReadme { + reason: InvalidReadmeReason::Empty, + }); } + + let default_readme = default_readme(config.name.as_str()); + if normalised_project_readme == normalise(default_readme) { + return Err(Error::CannotPublishWithInvalidReadme { + reason: InvalidReadmeReason::Default, + }); + } + + Ok(()) } fn check_for_name_squatting(package: &Package) -> Result<(), Error> { diff --git a/compiler-core/src/error.rs b/compiler-core/src/error.rs index d5ef70bdb2e..61d97bc840b 100644 --- a/compiler-core/src/error.rs +++ b/compiler-core/src/error.rs @@ -312,11 +312,8 @@ file_names.iter().map(|x| x.as_str()).join(", "))] #[error("The modules {unfinished:?} are empty and so cannot be published")] CannotPublishEmptyModules { unfinished: Vec }, - #[error("Publishing a package with the default README is not permitted")] - CannotPublishWithDefaultReadme, - - #[error("Publishing a package with no README is not permitted")] - CannotPublishWithNoReadme, + #[error("Publishing packages with an invalid README is not permitted")] + CannotPublishWithInvalidReadme { reason: InvalidReadmeReason }, #[error("Publishing packages to reserve names is not permitted")] HexPackageSquatting, @@ -352,6 +349,13 @@ file_names.iter().map(|x| x.as_str()).join(", "))] CannotAddSelfAsDependency { name: EcoString }, } +#[derive(Debug, Eq, PartialEq, Clone, Copy)] +pub enum InvalidReadmeReason { + Missing, + Empty, + Default, +} + // A wrapper that ignores the inner value for equality: #[derive(Debug, Clone)] pub struct NeverEqual(pub T); @@ -868,7 +872,9 @@ package deletion or account suspension. }] } - Error::CannotPublishWithDefaultReadme => { + Error::CannotPublishWithInvalidReadme { + reason: InvalidReadmeReason::Default, + } => { let text = "You appear to be attempting to publish a package with the default README generated by the `gleam new` command. That is meant as a placeholder and a @@ -887,7 +893,9 @@ published package should have its own carefully written README. }] } - Error::CannotPublishWithNoReadme => { + Error::CannotPublishWithInvalidReadme { + reason: InvalidReadmeReason::Missing, + } => { let text = "You appear to be attempting to publish a package with no README. All published packages should have one. " @@ -902,6 +910,25 @@ All published packages should have one. }] } + Error::CannotPublishWithInvalidReadme { + reason: InvalidReadmeReason::Empty, + } => { + let text = "You appear to be attempting to publish a package with an empty README. +All published packages should have a non empty README. +" + .into(); + + vec![Diagnostic { + title: "Cannot publish with empty README".into(), + text, + level: Level::Error, + location: None, + hint: Some( + "Update your project's README to describe it before publishing".into(), + ), + }] + } + Error::CannotPublishWithDefaultMain { package_name } => { let text = wrap_format!( "Packages with the default main function cannot be published diff --git a/test/multi_namespace/README.md b/test/multi_namespace/README.md new file mode 100644 index 00000000000..622f79bfc53 --- /dev/null +++ b/test/multi_namespace/README.md @@ -0,0 +1,3 @@ +# Multi namespace project + +should not be published! diff --git a/test/multi_namespace_not_top_level/README.md b/test/multi_namespace_not_top_level/README.md new file mode 100644 index 00000000000..622f79bfc53 --- /dev/null +++ b/test/multi_namespace_not_top_level/README.md @@ -0,0 +1,3 @@ +# Multi namespace project + +should not be published! diff --git a/test/publishing_empty_readme/.gitignore b/test/publishing_empty_readme/.gitignore new file mode 100644 index 00000000000..c1dc9b0dd00 --- /dev/null +++ b/test/publishing_empty_readme/.gitignore @@ -0,0 +1,3 @@ +*.beam +*.ez +build diff --git a/test/publishing_empty_readme/README.md b/test/publishing_empty_readme/README.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/publishing_empty_readme/gleam.toml b/test/publishing_empty_readme/gleam.toml new file mode 100644 index 00000000000..d97b24244b8 --- /dev/null +++ b/test/publishing_empty_readme/gleam.toml @@ -0,0 +1,7 @@ +name = "empty_readme" +version = "1.0.0" +description = "Test project for empty readme" +licences = ["Apache-2.0"] + +[dependencies] +gleam_stdlib = ">= 0.44.0 and < 2.0.0" diff --git a/test/publishing_empty_readme/manifest.toml b/test/publishing_empty_readme/manifest.toml new file mode 100644 index 00000000000..88377adc600 --- /dev/null +++ b/test/publishing_empty_readme/manifest.toml @@ -0,0 +1,9 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "gleam_stdlib", version = "0.62.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "0080706D3A5A9A36C40C68481D1D231D243AF602E6D2A2BE67BA8F8F4DFF45EC" }, +] + +[requirements] +gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" } diff --git a/test/publishing_empty_readme/src/empty_readme.gleam b/test/publishing_empty_readme/src/empty_readme.gleam new file mode 100644 index 00000000000..d2318ee3ee0 --- /dev/null +++ b/test/publishing_empty_readme/src/empty_readme.gleam @@ -0,0 +1,21 @@ +import gleam/io + +/// This tests that a project with an empty readme doesn't get published. +/// +pub fn main() -> Nil { + greeting() + first_line() + second_line() +} + +fn greeting() { + io.println("Hello from empty_readme!") +} + +fn first_line() { + io.println("Here we have some additional code so that this is not mistaken") +} + +fn second_line() { + io.println("for a default main project, that would be rejected as well!") +} diff --git a/test/publishing_empty_readme/test.sh b/test/publishing_empty_readme/test.sh new file mode 100755 index 00000000000..d534ee4793e --- /dev/null +++ b/test/publishing_empty_readme/test.sh @@ -0,0 +1,23 @@ +#!/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 +if yes "n" | g publish; then + echo "Expected publish to fail, but it succeeded" + exit 1 +fi + +echo +echo Success! 💖 +echo