just playing with tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

signing: allow specifying sign behavior

authored by

maan2003 and committed by
maan2003
ec6f8278 a4b064ea

+93 -30
+6
CHANGELOG.md
··· 39 39 `split.legacy-bookmark-behavior = true`, but this will likely be removed in a 40 40 future release. [#3419](https://github.com/jj-vcs/jj/issues/3419) 41 41 42 + * The `signing.sign-all` config option has been deprecated in favor of 43 + `signing.behavior`. The new option accepts `drop` (never sign), `keep` (preserve 44 + existing signatures), `own` (sign own commits), or `force` (sign all commits). 45 + Existing `signing.sign-all = true` translates to `signing.behavior = "own"`, and 46 + `false` translates to `"keep"`. 47 + 42 48 43 49 ### New features 44 50
+4 -4
cli/src/config-schema.json
··· 607 607 "type": "string", 608 608 "description": "The key the configured signing backend will use to to sign commits. Overridden by `jj sign` parameter or by the global `--sign-with` option" 609 609 }, 610 - "sign-all": { 611 - "type": "boolean", 612 - "description": "Whether to sign all commits by default. Overridden by global `--no-sign` option", 613 - "default": false 610 + "behavior": { 611 + "type": "string", 612 + "enum": ["drop", "keep", "own", "force"], 613 + "description": "Which commits to sign by default. Values: drop (never sign), keep (preserve existing signatures), own (sign own commits), force (sign all commits)" 614 614 }, 615 615 "backends": { 616 616 "type": "object",
+15
cli/src/config.rs
··· 605 605 ConfigMigrationRule::rename_value("git.auto-local-branch", "git.auto-local-bookmark"), 606 606 // TODO: Delete in jj 0.28+ 607 607 ConfigMigrationRule::rename_value("git.push-branch-prefix", "git.push-bookmark-prefix"), 608 + // TODO: Delete in jj 0.33+ 609 + ConfigMigrationRule::rename_update_value( 610 + "signing.sign-all", 611 + "signing.behavior", 612 + |old_value| { 613 + if old_value 614 + .as_bool() 615 + .ok_or("signing.sign-all expects a boolean")? 616 + { 617 + Ok("own".into()) 618 + } else { 619 + Ok("keep".into()) 620 + } 621 + }, 622 + ), 608 623 ] 609 624 } 610 625
+1 -1
cli/tests/test_commit_template.rs
··· 1464 1464 let repo_path = test_env.env_root().join("repo"); 1465 1465 1466 1466 test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "unsigned"]); 1467 - test_env.add_config("signing.sign-all = true"); 1467 + test_env.add_config("signing.behavior = 'own'"); 1468 1468 test_env.add_config("signing.backend = 'test'"); 1469 1469 test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "signed"]); 1470 1470
+12 -4
cli/tests/test_completion.rs
··· 575 575 ); 576 576 insta::assert_snapshot!(stdout, @"ui.conflict-marker-style=git"); 577 577 578 - let stdout = 579 - test_env.jj_cmd_success(dir, &["--", "jj", "log", "--config", "signing.sign-all="]); 578 + let stdout = test_env.jj_cmd_success( 579 + dir, 580 + &[ 581 + "--", 582 + "jj", 583 + "log", 584 + "--config", 585 + "git.abandon-unreachable-commits=", 586 + ], 587 + ); 580 588 insta::assert_snapshot!(stdout, @r" 581 - signing.sign-all=false 582 - signing.sign-all=true 589 + git.abandon-unreachable-commits=false 590 + git.abandon-unreachable-commits=true 583 591 "); 584 592 } 585 593
+6 -5
docs/config.md
··· 1120 1120 1121 1121 ```toml 1122 1122 [signing] 1123 - sign-all = true 1123 + behavior = "own" 1124 1124 backend = "gpg" 1125 1125 key = "4ED556E9729E000F" 1126 1126 ## You can set `key` to anything accepted by `gpg -u` ··· 1147 1147 1148 1148 ```toml 1149 1149 [signing] 1150 - sign-all = true 1150 + behavior = "own" 1151 1151 backend = "ssh" 1152 1152 key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGj+J6N6SO+4P8dOZqfR1oiay2yxhhHnagH52avUqw5h" 1153 1153 ## You can also use a path instead of embedding the key ··· 1176 1176 1177 1177 ### Sign commits only on `jj git push` 1178 1178 1179 - Instead of signing all commits during creation when `signing.sign-all` is 1180 - set to `true`, the `git.sign-on-push` configuration can be used to sign 1179 + Instead of signing all commits during creation when `signing.behavior` is 1180 + set to `own`, the `git.sign-on-push` configuration can be used to sign 1181 1181 commits only upon running `jj git push`. All mutable unsigned commits 1182 1182 being pushed will be signed prior to pushing. This might be preferred if the 1183 1183 signing backend requires user interaction or is slow, so that signing is 1184 1184 performed in a single batch operation. 1185 1185 1186 1186 ```toml 1187 - # Configure signing backend as before, without setting `signing.sign-all` 1187 + # Configure signing backend as before, but lazily signing only on push. 1188 1188 [signing] 1189 + behavior = "drop" 1189 1190 backend = "ssh" 1190 1191 key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGj+J6N6SO+4P8dOZqfR1oiay2yxhhHnagH52avUqw5h" 1191 1192
+5 -6
lib/src/settings.rs
··· 100 100 impl SignSettings { 101 101 /// Load the signing settings from the config. 102 102 pub fn from_settings(settings: &UserSettings) -> Self { 103 - let sign_all = settings.get_bool("signing.sign-all").unwrap_or(false); 103 + let behavior = settings 104 + .get("signing.behavior") 105 + .unwrap_or(SignBehavior::Keep); 106 + 104 107 Self { 105 - behavior: if sign_all { 106 - SignBehavior::Own 107 - } else { 108 - SignBehavior::Keep 109 - }, 108 + behavior, 110 109 user_email: settings.user_email().to_owned(), 111 110 key: settings.get_string("signing.key").ok(), 112 111 }
+2 -1
lib/src/signing.rs
··· 141 141 } 142 142 143 143 /// A enum that describes if a created/rewritten commit should be signed or not. 144 - #[derive(Debug, Clone, Copy, PartialEq, Eq)] 144 + #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Deserialize)] 145 + #[serde(rename_all = "kebab-case")] 145 146 pub enum SignBehavior { 146 147 /// Drop existing signatures. 147 148 /// This is what jj did before signing support or does now when a signing
+42 -9
lib/tests/test_signing.rs
··· 16 16 use testutils::TestRepoBackend; 17 17 use testutils::TestWorkspace; 18 18 19 - fn user_settings(sign_all: bool) -> UserSettings { 19 + fn user_settings(behavior: SignBehavior) -> UserSettings { 20 20 let mut config = testutils::base_user_config(); 21 21 config.add_layer( 22 22 ConfigLayer::parse( ··· 24 24 &format!( 25 25 r#" 26 26 signing.key = "impeccable" 27 - signing.sign-all = {sign_all} 28 - "# 27 + signing.behavior = "{}" 28 + "#, 29 + match behavior { 30 + SignBehavior::Drop => "drop", 31 + SignBehavior::Keep => "keep", 32 + SignBehavior::Own => "own", 33 + SignBehavior::Force => "force", 34 + } 29 35 ), 30 36 ) 31 37 .unwrap(), ··· 55 61 #[test_case(TestRepoBackend::Local ; "local backend")] 56 62 #[test_case(TestRepoBackend::Git ; "git backend")] 57 63 fn manual(backend: TestRepoBackend) { 58 - let settings = user_settings(true); 64 + let settings = user_settings(SignBehavior::Own); 59 65 60 66 let signer = Signer::new(Some(Box::new(TestSigningBackend)), vec![]); 61 67 let test_workspace = TestWorkspace::init_with_backend_and_signer(backend, signer, &settings); ··· 84 90 85 91 #[test_case(TestRepoBackend::Git ; "git backend")] 86 92 fn keep_on_rewrite(backend: TestRepoBackend) { 87 - let settings = user_settings(true); 93 + let settings = user_settings(SignBehavior::Own); 88 94 89 95 let signer = Signer::new(Some(Box::new(TestSigningBackend)), vec![]); 90 96 let test_workspace = TestWorkspace::init_with_backend_and_signer(backend, signer, &settings); ··· 109 115 110 116 #[test_case(TestRepoBackend::Git ; "git backend")] 111 117 fn manual_drop_on_rewrite(backend: TestRepoBackend) { 112 - let settings = user_settings(true); 118 + let settings = user_settings(SignBehavior::Own); 113 119 114 120 let signer = Signer::new(Some(Box::new(TestSigningBackend)), vec![]); 115 121 let test_workspace = TestWorkspace::init_with_backend_and_signer(backend, signer, &settings); ··· 138 144 139 145 #[test_case(TestRepoBackend::Git ; "git backend")] 140 146 fn forced(backend: TestRepoBackend) { 141 - let settings = user_settings(true); 147 + let settings = user_settings(SignBehavior::Force); 142 148 143 149 let signer = Signer::new(Some(Box::new(TestSigningBackend)), vec![]); 144 150 let test_workspace = TestWorkspace::init_with_backend_and_signer(backend, signer, &settings); ··· 148 154 let repo = repo.clone(); 149 155 let mut tx = repo.start_transaction(); 150 156 let commit = create_random_commit(tx.repo_mut()) 151 - .set_sign_behavior(SignBehavior::Force) 152 157 .set_author(someone_else()) 153 158 .write() 154 159 .unwrap(); ··· 160 165 161 166 #[test_case(TestRepoBackend::Git ; "git backend")] 162 167 fn configured(backend: TestRepoBackend) { 163 - let settings = user_settings(true); 168 + let settings = user_settings(SignBehavior::Own); 164 169 165 170 let signer = Signer::new(Some(Box::new(TestSigningBackend)), vec![]); 166 171 let test_workspace = TestWorkspace::init_with_backend_and_signer(backend, signer, &settings); ··· 175 180 let commit = repo.store().get_commit(commit.id()).unwrap(); 176 181 assert_eq!(commit.verification().unwrap(), good_verification()); 177 182 } 183 + 184 + #[test_case(TestRepoBackend::Git ; "git backend")] 185 + fn drop_behavior(backend: TestRepoBackend) { 186 + let settings = user_settings(SignBehavior::Drop); 187 + 188 + let signer = Signer::new(Some(Box::new(TestSigningBackend)), vec![]); 189 + let test_workspace = TestWorkspace::init_with_backend_and_signer(backend, signer, &settings); 190 + 191 + let repo = &test_workspace.repo; 192 + 193 + let repo = repo.clone(); 194 + let mut tx = repo.start_transaction(); 195 + let commit = create_random_commit(tx.repo_mut()) 196 + .set_sign_behavior(SignBehavior::Own) 197 + .write() 198 + .unwrap(); 199 + tx.commit("test").unwrap(); 200 + 201 + let original_commit = repo.store().get_commit(commit.id()).unwrap(); 202 + assert_eq!(original_commit.verification().unwrap(), good_verification()); 203 + 204 + let mut tx = repo.start_transaction(); 205 + let mut_repo = tx.repo_mut(); 206 + let rewritten = mut_repo.rewrite_commit(&original_commit).write().unwrap(); 207 + 208 + let rewritten_commit = repo.store().get_commit(rewritten.id()).unwrap(); 209 + assert_eq!(rewritten_commit.verification().unwrap(), None); 210 + }