diff --git a/scarb/src/core/publishing/source.rs b/scarb/src/core/publishing/source.rs index 1142cf299..bb976f239 100644 --- a/scarb/src/core/publishing/source.rs +++ b/scarb/src/core/publishing/source.rs @@ -4,14 +4,14 @@ use ignore::{DirEntry, WalkBuilder}; use crate::core::Package; use crate::internal::fsx::PathBufUtf8Ext; -use crate::{DEFAULT_TARGET_DIR_NAME, LOCK_FILE_NAME, MANIFEST_FILE_NAME}; +use crate::{DEFAULT_TARGET_DIR_NAME, LOCK_FILE_NAME, MANIFEST_FILE_NAME, SCARB_IGNORE_FILE_NAME}; /// List all files relevant to building this package inside this source. /// /// The basic assumption is that all files in the package directory are relevant for building this /// package, provided that they potentially can be committed to the source directory. The following /// rules hold: -/// * Look for any `.gitignore` or `.ignore`-like files, using the [`ignore`] crate. +/// * Look for any `.scarbignore`, `.gitignore` or `.ignore`-like files, using the [`ignore`] crate. /// * Skip `.git` directory. /// * Skip any subdirectories containing `Scarb.toml`. /// * Skip `/target` directory. @@ -63,6 +63,7 @@ fn push_worktree_files(pkg: &Package, ret: &mut Vec) -> Result<()> .parents(false) .require_git(true) .same_file_system(true) + .add_custom_ignore_filename(SCARB_IGNORE_FILE_NAME) .filter_entry(filter) .build() .try_for_each(|entry| { diff --git a/scarb/src/lib.rs b/scarb/src/lib.rs index 56885c029..a41eaf3e9 100644 --- a/scarb/src/lib.rs +++ b/scarb/src/lib.rs @@ -29,3 +29,4 @@ pub const DEFAULT_SOURCE_PATH: &str = "src/lib.cairo"; pub const DEFAULT_MODULE_MAIN_FILE: &str = "lib.cairo"; pub const DEFAULT_TESTS_PATH: &str = "tests"; pub const DEFAULT_TARGET_DIR_NAME: &str = "target"; +pub const SCARB_IGNORE_FILE_NAME: &str = ".scarbignore"; diff --git a/scarb/tests/package.rs b/scarb/tests/package.rs index 927dad1bc..60745ec85 100644 --- a/scarb/tests/package.rs +++ b/scarb/tests/package.rs @@ -1,3 +1,5 @@ +#![allow(clippy::items_after_test_module)] + use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::{BufReader, Read}; @@ -741,9 +743,11 @@ fn clean_tar_headers() { #[test_case("../.gitignore", false, false; "gitignore outside")] #[test_case("../.gitignore", true, false; "gitignore outside with git")] #[test_case("../.ignore", false, false; "ignore outside")] +#[test_case("../.scarbignore", false, false; "scarbignore outside")] #[test_case(".gitignore", false, false; "gitignore inside")] #[test_case(".gitignore", true, true; "gitignore inside with git")] #[test_case(".ignore", false, true; "ignore inside")] +#[test_case(".scarbignore", false, true; "scarbignore inside")] fn ignore_file(ignore_path: &str, setup_git: bool, expect_ignore_to_work: bool) { let g = gitx::new_conditional(setup_git, "package", |t| { ProjectBuilder::start() @@ -780,3 +784,41 @@ fn ignore_file(ignore_path: &str, setup_git: bool, expect_ignore_to_work: bool) .success() .stdout_eq(expected.join("\n")); } + +#[test] +fn ignore_whitelist_pattern() { + let t = TempDir::new().unwrap(); + ProjectBuilder::start() + .name("foo") + .version("1.0.0") + .src("ignore.txt", "") + .src("noignore.txt", "") + .src("src/ignore.txt", "") + .build(&t); + + t.child(".scarbignore") + .write_str(indoc! {r#" + * + !*/ + !Scarb.toml + !src/ + !src/* + src/ignore.* + !noignore.txt + "#}) + .unwrap(); + + Scarb::quick_snapbox() + .arg("package") + .arg("--list") + .current_dir(&t) + .assert() + .success() + .stdout_eq(indoc! {r#" + VERSION + Scarb.orig.toml + Scarb.toml + noignore.txt + src/lib.cairo + "#}); +}