Repository: cocogitto/cocogitto
Pull request #311 (2023-08-19 09:29:46)

feat(bump): option to skip untracked and uncomitted changes
Resolves https://github.com/cocogitto/cocogitto/issues/275

cocogitto-bot[bot]: :heavy_check_mark: eb55b87 - Conventional commits check succeeded.
Wassim-AB: Writing tests
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/cocogitto/cocogitto/pull/311?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cocogitto) Report
> Merging [#311](https://app.codecov.io/gh/cocogitto/cocogitto/pull/311?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cocogitto) (eb55b87) into [main](https://app.codecov.io/gh/cocogitto/cocogitto/commit/b2d36aa39d37bf6491fe3074ada401480d7832a6?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cocogitto) (b2d36aa) will **decrease** coverage by `0.01%`.
> Report is 2 commits behind head on main.
> The diff coverage is `75.00%`.

```diff
@@            Coverage Diff             @@
##             main     #311      +/-   ##
==========================================
- Coverage   85.26%   85.25%   -0.01%     
==========================================
  Files          45       45              
  Lines        6270     6273       +3     
==========================================
+ Hits         5346     5348       +2     
- Misses        924      925       +1     
```


| [Files Changed](https://app.codecov.io/gh/cocogitto/cocogitto/pull/311?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cocogitto) | Coverage Δ | |
|---|---|---|
| [src/command/bump/mod.rs](https://app.codecov.io/gh/cocogitto/cocogitto/pull/311?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cocogitto#diff-c3JjL2NvbW1hbmQvYnVtcC9tb2QucnM=) | `84.55% <66.66%> (-0.26%)` | :arrow_down: |
| [src/settings/mod.rs](https://app.codecov.io/gh/cocogitto/cocogitto/pull/311?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cocogitto#diff-c3JjL3NldHRpbmdzL21vZC5ycw==) | `75.29% <100.00%> (+0.09%)` | :arrow_up: |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cocogitto)

cocogitto-bot[bot]: :heavy_check_mark: 2ddf1e7 - Conventional commits check succeeded.
cocogitto-bot[bot]: :heavy_check_mark: d2ee55b - Conventional commits check succeeded.
cocogitto-bot[bot]: :heavy_check_mark: 2fddee7 - Conventional commits check succeeded.
marcbull: I think this feature should be a command line option instead of a value hidden in the settings, so you can control the behavior at each invocation of `cog`.

And the repository statuses should be printed to [stderr](https://doc.rust-lang.org/std/macro.eprintln.html) to avoid complicated parsing to fetch the version number from stdout.
cocogitto-bot[bot]: :heavy_check_mark: 2fddee7...fd11064 - Conventional commits check succeeded.
cocogitto-bot[bot]: :heavy_check_mark: 2fddee7...e9b57e5 - Conventional commits check succeeded.
cocogitto-bot[bot]: :heavy_check_mark: 2fddee7...8d28971 - Conventional commits check succeeded.
Wassim-AB: > I think this feature should be a command line option instead of a value hidden in the settings, so you can control the behavior at each invocation of `cog`.
> 
> And the repository statuses should be printed to [stderr](https://doc.rust-lang.org/std/macro.eprintln.html) to avoid complicated parsing to fetch the version number from stdout.

Hey @marcbull, done :)
cocogitto-bot[bot]: :heavy_check_mark: b076951...7d18867 - Conventional commits check succeeded.

Patch:
diff --git a/README.md b/README.md
index 15f7024..4823c15 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@
       src="https://img.shields.io/github/license/cocogitto/cocogitto"
       alt="Repository license"
   /></a>
-  <a href="https://discord.gg/951009223121195021">
+  <a href="https://discord.gg/WeZRdhtuf6">
     <img alt="Discord logo" src="https://img.shields.io/discord/951009223121195021?color=blue&logo=discord">
   </a>
 
diff --git a/cog.toml b/cog.toml
index 39ce4f5..18296da 100644
--- a/cog.toml
+++ b/cog.toml
@@ -87,5 +87,6 @@ authors = [
     { signature = "Racci", username = "DaRacci" },
     { signature = "Conrad Hoffmann", username = "bitfehler" },
     { signature = "andre161292", username = "andre161292" },
-    { signature = "Sanchith Hegde", username = "SanchithHegde" }
+    { signature = "Sanchith Hegde", username = "SanchithHegde" },
+    { signature = "Wassim Ahmed-Belkacem", username = "Wassim-AB" },
 ]
diff --git a/src/bin/cog/main.rs b/src/bin/cog/main.rs
index 4d2f541..20b2fd2 100644
--- a/src/bin/cog/main.rs
+++ b/src/bin/cog/main.rs
@@ -285,6 +285,10 @@ enum Command {
         /// Specify a "Skip CI" string to append to the end of the commit
         #[arg(long = "skip-ci")]
         skip_ci: Option<String>,
+
+        /// Don't fail if there are untracked or uncommited files
+        #[arg(long = "skip-untracked")]
+        skip_untracked: bool,
     },
 
     /// Install cog config files
@@ -363,6 +367,7 @@ fn main() -> Result<()> {
             annotated,
             dry_run,
             skip_ci,
+            skip_untracked,
         } => {
             let mut cocogitto = CocoGitto::get()?;
             let is_monorepo = !SETTINGS.packages.is_empty();
@@ -398,6 +403,7 @@ fn main() -> Result<()> {
                             annotated,
                             dry_run,
                             skip_ci,
+                            skip_untracked,
                         )?
                     }
                     None => cocogitto.create_monorepo_version(
@@ -407,6 +413,7 @@ fn main() -> Result<()> {
                         annotated,
                         dry_run,
                         skip_ci,
+                        skip_untracked,
                     )?,
                 }
             } else {
@@ -417,6 +424,7 @@ fn main() -> Result<()> {
                     annotated,
                     dry_run,
                     skip_ci,
+                    skip_untracked,
                 )?
             }
         }
diff --git a/src/command/bump/mod.rs b/src/command/bump/mod.rs
index 1dc54ba..687632a 100644
--- a/src/command/bump/mod.rs
+++ b/src/command/bump/mod.rs
@@ -130,7 +130,7 @@ impl CocoGitto {
         }
     }
 
-    fn pre_bump_checks(&mut self) -> Result<()> {
+    fn pre_bump_checks(&mut self, skip_untracked: bool) -> Result<()> {
         if *SETTINGS == Settings::default() {
             let part1 = "Warning: using".yellow();
             let part2 = "with the default configuration. \n".yellow();
@@ -143,8 +143,11 @@ impl CocoGitto {
         }
         let statuses = self.repository.get_statuses()?;
 
-        // Fail if repo contains un-staged or un-committed changes
-        ensure!(statuses.0.is_empty(), "{}", self.repository.get_statuses()?);
+        if skip_untracked || SETTINGS.skip_untracked {
+            eprintln!("{}", self.repository.get_statuses()?);
+        } else {
+            ensure!(statuses.0.is_empty(), "{}", self.repository.get_statuses()?);
+        }
 
         if !SETTINGS.branch_whitelist.is_empty() {
             if let Some(branch) = self.repository.get_branch_shorthand() {
diff --git a/src/command/bump/monorepo.rs b/src/command/bump/monorepo.rs
index 90e5ae9..aa856c9 100644
--- a/src/command/bump/monorepo.rs
+++ b/src/command/bump/monorepo.rs
@@ -38,6 +38,7 @@ struct PackageData {
 }
 
 impl CocoGitto {
+    #[allow(clippy::too_many_arguments)]
     pub fn create_monorepo_version(
         &mut self,
         increment: IncrementCommand,
@@ -46,6 +47,7 @@ impl CocoGitto {
         annotated: Option<String>,
         dry_run: bool,
         skip_ci: Option<String>,
+        skip_untracked: bool,
     ) -> Result<()> {
         match increment {
             IncrementCommand::Auto => {
@@ -56,6 +58,7 @@ impl CocoGitto {
                         annotated,
                         dry_run,
                         skip_ci,
+                        skip_untracked,
                     )
                 } else {
                     if annotated.is_some() {
@@ -66,6 +69,7 @@ impl CocoGitto {
                         hooks_config,
                         dry_run,
                         skip_ci,
+                        skip_untracked,
                     )
                 }
             }
@@ -76,6 +80,7 @@ impl CocoGitto {
                 annotated,
                 dry_run,
                 skip_ci,
+                skip_untracked,
             ),
         }
     }
@@ -86,8 +91,9 @@ impl CocoGitto {
         hooks_config: Option<&str>,
         dry_run: bool,
         skip_ci: Option<String>,
+        skip_untracked: bool,
     ) -> Result<()> {
-        self.pre_bump_checks()?;
+        self.pre_bump_checks(skip_untracked)?;
         // Get package bumps
         let bumps = self.get_packages_bumps(pre_release)?;
 
@@ -151,8 +157,9 @@ impl CocoGitto {
         annotated: Option<String>,
         dry_run: bool,
         skip_ci: Option<String>,
+        skip_untracked: bool,
     ) -> Result<()> {
-        self.pre_bump_checks()?;
+        self.pre_bump_checks(skip_untracked)?;
         // Get package bumps
         let bumps = self.get_packages_bumps(pre_release)?;
 
@@ -298,6 +305,7 @@ impl CocoGitto {
         Ok(())
     }
 
+    #[allow(clippy::too_many_arguments)]
     fn create_monorepo_version_manual(
         &mut self,
         increment: IncrementCommand,
@@ -306,8 +314,9 @@ impl CocoGitto {
         annotated: Option<String>,
         dry_run: bool,
         skip_ci: Option<String>,
+        skip_untracked: bool,
     ) -> Result<()> {
-        self.pre_bump_checks()?;
+        self.pre_bump_checks(skip_untracked)?;
         // Get package bumps
         let bumps = self.get_current_packages()?;
 
diff --git a/src/command/bump/package.rs b/src/command/bump/package.rs
index 6791051..877967d 100644
--- a/src/command/bump/package.rs
+++ b/src/command/bump/package.rs
@@ -25,8 +25,9 @@ impl CocoGitto {
         annotated: Option<String>,
         dry_run: bool,
         skip_ci: Option<String>,
+        skip_untracked: bool,
     ) -> Result<()> {
-        self.pre_bump_checks()?;
+        self.pre_bump_checks(skip_untracked)?;
 
         let current_tag = self.repository.get_latest_package_tag(package_name);
         let current_tag = tag_or_fallback_to_zero(current_tag)?;
diff --git a/src/command/bump/standard.rs b/src/command/bump/standard.rs
index 4e8d17f..1ff3850 100644
--- a/src/command/bump/standard.rs
+++ b/src/command/bump/standard.rs
@@ -14,6 +14,7 @@ use semver::Prerelease;
 use tera::Tera;
 
 impl CocoGitto {
+    #[allow(clippy::too_many_arguments)]
     pub fn create_version(
         &mut self,
         increment: IncrementCommand,
@@ -22,8 +23,9 @@ impl CocoGitto {
         annotated: Option<String>,
         dry_run: bool,
         skip_ci: Option<String>,
+        skip_untracked: bool,
     ) -> Result<()> {
-        self.pre_bump_checks()?;
+        self.pre_bump_checks(skip_untracked)?;
 
         let current_tag = self.repository.get_latest_tag();
         let current_tag = tag_or_fallback_to_zero(current_tag)?;
diff --git a/src/settings/mod.rs b/src/settings/mod.rs
index c0fa1a1..f9d061c 100644
--- a/src/settings/mod.rs
+++ b/src/settings/mod.rs
@@ -37,6 +37,7 @@ pub struct Settings {
     pub branch_whitelist: Vec<String>,
     pub tag_prefix: Option<String>,
     pub skip_ci: Option<String>,
+    pub skip_untracked: bool,
     pub pre_bump_hooks: Vec<String>,
     pub post_bump_hooks: Vec<String>,
     pub pre_package_bump_hooks: Vec<String>,
@@ -58,6 +59,7 @@ impl Default for Settings {
             branch_whitelist: vec![],
             tag_prefix: None,
             skip_ci: None,
+            skip_untracked: false,
             pre_bump_hooks: vec![],
             post_bump_hooks: vec![],
             pre_package_bump_hooks: vec![],


Test patch:
diff --git a/tests/cog_tests/bump.rs b/tests/cog_tests/bump.rs
index 61d82ed..b8aef10 100644
--- a/tests/cog_tests/bump.rs
+++ b/tests/cog_tests/bump.rs
@@ -4,6 +4,7 @@ use crate::helpers::*;
 
 use anyhow::Result;
 use assert_cmd::prelude::*;
+use cmd_lib::run_cmd;
 use cocogitto::settings::Settings;
 use indoc::indoc;
 use sealed_test::prelude::*;
@@ -333,3 +334,49 @@ fn package_dry_run() -> Result<()> {
     assert_tag_does_not_exist("1.1.0")?;
     Ok(())
 }
+
+#[sealed_test]
+fn uncommited_changes_should_throw_error_by_default() -> Result<()> {
+    init_monorepo(&mut Settings::default())?;
+
+    run_cmd!(
+        echo two > two;
+    )?;
+
+    Command::cargo_bin("cog")?
+        .arg("bump")
+        .arg("--auto")
+        .arg("--dry-run")
+        .assert()
+        .failure();
+
+    Ok(())
+}
+
+#[sealed_test]
+fn uncommited_changes_should_not_throw_error_with_option() -> Result<()> {
+    let mut settings = Settings {
+        skip_untracked: true,
+        ..Default::default()
+    };
+
+    init_monorepo(&mut settings)?;
+
+    run_cmd!(
+        echo two > two;
+        echo "other changes" > one/file;
+    )?;
+
+    Command::cargo_bin("cog")?
+        .arg("bump")
+        .arg("--auto")
+        .arg("--dry-run")
+        .assert()
+        .success()
+        .stderr(indoc!("Untracked files :\n\tmodified: one/file\n\tnew: two\n\nnothing added to commit but untracked files present (use \"git add\" to track)\n\n"))
+        .stdout(indoc!("one-0.1.0\n0.1.0\n"));
+
+    assert_that!(Path::new("CHANGELOG.md")).does_not_exist();
+    assert_tag_does_not_exist("1.1.0")?;
+    Ok(())
+}
diff --git a/tests/lib_tests/bump.rs b/tests/lib_tests/bump.rs
index 77a1f9f..ac80f92 100644
--- a/tests/lib_tests/bump.rs
+++ b/tests/lib_tests/bump.rs
@@ -21,7 +21,8 @@ fn bump_ok() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result = cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None);
+    let result =
+        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None, false);
 
     // Assert
     assert_that!(result).is_ok();
@@ -48,6 +49,7 @@ fn annotated_bump_ok() -> Result<()> {
         Some(String::from("Release version {{version}}")),
         false,
         None,
+        false,
     );
 
     // Assert
@@ -69,8 +71,15 @@ fn monorepo_bump_ok() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result =
-        cocogitto.create_monorepo_version(IncrementCommand::Auto, None, None, None, false, None);
+    let result = cocogitto.create_monorepo_version(
+        IncrementCommand::Auto,
+        None,
+        None,
+        None,
+        false,
+        None,
+        false,
+    );
 
     // Assert
     assert_that!(result).is_ok();
@@ -94,8 +103,15 @@ fn monorepo_bump_manual_ok() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result =
-        cocogitto.create_monorepo_version(IncrementCommand::Major, None, None, None, false, None);
+    let result = cocogitto.create_monorepo_version(
+        IncrementCommand::Major,
+        None,
+        None,
+        None,
+        false,
+        None,
+        false,
+    );
 
     // Assert
     assert_that!(result).is_ok();
@@ -116,8 +132,15 @@ fn monorepo_with_tag_prefix_bump_ok() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result =
-        cocogitto.create_monorepo_version(IncrementCommand::Auto, None, None, None, false, None);
+    let result = cocogitto.create_monorepo_version(
+        IncrementCommand::Auto,
+        None,
+        None,
+        None,
+        false,
+        None,
+        false,
+    );
 
     // Assert
     assert_that!(result).is_ok();
@@ -146,6 +169,7 @@ fn package_bump_ok() -> Result<()> {
         None,
         false,
         None,
+        false,
     );
 
     // Assert
@@ -214,6 +238,7 @@ fn consecutive_package_bump_ok() -> Result<()> {
         None,
         false,
         None,
+        false,
     )?;
 
     cocogitto.create_package_version(
@@ -224,6 +249,7 @@ fn consecutive_package_bump_ok() -> Result<()> {
         None,
         false,
         None,
+        false,
     )?;
 
     run_cmd!(
@@ -240,6 +266,7 @@ fn consecutive_package_bump_ok() -> Result<()> {
         None,
         false,
         None,
+        false,
     )?;
 
     // Assert
@@ -261,7 +288,8 @@ fn should_fallback_to_0_0_0_when_there_is_no_tag() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result = cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None);
+    let result =
+        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None, false);
 
     // Assert
     assert_that!(result).is_ok();
@@ -320,7 +348,7 @@ fn auto_bump_package_only_ok() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    cocogitto.create_all_package_version_auto(None, None, false, None)?;
+    cocogitto.create_all_package_version_auto(None, None, false, None, false)?;
 
     assert_tag_exists("jenkins-0.1.0")?;
     assert_tag_exists("thumbor-0.1.0")?;
@@ -332,7 +360,7 @@ fn auto_bump_package_only_ok() -> Result<()> {
         git commit -m "fix(jenkins): bug fix on jenkins package";
     )?;
 
-    cocogitto.create_all_package_version_auto(None, None, false, None)?;
+    cocogitto.create_all_package_version_auto(None, None, false, None, false)?;
 
     // Assert
     assert_tag_exists("jenkins-0.1.1")?;
@@ -384,7 +412,8 @@ fn bump_with_whitelisted_branch_ok() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result = cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None);
+    let result =
+        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None, false);
 
     // Assert
     assert_that!(result).is_ok();
@@ -409,7 +438,8 @@ fn bump_with_whitelisted_branch_fails() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result = cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None);
+    let result =
+        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None, false);
 
     // Assert
     assert_that!(result.unwrap_err().to_string()).is_equal_to(
@@ -438,7 +468,8 @@ fn bump_with_whitelisted_branch_pattern_ok() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result = cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None);
+    let result =
+        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None, false);
 
     // Assert
     assert_that!(result).is_ok();
@@ -463,7 +494,8 @@ fn bump_with_whitelisted_branch_pattern_err() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result = cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None);
+    let result =
+        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None, false);
 
     // Assert
     assert_that!(result).is_err();
@@ -520,7 +552,15 @@ fn bump_no_error_should_be_thrown_on_only_chore_docs_commit() -> Result<()> {
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    cocogitto.create_monorepo_version(IncrementCommand::Auto, None, None, None, false, None)?;
+    cocogitto.create_monorepo_version(
+        IncrementCommand::Auto,
+        None,
+        None,
+        None,
+        false,
+        None,
+        false,
+    )?;
 
     run_cmd!(
         echo "chore on jenkins" > jenkins/fix;
@@ -531,7 +571,15 @@ fn bump_no_error_should_be_thrown_on_only_chore_docs_commit() -> Result<()> {
         git commit -m "docs(jenkins): jenkins docs";
     )?;
 
-    cocogitto.create_monorepo_version(IncrementCommand::Auto, None, None, None, false, None)?;
+    cocogitto.create_monorepo_version(
+        IncrementCommand::Auto,
+        None,
+        None,
+        None,
+        false,
+        None,
+        false,
+    )?;
 
     cocogitto.create_package_version(
         ("jenkins", &jenkins()),
@@ -541,6 +589,7 @@ fn bump_no_error_should_be_thrown_on_only_chore_docs_commit() -> Result<()> {
         None,
         false,
         None,
+        false,
     )?;
 
     run_cmd!(
@@ -549,7 +598,15 @@ fn bump_no_error_should_be_thrown_on_only_chore_docs_commit() -> Result<()> {
         git commit -m "feat(thumbor): more feat on thumbor";
     )?;
 
-    cocogitto.create_monorepo_version(IncrementCommand::Auto, None, None, None, false, None)?;
+    cocogitto.create_monorepo_version(
+        IncrementCommand::Auto,
+        None,
+        None,
+        None,
+        false,
+        None,
+        false,
+    )?;
 
     // Assert
     assert_tag_exists("jenkins-0.1.0")?;
@@ -591,7 +648,7 @@ fn error_on_no_conventionnal_commits_found_for_monorepo() -> Result<()> {
 
     // Act
     let first_result =
-        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None);
+        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None, false);
 
     // Assert
     assert_that!(first_result).is_ok();
@@ -605,7 +662,7 @@ fn error_on_no_conventionnal_commits_found_for_monorepo() -> Result<()> {
 
     // Act
     let second_result =
-        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None);
+        cocogitto.create_version(IncrementCommand::Auto, None, None, None, false, None, false);
 
     // Assert
     assert_that!(second_result).is_err();
@@ -659,6 +716,7 @@ fn error_on_no_conventionnal_commits_found_for_package() -> Result<()> {
         None,
         false,
         None,
+        false,
     );
 
     assert_that!(first_result).is_ok();
@@ -677,6 +735,7 @@ fn error_on_no_conventionnal_commits_found_for_package() -> Result<()> {
         None,
         false,
         None,
+        false,
     );
 
     assert_that!(second_result).is_err();
@@ -733,8 +792,15 @@ fn bump_with_unconventionnal_and_conventional_commits_found_for_packages() -> Re
     let mut cocogitto = CocoGitto::get()?;
 
     // Act
-    let result =
-        cocogitto.create_monorepo_version(IncrementCommand::Auto, None, None, None, false, None);
+    let result = cocogitto.create_monorepo_version(
+        IncrementCommand::Auto,
+        None,
+        None,
+        None,
+        false,
+        None,
+        false,
+    );
 
     // Assert
     assert_that!(result).is_ok();