@@ -24,14 +24,35 @@ struct ProductVersion {
2424 version : String ,
2525}
2626
27+ /// Configuration that applies to all versions of a product, located at $ROOT/$product/stackable/patches/patchable.toml
28+ ///
29+ /// Must be created by hand (for now).
2730#[ derive( Deserialize , Serialize ) ]
31+ #[ serde( rename_all = "kebab-case" ) ]
2832struct ProductConfig {
33+ /// The upstream repository URL
2934 upstream : String ,
30- mirror : Option < String > ,
35+
36+ /// The repository that commits are mirrored to by `init --mirror`, typically `https://github.com/stackabletech/$product.git`
37+ ///
38+ /// This value is _not_ used by `checkout`, that uses [`ProductVersionConfig::mirror`] instead.
39+ /// `init --mirror` copies this value into [`ProductVersionConfig::mirror`].
40+ default_mirror : Option < String > ,
3141}
3242
43+ /// Configuration that applies to an individual version of a product, located at $ROOT/$product/stackable/patches/$version/patchable.toml
44+ ///
45+ /// Typically created by `patchable init`.
3346#[ derive( Deserialize , Serialize ) ]
3447struct ProductVersionConfig {
48+ /// The mirror repository that this version can be fetched from
49+ ///
50+ /// Copied from [`ProductConfig::default_mirror`] by `init --mirror`.
51+ mirror : Option < String > ,
52+
53+ /// The upstream base commit for this version
54+ ///
55+ /// Must be a commit ID, not a generic commitish (branch, tag, or anotherother ref), those are resolved by `init`.
3556 #[ serde( with = "utils::oid_serde" ) ]
3657 base : Oid ,
3758}
@@ -163,6 +184,9 @@ enum Cmd {
163184 /// Refs (such as tags and branches) will be resolved to commit IDs.
164185 #[ clap( long) ]
165186 base : String ,
187+
188+ #[ clap( long) ]
189+ mirror : bool ,
166190 } ,
167191
168192 /// Shows the patch directory for a given product version
@@ -211,6 +235,10 @@ pub enum Error {
211235 path : PathBuf ,
212236 } ,
213237
238+ #[ snafu( display(
239+ "mirroring requested, but default-mirror is not configured in product configuration"
240+ ) ) ]
241+ InitMirrorNotConfigured ,
214242 #[ snafu( display( "failed to add temporary mirror remote for {url:?}" ) ) ]
215243 AddMirrorRemote { source : git2:: Error , url : String } ,
216244 #[ snafu( display( "failed to push commit {commit} (as {refspec}) to mirror {url:?}" ) ) ]
@@ -312,10 +340,10 @@ fn main() -> Result<()> {
312340 let base_commit = repo:: resolve_and_fetch_commitish (
313341 & product_repo,
314342 & version_config. base . to_string ( ) ,
315- product_config
316- . mirror
317- . as_deref ( )
318- . unwrap_or ( & product_config . upstream ) ,
343+ version_config . mirror . as_deref ( ) . unwrap_or_else ( || {
344+ tracing :: warn! ( "this product version is not mirrored, re-init it with -- mirror before merging it" ) ;
345+ & product_config . upstream
346+ } ) ,
319347 )
320348 . context ( FetchBaseCommitSnafu ) ?;
321349 let base_branch = ctx. base_branch ( ) ;
@@ -425,7 +453,7 @@ fn main() -> Result<()> {
425453 ) ;
426454 }
427455
428- Cmd :: Init { pv, base } => {
456+ Cmd :: Init { pv, base, mirror } => {
429457 let ctx = ProductVersionContext {
430458 pv,
431459 images_repo_root,
@@ -449,7 +477,11 @@ fn main() -> Result<()> {
449477 . context ( FetchBaseCommitSnafu ) ?;
450478 tracing:: info!( ?base, base. commit = ?base_commit, "resolved base commit" ) ;
451479
452- if let Some ( mirror_url) = config. mirror {
480+ let mirror_url = if mirror {
481+ let mirror_url = config
482+ . default_mirror
483+ . context ( InitMirrorNotConfiguredSnafu ) ?;
484+
453485 // Add mirror remote
454486 let mut mirror_remote =
455487 product_repo
@@ -491,16 +523,25 @@ fn main() -> Result<()> {
491523 mirror_remote
492524 . push ( & [ & refspec] , Some ( & mut push_options) )
493525 . context ( PushToMirrorSnafu {
494- url : mirror_url,
526+ url : & mirror_url,
495527 refspec : & refspec,
496528 commit : base_commit,
497529 } ) ?;
498530
499531 tracing:: info!( "successfully pushed base ref to mirror" ) ;
532+ Some ( mirror_url)
533+ } else {
534+ tracing:: warn!(
535+ "this version is not mirrored, re-run with --mirror before merging into main"
536+ ) ;
537+ None
500538 } ;
501539
502540 tracing:: info!( "saving version-level configuration" ) ;
503- let config = ProductVersionConfig { base : base_commit } ;
541+ let config = ProductVersionConfig {
542+ base : base_commit,
543+ mirror : mirror_url,
544+ } ;
504545 let config_path = ctx. version_config_path ( ) ;
505546 if let Some ( config_dir) = config_path. parent ( ) {
506547 std:: fs:: create_dir_all ( config_dir)
0 commit comments