Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/automatic_updates
  • issue/automatic_updates-3159719
  • issue/automatic_updates-3227923
  • issue/automatic_updates-3227927
  • issue/automatic_updates-3227122
  • issue/automatic_updates-3227940
  • issue/automatic_updates-3228095
  • issue/automatic_updates-3228101
  • issue/automatic_updates-3228115
  • issue/automatic_updates-3228125
  • issue/automatic_updates-3228359
  • issue/automatic_updates-3228392
  • issue/automatic_updates-3225753
  • issue/automatic_updates-3227588
  • issue/automatic_updates-3228521
  • issue/automatic_updates-3228539
  • issue/automatic_updates-3226570
  • issue/automatic_updates-3228806
  • issue/automatic_updates-3227575
  • issue/automatic_updates-3229485
  • issue/automatic_updates-3228955
  • issue/automatic_updates-3230024
  • issue/automatic_updates-3230250
  • issue/automatic_updates-3230249
  • issue/automatic_updates-3230264
  • issue/automatic_updates-3230510
  • issue/automatic_updates-3230235
  • issue/automatic_updates-3230050
  • issue/automatic_updates-3230934
  • issue/automatic_updates-3230049
  • issue/automatic_updates-3230507
  • issue/automatic_updates-3231153
  • issue/automatic_updates-3231992
  • issue/automatic_updates-3232003
  • issue/automatic_updates-3232004
  • issue/automatic_updates-3231996
  • issue/automatic_updates-3231999
  • issue/automatic_updates-3230668
  • issue/automatic_updates-3232000
  • issue/automatic_updates-3232420
  • issue/automatic_updates-3232729
  • issue/automatic_updates-3232761
  • issue/automatic_updates-3231997
  • issue/automatic_updates-3232927
  • issue/automatic_updates-3232959
  • issue/automatic_updates-3233124
  • issue/automatic_updates-3230856
  • issue/automatic_updates-3233493
  • issue/automatic_updates-3233587
  • issue/automatic_updates-3233521
  • issue/automatic_updates-3236405
  • issue/automatic_updates-3236299
  • issue/automatic_updates-3238586
  • issue/automatic_updates-3238647
  • issue/automatic_updates-3238717
  • issue/automatic_updates-3238846
  • issue/automatic_updates-3238852
  • issue/automatic_updates-3238866
  • issue/automatic_updates-3238714
  • issue/automatic_updates-3239103
  • issue/automatic_updates-3233138
  • issue/automatic_updates-3239466
  • issue/automatic_updates-3239645
  • issue/automatic_updates-3239673
  • issue/automatic_updates-3277775
  • issue/automatic_updates-3280923
  • issue/automatic_updates-3275315
  • issue/automatic_updates-3279527
  • issue/automatic_updates-3279733
  • issue/automatic_updates-3281405
  • issue/automatic_updates-3281397
  • issue/automatic_updates-3280204
  • issue/automatic_updates-3277817
  • issue/automatic_updates-3277230
  • issue/automatic_updates-3276534
  • issue/automatic_updates-3279538
  • issue/automatic_updates-3280168
  • issue/automatic_updates-3271502
  • issue/automatic_updates-3283644
  • issue/automatic_updates-3302524
  • issue/automatic_updates-3275883
  • issue/automatic_updates-3280180
  • issue/automatic_updates-3274837
  • issue/automatic_updates-3281473
  • issue/automatic_updates-3281634
  • issue/automatic_updates-3239889
  • issue/automatic_updates-3240753
  • issue/automatic_updates-3233103
  • issue/automatic_updates-3240971
  • issue/automatic_updates-3233564
  • issue/automatic_updates-3241380
  • issue/automatic_updates-3241105
  • issue/automatic_updates-3242626
  • issue/automatic_updates-3242724
  • issue/automatic_updates-3243057
  • issue/automatic_updates-3243348
  • issue/automatic_updates-3243339
  • issue/automatic_updates-3243422
  • issue/automatic_updates-3243436
  • issue/automatic_updates-3243600
  • issue/automatic_updates-3243851
  • issue/automatic_updates-3243405
  • issue/automatic_updates-3244338
  • issue/automatic_updates-3244337
  • issue/automatic_updates-3244360
  • issue/automatic_updates-3244358
  • issue/automatic_updates-3244679
  • issue/automatic_updates-3244939
  • issue/automatic_updates-3244976
  • issue/automatic_updates-3245376
  • issue/automatic_updates-3245388
  • issue/automatic_updates-3245428
  • issue/automatic_updates-3245655
  • issue/automatic_updates-3245766
  • issue/automatic_updates-3245810
  • issue/automatic_updates-3245846
  • issue/automatic_updates-3246036
  • issue/automatic_updates-3246194
  • issue/automatic_updates-3246203
  • issue/automatic_updates-3246283
  • issue/automatic_updates-3279064
  • issue/automatic_updates-3246420
  • issue/automatic_updates-3246638
  • issue/automatic_updates-3246660
  • issue/automatic_updates-3246673
  • issue/automatic_updates-3246695
  • issue/automatic_updates-3245996
  • issue/automatic_updates-3247308
  • issue/automatic_updates-3247478
  • issue/automatic_updates-3247479
  • issue/automatic_updates-3279086
  • issue/automatic_updates-3248312
  • issue/automatic_updates-3248523
  • issue/automatic_updates-3248527
  • issue/automatic_updates-3244412
  • issue/automatic_updates-3248976
  • issue/automatic_updates-3248909
  • issue/automatic_updates-3246507
  • issue/automatic_updates-3249531
  • issue/automatic_updates-3249517
  • issue/automatic_updates-3249983
  • issue/automatic_updates-3249135
  • issue/automatic_updates-3250136
  • issue/automatic_updates-3250386
  • issue/automatic_updates-3251701
  • issue/automatic_updates-3250696
  • issue/automatic_updates-3248911
  • issue/automatic_updates-3227420
  • issue/automatic_updates-3252071
  • issue/automatic_updates-3252097
  • issue/automatic_updates-3252109
  • issue/automatic_updates-3252126
  • issue/automatic_updates-3249130
  • issue/automatic_updates-3251972
  • issue/automatic_updates-3252187
  • issue/automatic_updates-3252328
  • issue/automatic_updates-3252324
  • issue/automatic_updates-3252533
  • issue/automatic_updates-3253055
  • issue/automatic_updates-3253186
  • issue/automatic_updates-3253395
  • issue/automatic_updates-3253400
  • issue/automatic_updates-3253624
  • issue/automatic_updates-3253647
  • issue/automatic_updates-3253649
  • issue/automatic_updates-3253858
  • issue/automatic_updates-3254166
  • issue/automatic_updates-3254207
  • issue/automatic_updates-3279108
  • issue/automatic_updates-3254606
  • issue/automatic_updates-3254616
  • issue/automatic_updates-3254911
  • issue/automatic_updates-3255011
  • issue/automatic_updates-3255014
  • issue/automatic_updates-3255320
  • issue/automatic_updates-3277562
  • issue/automatic_updates-3255678
  • issue/automatic_updates-3256958
  • issue/automatic_updates-3257115
  • issue/automatic_updates-3257432
  • issue/automatic_updates-3257446
  • issue/automatic_updates-3257473
  • issue/automatic_updates-3257134
  • issue/automatic_updates-3257849
  • issue/automatic_updates-3258065
  • issue/automatic_updates-3258056
  • issue/automatic_updates-3258048
  • issue/automatic_updates-3258045
  • issue/automatic_updates-3258464
  • issue/automatic_updates-3258611
  • issue/automatic_updates-3258646
  • issue/automatic_updates-3258661
  • issue/automatic_updates-3258667
  • issue/automatic_updates-3258590
  • issue/automatic_updates-3259228
  • issue/automatic_updates-3259656
  • issue/automatic_updates-3252299
  • issue/automatic_updates-3259664
  • issue/automatic_updates-3259822
  • issue/automatic_updates-3259810
  • issue/automatic_updates-3259814
  • issue/automatic_updates-3260368
  • issue/automatic_updates-3257845
  • issue/automatic_updates-3260664
  • issue/automatic_updates-3260672
  • issue/automatic_updates-3260698
  • issue/automatic_updates-3260662
  • issue/automatic_updates-3260669
  • issue/automatic_updates-3260668
  • issue/automatic_updates-3261637
  • issue/automatic_updates-3261772
  • issue/automatic_updates-3261847
  • issue/automatic_updates-3262016
  • issue/automatic_updates-3262244
  • issue/automatic_updates-3262303
  • issue/automatic_updates-3261642
  • issue/automatic_updates-3262359
  • issue/automatic_updates-3262542
  • issue/automatic_updates-3261098
  • issue/automatic_updates-3260666
  • issue/automatic_updates-3262587
  • issue/automatic_updates-3262965
  • issue/automatic_updates-3263155
  • issue/automatic_updates-3263223
  • issue/automatic_updates-3254755
  • issue/automatic_updates-3261758
  • issue/automatic_updates-3258059
  • issue/automatic_updates-3259196
  • issue/automatic_updates-3263865
  • issue/automatic_updates-3262284
  • issue/automatic_updates-3264554
  • issue/automatic_updates-3248928
  • issue/automatic_updates-3248929
  • issue/automatic_updates-3265072
  • issue/automatic_updates-3265057
  • issue/automatic_updates-3265873
  • issue/automatic_updates-3266092
  • issue/automatic_updates-3266633
  • issue/automatic_updates-3266640
  • issue/automatic_updates-3266687
  • issue/automatic_updates-3266981
  • issue/automatic_updates-3267387
  • issue/automatic_updates-3267389
  • issue/automatic_updates-3267411
  • issue/automatic_updates-3267603
  • issue/automatic_updates-3265874
  • issue/automatic_updates-3267577
  • issue/automatic_updates-3267386
  • issue/automatic_updates-3268363
  • issue/automatic_updates-3268868
  • issue/automatic_updates-3268612
  • issue/automatic_updates-3269097
  • issue/automatic_updates-3267632
  • issue/automatic_updates-3270736
  • issue/automatic_updates-3271144
  • issue/automatic_updates-3271226
  • issue/automatic_updates-3271078
  • issue/automatic_updates-3271371
  • issue/automatic_updates-3267646
  • issue/automatic_updates-3272060
  • issue/automatic_updates-3265031
  • issue/automatic_updates-3253591
  • issue/automatic_updates-3272520
  • issue/automatic_updates-3272061
  • issue/automatic_updates-3272785
  • issue/automatic_updates-3273011
  • issue/automatic_updates-3273008
  • issue/automatic_updates-3273364
  • issue/automatic_updates-3273407
  • issue/automatic_updates-3271235
  • issue/automatic_updates-3273006
  • issue/automatic_updates-3271240
  • issue/automatic_updates-3271468
  • issue/automatic_updates-3272326
  • issue/automatic_updates-3273693
  • issue/automatic_updates-3264849
  • issue/automatic_updates-3273807
  • issue/automatic_updates-3273017
  • issue/automatic_updates-3274269
  • issue/automatic_updates-3274273
  • issue/automatic_updates-3274292
  • issue/automatic_updates-3273812
  • issue/automatic_updates-3274323
  • issue/automatic_updates-3274633
  • issue/automatic_updates-3274858
  • issue/automatic_updates-3274830
  • issue/automatic_updates-3274892
  • issue/automatic_updates-3275075
  • issue/automatic_updates-3275256
  • issue/automatic_updates-3275282
  • issue/automatic_updates-3275320
  • issue/automatic_updates-3275323
  • issue/automatic_updates-3275324
  • issue/automatic_updates-3275317
  • issue/automatic_updates-3275313
  • issue/automatic_updates-3275357
  • issue/automatic_updates-3275474
  • issue/automatic_updates-3275311
  • issue/automatic_updates-3275546
  • issue/automatic_updates-3275508
  • issue/automatic_updates-3275810
  • issue/automatic_updates-3275860
  • issue/automatic_updates-3275865
  • issue/automatic_updates-3275886
  • issue/automatic_updates-3275887
  • issue/automatic_updates-3276031
  • issue/automatic_updates-3276041
  • issue/automatic_updates-3276072
  • issue/automatic_updates-3276159
  • issue/automatic_updates-3276255
  • issue/automatic_updates-3275825
  • issue/automatic_updates-3276661
  • issue/automatic_updates-3275369
  • issue/automatic_updates-3277014
  • issue/automatic_updates-3277035
  • issue/automatic_updates-3272813
  • issue/automatic_updates-3277211
  • issue/automatic_updates-3277229
  • issue/automatic_updates-3275316
  • issue/automatic_updates-3274047
  • issue/automatic_updates-3277815
  • issue/automatic_updates-3276662
  • issue/automatic_updates-3277235
  • issue/automatic_updates-3278411
  • issue/automatic_updates-3278435
  • issue/automatic_updates-3279229
  • issue/automatic_updates-3277007
  • issue/automatic_updates-3284346
  • issue/automatic_updates-3239759
  • issue/automatic_updates-3284495
  • issue/automatic_updates-3284530
  • issue/automatic_updates-3282677
  • issue/automatic_updates-3281379
  • issue/automatic_updates-3285408
  • issue/automatic_updates-3285631
  • issue/automatic_updates-3285669
  • issue/automatic_updates-3273014
  • issue/automatic_updates-3273369
  • issue/automatic_updates-3285491
  • issue/automatic_updates-3285898
  • issue/automatic_updates-3287251
  • issue/automatic_updates-3291147
  • issue/automatic_updates-3286650
  • issue/automatic_updates-3291770
  • issue/automatic_updates-3280403
  • issue/automatic_updates-3291959
  • issue/automatic_updates-3287398
  • issue/automatic_updates-3285145
  • issue/automatic_updates-3292027
  • issue/automatic_updates-3278445
  • issue/automatic_updates-3292933
  • issue/automatic_updates-3292958
  • issue/automatic_updates-3293157
  • issue/automatic_updates-3292956
  • issue/automatic_updates-3293146
  • issue/automatic_updates-3293381
  • issue/automatic_updates-3293449
  • issue/automatic_updates-3293427
  • issue/automatic_updates-3293422
  • issue/automatic_updates-3293685
  • issue/automatic_updates-3291730
  • issue/automatic_updates-3293866
  • issue/automatic_updates-3294338
  • issue/automatic_updates-3293656
  • issue/automatic_updates-3294600
  • issue/automatic_updates-3294335
  • issue/automatic_updates-3295013
  • issue/automatic_updates-3284936
  • issue/automatic_updates-3295596
  • issue/automatic_updates-3295758
  • issue/automatic_updates-3295791
  • issue/automatic_updates-3295830
  • issue/automatic_updates-3295874
  • issue/automatic_updates-3295897
  • issue/automatic_updates-3296074
  • issue/automatic_updates-3295965
  • issue/automatic_updates-3296181
  • issue/automatic_updates-3296065
  • issue/automatic_updates-3296178
  • issue/automatic_updates-3296261
  • issue/automatic_updates-3293148
  • issue/automatic_updates-3303953
  • issue/automatic_updates-3304367
  • issue/automatic_updates-3304640
  • issue/automatic_updates-3304836
  • issue/automatic_updates-3304142
  • issue/automatic_updates-3298349
  • issue/automatic_updates-3298444
  • issue/automatic_updates-3298510
  • issue/automatic_updates-3298431
  • issue/automatic_updates-3298863
  • issue/automatic_updates-3298877
  • issue/automatic_updates-3298904
  • issue/automatic_updates-3298951
  • issue/automatic_updates-3299101
  • issue/automatic_updates-3299417
  • issue/automatic_updates-3293417
  • issue/automatic_updates-3299612
  • issue/automatic_updates-3299093
  • issue/automatic_updates-3299087
  • issue/automatic_updates-3300006
  • issue/automatic_updates-3300036
  • issue/automatic_updates-3293150
  • issue/automatic_updates-3303807
  • issue/automatic_updates-3303929
  • issue/automatic_updates-3304417
  • issue/automatic_updates-3303727
  • issue/automatic_updates-3305527
  • issue/automatic_updates-3301844
  • issue/automatic_updates-3302527
  • issue/automatic_updates-3302673
  • issue/automatic_updates-3302897
  • issue/automatic_updates-3303143
  • issue/automatic_updates-3303168
  • issue/automatic_updates-3303174
  • issue/automatic_updates-3303185
  • issue/automatic_updates-3303200
  • issue/automatic_updates-3303113
  • issue/automatic_updates-3304036
  • issue/automatic_updates-3304165
  • issue/automatic_updates-3304583
  • issue/automatic_updates-3303902
  • issue/automatic_updates-3304651
  • issue/automatic_updates-3305312
  • issue/automatic_updates-3305612
  • issue/automatic_updates-3305568
  • issue/automatic_updates-3305773
  • issue/automatic_updates-3305874
  • issue/automatic_updates-3310901
  • issue/automatic_updates-3310929
  • issue/automatic_updates-3310936
  • issue/automatic_updates-3310972
  • issue/automatic_updates-3311001
  • issue/automatic_updates-3311020
  • issue/automatic_updates-3305240
  • issue/automatic_updates-3305994
  • issue/automatic_updates-3305564
  • issue/automatic_updates-3305998
  • issue/automatic_updates-3306600
  • issue/automatic_updates-3306631
  • issue/automatic_updates-3307086
  • issue/automatic_updates-3307103
  • issue/automatic_updates-3307168
  • issue/automatic_updates-3306163
  • issue/automatic_updates-3304617
  • issue/automatic_updates-3307163
  • issue/automatic_updates-3307398
  • issue/automatic_updates-3307478
  • issue/automatic_updates-3307369
  • issue/automatic_updates-3308404
  • issue/automatic_updates-3307611
  • issue/automatic_updates-3308372
  • issue/automatic_updates-3308686
  • issue/automatic_updates-3308886
  • issue/automatic_updates-3309220
  • issue/automatic_updates-3309270
  • issue/automatic_updates-3308711
  • issue/automatic_updates-3309486
  • issue/automatic_updates-3305167
  • issue/automatic_updates-3309676
  • issue/automatic_updates-3309025
  • issue/automatic_updates-3309891
  • issue/automatic_updates-3308365
  • issue/automatic_updates-3310000
  • issue/automatic_updates-3309205
  • issue/automatic_updates-3248975
  • issue/automatic_updates-3310702
  • issue/automatic_updates-3272313
  • issue/automatic_updates-3310990
  • issue/automatic_updates-3310997
  • issue/automatic_updates-3311200
  • issue/automatic_updates-3310696
  • issue/automatic_updates-3311265
  • issue/automatic_updates-3303167
  • issue/automatic_updates-3310946
  • issue/automatic_updates-3308828
  • issue/automatic_updates-3310666
  • issue/automatic_updates-3109082
  • issue/automatic_updates-3311534
  • issue/automatic_updates-3311436
  • issue/automatic_updates-3308843
  • issue/automatic_updates-3303900
  • issue/automatic_updates-3312085
  • issue/automatic_updates-3312420
  • issue/automatic_updates-3312373
  • issue/automatic_updates-3312421
  • issue/automatic_updates-3312619
  • issue/automatic_updates-3312779
  • issue/automatic_updates-3275991
  • issue/automatic_updates-3312938
  • issue/automatic_updates-3312937
  • issue/automatic_updates-3312960
  • issue/automatic_updates-3312669
  • issue/automatic_updates-3312981
  • issue/automatic_updates-3313319
  • issue/automatic_updates-3313346
  • issue/automatic_updates-3310914
  • issue/automatic_updates-3317220
  • issue/automatic_updates-3317232
  • issue/automatic_updates-3317278
  • issue/automatic_updates-3317409
  • issue/automatic_updates-3317267
  • issue/automatic_updates-3317599
  • issue/automatic_updates-3317988
  • issue/automatic_updates-3318313
  • issue/automatic_updates-3313630
  • issue/automatic_updates-3313717
  • issue/automatic_updates-3313947
  • issue/automatic_updates-3313507
  • issue/automatic_updates-3276645
  • issue/automatic_updates-3313349
  • issue/automatic_updates-3314137
  • issue/automatic_updates-3314143
  • issue/automatic_updates-3304365
  • issue/automatic_updates-3317796
  • issue/automatic_updates-3317996
  • issue/automatic_updates-3316484
  • issue/automatic_updates-3313414
  • issue/automatic_updates-3314764
  • issue/automatic_updates-3314771
  • issue/automatic_updates-3314787
  • issue/automatic_updates-3314805
  • issue/automatic_updates-3314734
  • issue/automatic_updates-3298889
  • issue/automatic_updates-3314803
  • issue/automatic_updates-3315139
  • issue/automatic_updates-3314946
  • issue/automatic_updates-3315449
  • issue/automatic_updates-3315798
  • issue/automatic_updates-3315834
  • issue/automatic_updates-3309602
  • issue/automatic_updates-3316115
  • issue/automatic_updates-3316131
  • issue/automatic_updates-3316293
  • issue/automatic_updates-3316318
  • issue/automatic_updates-3310729
  • issue/automatic_updates-3315700
  • issue/automatic_updates-3316668
  • issue/automatic_updates-3316721
  • issue/automatic_updates-3306283
  • issue/automatic_updates-3316611
  • issue/automatic_updates-3316895
  • issue/automatic_updates-3317385
  • issue/automatic_updates-3318625
  • issue/automatic_updates-3318770
  • issue/automatic_updates-3318846
  • issue/automatic_updates-3318927
  • issue/automatic_updates-3318933
  • issue/automatic_updates-3319044
  • issue/automatic_updates-3319045
  • issue/automatic_updates-3325716
  • issue/automatic_updates-3324421
  • issue/automatic_updates-3320486
  • issue/automatic_updates-3320558
  • issue/automatic_updates-3321206
  • issue/automatic_updates-3326934
  • issue/automatic_updates-3320755
  • issue/automatic_updates-3328765
  • issue/automatic_updates-3325654
  • issue/automatic_updates-3325869
  • issue/automatic_updates-3277034
  • issue/automatic_updates-3328516
  • issue/automatic_updates-3322546
  • issue/automatic_updates-3320487
  • issue/automatic_updates-3320792
  • issue/automatic_updates-3320815
  • issue/automatic_updates-3320638
  • issue/automatic_updates-3321256
  • issue/automatic_updates-3321684
  • issue/automatic_updates-3325522
  • issue/automatic_updates-3326334
  • issue/automatic_updates-3328234
  • issue/automatic_updates-3328740
  • issue/automatic_updates-3316932
  • issue/automatic_updates-3321386
  • issue/automatic_updates-3321933
  • issue/automatic_updates-3321282
  • issue/automatic_updates-3326801
  • issue/automatic_updates-3327753
  • issue/automatic_updates-3328742
  • issue/automatic_updates-3322313
  • issue/automatic_updates-3322203
  • issue/automatic_updates-3322150
  • issue/automatic_updates-3322404
  • issue/automatic_updates-3321236
  • issue/automatic_updates-3321994
  • issue/automatic_updates-3322589
  • issue/automatic_updates-3321904
  • issue/automatic_updates-3316855
  • issue/automatic_updates-3322931
  • issue/automatic_updates-3322913
  • issue/automatic_updates-3323037
  • issue/automatic_updates-3322918
  • issue/automatic_updates-3323211
  • issue/automatic_updates-3323565
  • issue/automatic_updates-3320824
  • issue/automatic_updates-3320836
  • issue/automatic_updates-3329002
  • issue/automatic_updates-3321971
  • issue/automatic_updates-3299094
  • issue/automatic_updates-3248544
  • issue/automatic_updates-3330139
  • issue/automatic_updates-3330365
  • issue/automatic_updates-3330712
  • issue/automatic_updates-3318065
  • issue/automatic_updates-3331310
  • issue/automatic_updates-3322917
  • issue/automatic_updates-3330140
  • issue/automatic_updates-3323003
  • issue/automatic_updates-3331355
  • issue/automatic_updates-3334054
  • issue/automatic_updates-3323706
  • issue/automatic_updates-3331168
  • issue/automatic_updates-3343430
  • issue/automatic_updates-3344562
  • issue/automatic_updates-3345039
  • issue/automatic_updates-3344039
  • issue/automatic_updates-3345313
  • issue/automatic_updates-3331471
  • issue/automatic_updates-3334994
  • issue/automatic_updates-3327229
  • issue/automatic_updates-3343889
  • issue/automatic_updates-3344124
  • issue/automatic_updates-3344689
  • issue/automatic_updates-3316368
  • issue/automatic_updates-3345767
  • issue/automatic_updates-3317815
  • issue/automatic_updates-3328600
  • issue/automatic_updates-3332256
  • issue/automatic_updates-3335766
  • issue/automatic_updates-3335802
  • issue/automatic_updates-3335908
  • issue/automatic_updates-3336243
  • issue/automatic_updates-3336247
  • issue/automatic_updates-3336255
  • issue/automatic_updates-3336259
  • issue/automatic_updates-3337062
  • issue/automatic_updates-3337068
  • issue/automatic_updates-3311229
  • issue/automatic_updates-3337697
  • issue/automatic_updates-3343768
  • issue/automatic_updates-3344127
  • issue/automatic_updates-3344595
  • issue/automatic_updates-3345763
  • issue/automatic_updates-3345765
  • issue/automatic_updates-3345771
  • issue/automatic_updates-3337760
  • issue/automatic_updates-3337049
  • issue/automatic_updates-3342430
  • issue/automatic_updates-3319507
  • issue/automatic_updates-3344583
  • issue/automatic_updates-3345764
  • issue/automatic_updates-3345768
  • issue/automatic_updates-3338667
  • issue/automatic_updates-3339016
  • issue/automatic_updates-3343827
  • issue/automatic_updates-3344556
  • issue/automatic_updates-3338666
  • issue/automatic_updates-3345649
  • issue/automatic_updates-3339657
  • issue/automatic_updates-3339719
  • issue/automatic_updates-3338789
  • issue/automatic_updates-3340022
  • issue/automatic_updates-3340284
  • issue/automatic_updates-3340638
  • issue/automatic_updates-3316617
  • issue/automatic_updates-3341224
  • issue/automatic_updates-3337953
  • issue/automatic_updates-3339714
  • issue/automatic_updates-3341708
  • issue/automatic_updates-3341841
  • issue/automatic_updates-3326486
  • issue/automatic_updates-3321474
  • issue/automatic_updates-3341974
  • issue/automatic_updates-3342120
  • issue/automatic_updates-3342227
  • issue/automatic_updates-3323461
  • issue/automatic_updates-3342137
  • issue/automatic_updates-3342460
  • issue/automatic_updates-3342364
  • issue/automatic_updates-3345028
  • issue/automatic_updates-3345549
  • issue/automatic_updates-3345881
  • issue/automatic_updates-3345762
  • issue/automatic_updates-3342726
  • issue/automatic_updates-3337667
  • issue/automatic_updates-3343463
  • issue/automatic_updates-3345766
  • issue/automatic_updates-3345754
  • issue/automatic_updates-3345633
  • issue/automatic_updates-3345772
  • issue/automatic_updates-3345769
  • issue/automatic_updates-3345761
  • issue/automatic_updates-3345755
  • issue/automatic_updates-3345760
  • issue/automatic_updates-3345757
  • issue/automatic_updates-3346520
  • issue/automatic_updates-3346545
  • issue/automatic_updates-3337054
  • issue/automatic_updates-3346628
  • issue/automatic_updates-3346717
  • issue/automatic_updates-3346594
  • issue/automatic_updates-3346659
  • issue/automatic_updates-3347031
  • issue/automatic_updates-3346547
  • issue/automatic_updates-3347164
  • issue/automatic_updates-3318306
  • issue/automatic_updates-3345646
  • issue/automatic_updates-3347165
  • issue/automatic_updates-3347959
  • issue/automatic_updates-3347267
  • issue/automatic_updates-3338346
  • issue/automatic_updates-3348122
  • issue/automatic_updates-3348129
  • issue/automatic_updates-3348162
  • issue/automatic_updates-3348276
  • issue/automatic_updates-3348441
  • issue/automatic_updates-3351604
  • issue/automatic_updates-3316843
  • issue/automatic_updates-3351908
  • issue/automatic_updates-3352731
  • issue/automatic_updates-3352898
  • issue/automatic_updates-3348866
  • issue/automatic_updates-3342817
  • issue/automatic_updates-3348159
  • issue/automatic_updates-3349142
  • issue/automatic_updates-3349966
  • issue/automatic_updates-3350909
  • issue/automatic_updates-3351594
  • issue/automatic_updates-3351883
  • issue/automatic_updates-3351925
  • issue/automatic_updates-3352198
  • issue/automatic_updates-3334552
  • issue/automatic_updates-3342790
  • issue/automatic_updates-3345222
  • issue/automatic_updates-3351212
  • issue/automatic_updates-3351093
  • issue/automatic_updates-3351247
  • issue/automatic_updates-3351962
  • issue/automatic_updates-3345641
  • issue/automatic_updates-3338940
  • issue/automatic_updates-3343721
  • issue/automatic_updates-3351069
  • issue/automatic_updates-3353219
  • issue/automatic_updates-3159920
  • issue/automatic_updates-3352355
  • issue/automatic_updates-3341469
  • issue/automatic_updates-3354099
  • issue/automatic_updates-3339659
  • issue/automatic_updates-3354312
  • issue/automatic_updates-3351895
  • issue/automatic_updates-3354249
  • issue/automatic_updates-3353270
  • issue/automatic_updates-3354003
  • issue/automatic_updates-3355074
  • issue/automatic_updates-3355094
  • issue/automatic_updates-3355105
  • issue/automatic_updates-3355162
  • issue/automatic_updates-3355446
  • issue/automatic_updates-3355045
  • issue/automatic_updates-3355558
  • issue/automatic_updates-3355553
  • issue/automatic_updates-3354594
  • issue/automatic_updates-3355609
  • issue/automatic_updates-3354325
  • issue/automatic_updates-3356395
  • issue/automatic_updates-3356638
  • issue/automatic_updates-3356640
  • issue/automatic_updates-3354701
  • issue/automatic_updates-3355463
  • issue/automatic_updates-3356804
  • issue/automatic_updates-3357721
  • issue/automatic_updates-3357578
  • issue/automatic_updates-3357657
  • issue/automatic_updates-3304108
  • issue/automatic_updates-3357941
  • issue/automatic_updates-3358012
  • issue/automatic_updates-3345535
  • issue/automatic_updates-3354827
  • issue/automatic_updates-3358570
  • issue/automatic_updates-3358878
  • issue/automatic_updates-3355628
  • issue/automatic_updates-3358504
  • issue/automatic_updates-3357969
  • issue/automatic_updates-3359609
  • issue/automatic_updates-3359727
  • issue/automatic_updates-3359825
  • issue/automatic_updates-3359820
  • issue/automatic_updates-3360548
  • issue/automatic_updates-3357480
  • issue/automatic_updates-3360656
  • issue/automatic_updates-3360763
  • issue/automatic_updates-3360655
  • issue/automatic_updates-3355618
  • issue/automatic_updates-3349351
  • issue/automatic_updates-3362110
  • issue/automatic_updates-3362143
  • issue/automatic_updates-3362589
  • issue/automatic_updates-3349004
  • issue/automatic_updates-3362507
  • issue/automatic_updates-3362746
  • issue/automatic_updates-3362978
  • issue/automatic_updates-3363259
  • issue/automatic_updates-3363725
  • issue/automatic_updates-3363926
  • issue/automatic_updates-3363937
  • issue/automatic_updates-3364514
  • issue/automatic_updates-3284443
  • issue/automatic_updates-3363938
  • issue/automatic_updates-3364731
  • issue/automatic_updates-3364748
  • issue/automatic_updates-3364735
  • issue/automatic_updates-3364725
  • issue/automatic_updates-3359670
  • issue/automatic_updates-3365133
  • issue/automatic_updates-3365151
  • issue/automatic_updates-3365177
  • issue/automatic_updates-3364958
  • issue/automatic_updates-3365390
  • issue/automatic_updates-3365414
  • issue/automatic_updates-3346644
  • issue/automatic_updates-3366267
  • issue/automatic_updates-3366289
  • issue/automatic_updates-3366499
  • issue/automatic_updates-3365437
  • issue/automatic_updates-3354914
  • issue/automatic_updates-3253828
  • issue/automatic_updates-3345484
  • issue/automatic_updates-3352846
  • issue/automatic_updates-3368741
  • issue/automatic_updates-3406008
  • issue/automatic_updates-3406122
  • issue/automatic_updates-3370197
  • issue/automatic_updates-3366271
  • issue/automatic_updates-3364135
  • issue/automatic_updates-3370603
  • issue/automatic_updates-3400146
  • issue/automatic_updates-3406010
  • issue/automatic_updates-3404429
  • issue/automatic_updates-3371212
  • issue/automatic_updates-3371076
  • issue/automatic_updates-3372673
  • issue/automatic_updates-3368808
  • issue/automatic_updates-3374175
  • issue/automatic_updates-3374739
  • issue/automatic_updates-3374753
  • issue/automatic_updates-3375679
  • issue/automatic_updates-3377237
  • issue/automatic_updates-3377245
  • issue/automatic_updates-3378774
  • issue/automatic_updates-3378793
  • issue/automatic_updates-3360485
  • issue/automatic_updates-3380698
  • issue/automatic_updates-3375940
  • issue/automatic_updates-3381294
  • issue/automatic_updates-3381484
  • issue/automatic_updates-3382942
  • issue/automatic_updates-3383462
  • issue/automatic_updates-3383451
  • issue/automatic_updates-3384359
  • issue/automatic_updates-3384637
  • issue/automatic_updates-3375640
  • issue/automatic_updates-3386135
  • issue/automatic_updates-3386533
  • issue/automatic_updates-3387610
  • issue/automatic_updates-3387637
  • issue/automatic_updates-3387656
  • issue/automatic_updates-3389157
  • issue/automatic_updates-3388965
  • issue/automatic_updates-3387379
  • issue/automatic_updates-3390493
  • issue/automatic_updates-3308235
  • issue/automatic_updates-3391715
  • issue/automatic_updates-3392246
  • issue/automatic_updates-3393633
  • issue/automatic_updates-3379344
  • issue/automatic_updates-3394413
  • issue/automatic_updates-3394705
  • issue/automatic_updates-3394936
  • issue/automatic_updates-3363497
  • issue/automatic_updates-3395782
  • issue/automatic_updates-3341406
  • issue/automatic_updates-3311472
  • issue/automatic_updates-3397228
  • issue/automatic_updates-3352654
  • issue/automatic_updates-3398782
  • issue/automatic_updates-3399147
  • issue/automatic_updates-3399155
  • issue/automatic_updates-3406812
  • issue/automatic_updates-3408483
  • issue/automatic_updates-3408488
  • issue/automatic_updates-3408560
  • issue/automatic_updates-3437633
  • issue/automatic_updates-3408835
  • issue/automatic_updates-3408937
  • issue/automatic_updates-3409491
  • issue/automatic_updates-3409519
  • issue/automatic_updates-3377458
  • issue/automatic_updates-3437951
  • issue/automatic_updates-3409774
  • issue/automatic_updates-3410047
  • issue/automatic_updates-3411110
  • issue/automatic_updates-3411241
  • issue/automatic_updates-3411276
  • issue/automatic_updates-3411392
  • issue/automatic_updates-3411240
  • issue/automatic_updates-3412630
  • issue/automatic_updates-3413866
  • issue/automatic_updates-3414168
  • issue/automatic_updates-3415291
  • issue/automatic_updates-3415389
  • issue/automatic_updates-3415403
  • issue/automatic_updates-3416768
  • issue/automatic_updates-3417905
  • issue/automatic_updates-3420188
  • issue/automatic_updates-3421641
  • issue/automatic_updates-3424290
  • issue/automatic_updates-3426229
  • issue/automatic_updates-3426666
  • issue/automatic_updates-3426716
  • issue/automatic_updates-3428199
  • issue/automatic_updates-3436741
  • issue/automatic_updates-3441923
  • issue/automatic_updates-3428651
  • issue/automatic_updates-3441799
  • issue/automatic_updates-3443249
  • issue/automatic_updates-3428922
  • issue/automatic_updates-3441817
  • issue/automatic_updates-3429248
  • issue/automatic_updates-3440646
  • issue/automatic_updates-3437877
  • issue/automatic_updates-3445149
  • issue/automatic_updates-3429268
  • issue/automatic_updates-3442153
  • issue/automatic_updates-3438156
  • issue/automatic_updates-3436993
  • issue/automatic_updates-3437704
  • issue/automatic_updates-3432496
  • issue/automatic_updates-3440006
  • issue/automatic_updates-3435893
  • issue/automatic_updates-3441577
  • issue/automatic_updates-3437023
  • issue/automatic_updates-3432391
  • issue/automatic_updates-3432447
  • issue/automatic_updates-3432472
  • issue/automatic_updates-3432489
  • issue/automatic_updates-3432476
  • issue/automatic_updates-3435918
  • issue/automatic_updates-3439067
  • issue/automatic_updates-3437409
  • issue/automatic_updates-3449093
  • issue/automatic_updates-3449480
  • issue/automatic_updates-3449519
  • issue/automatic_updates-3449631
  • issue/automatic_updates-3449636
  • issue/automatic_updates-3449689
  • issue/automatic_updates-3449693
  • issue/automatic_updates-3450884
  • issue/automatic_updates-3452870
  • issue/automatic_updates-3453030
  • issue/automatic_updates-3455161
  • issue/automatic_updates-3459557
  • issue/automatic_updates-3462138
  • issue/automatic_updates-3462168
  • issue/automatic_updates-3462883
  • issue/automatic_updates-3463662
  • issue/automatic_updates-3463813
  • issue/automatic_updates-3446371
  • issue/automatic_updates-3465155
  • issue/automatic_updates-3340355
  • issue/automatic_updates-3467749
  • issue/automatic_updates-3473410
  • issue/automatic_updates-3441926
  • issue/automatic_updates-3474603
  • issue/automatic_updates-3484802
  • issue/automatic_updates-3498586
  • issue/automatic_updates-3499481
  • issue/automatic_updates-3498018
  • issue/automatic_updates-3506632
  • issue/automatic_updates-3511959
  • issue/automatic_updates-3511943
981 results
Show changes
Showing
with 837 additions and 424 deletions
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Event;
use Drupal\package_manager\ImmutablePathList;
use Drupal\package_manager\StageBase;
use PhpTuf\ComposerStager\API\Path\Value\PathListInterface;
/**
* Event fired before a staging area is created.
* Event fired before a stage directory is created.
*/
class PreCreateEvent extends PreOperationStageEvent {
final class PreCreateEvent extends PreOperationStageEvent {
/**
* The list of paths to exclude from the stage directory.
*
* @var \Drupal\package_manager\ImmutablePathList
*/
public readonly ImmutablePathList $excludedPaths;
use ExcludedPathsTrait;
/**
* Constructs a PreCreateEvent object.
*
* @param \Drupal\package_manager\StageBase $stage
* The stage which fired this event.
* @param \PhpTuf\ComposerStager\API\Path\Value\PathListInterface $excluded_paths
* The list of paths to exclude. These will not be copied into the stage
* directory when it is created.
*/
public function __construct(StageBase $stage, PathListInterface $excluded_paths) {
parent::__construct($stage);
$this->excludedPaths = new ImmutablePathList($excluded_paths);
}
}
<?php
namespace Drupal\package_manager\Event;
/**
* Event fired before the staging area is destroyed.
*
* If the stage is being force destroyed, ::getStage() may return an object of a
* different class than the one that originally created the staging area.
*
* @see \Drupal\package_manager\Stage::destroy()
*/
class PreDestroyEvent extends PreOperationStageEvent {
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Event;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\package_manager\ValidationResult;
use Drupal\system\SystemManager;
/**
* Base class for events dispatched before a stage life cycle operation.
......@@ -30,17 +33,62 @@ abstract class PreOperationStageEvent extends StageEvent {
public function getResults(?int $severity = NULL): array {
if ($severity !== NULL) {
return array_filter($this->results, function ($result) use ($severity) {
return $result->getSeverity() === $severity;
return $result->severity === $severity;
});
}
return $this->results;
}
/**
* Adds error information to the event.
* Convenience method, adds error validation result.
*
* @param \Drupal\Core\StringTranslation\TranslatableMarkup[] $messages
* The error messages.
* @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $summary
* (optional) The summary of error messages. Only required if there
* is more than one message.
*/
public function addError(array $messages, ?TranslatableMarkup $summary = NULL): void {
$this->results[] = ValidationResult::createError($messages, $summary);
$this->addResult(ValidationResult::createError(array_values($messages), $summary));
}
/**
* Convenience method, adds an error validation result from a throwable.
*
* @param \Throwable $throwable
* The throwable.
* @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $summary
* (optional) The summary of error messages.
*/
public function addErrorFromThrowable(\Throwable $throwable, ?TranslatableMarkup $summary = NULL): void {
$this->addResult(ValidationResult::createErrorFromThrowable($throwable, $summary));
}
/**
* Adds a validation result to the event.
*
* @param \Drupal\package_manager\ValidationResult $result
* The validation result to add.
*
* @throws \InvalidArgumentException
* Thrown if the validation result is not an error.
*/
public function addResult(ValidationResult $result): void {
// Only errors are allowed for this event.
if ($result->severity !== SystemManager::REQUIREMENT_ERROR) {
throw new \InvalidArgumentException('Only errors are allowed.');
}
$this->results[] = $result;
}
/**
* {@inheritdoc}
*/
public function stopPropagation(): void {
if (empty($this->getResults(SystemManager::REQUIREMENT_ERROR))) {
$this->addErrorFromThrowable(new \LogicException('Event propagation stopped without any errors added to the event. This bypasses the package_manager validation system.'));
}
parent::stopPropagation();
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Event;
/**
* Event fired before packages are updated to the staging area.
* Event fired before packages are updated to the stage directory.
*/
class PreRequireEvent extends PreOperationStageEvent {
final class PreRequireEvent extends PreOperationStageEvent {
use RequireEventTrait;
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Event;
use Drupal\package_manager\StageBase;
/**
* Common methods for pre- and post-require events.
*
* @internal
* This is an internal part of Automatic Updates and should only be used by
* \Drupal\package_manager\Event\PreRequireEvent and
* \Drupal\package_manager\Event\PostRequireEvent.
*/
trait RequireEventTrait {
/**
* The runtime packages, in the form 'vendor/name:constraint'.
*
* @var string[]
*/
private $runtimePackages;
/**
* The dev packages to be required, in the form 'vendor/name:constraint'.
*
* @var string[]
*/
private $devPackages;
/**
* Constructs the object.
*
* @param \Drupal\package_manager\StageBase $stage
* The stage.
* @param string[] $runtime_packages
* The runtime (i.e., non-dev) packages to be required, in the form
* 'vendor/name:constraint'.
* @param string[] $dev_packages
* The dev packages to be required, in the form 'vendor/name:constraint'.
*/
public function __construct(StageBase $stage, array $runtime_packages, array $dev_packages = []) {
$this->runtimePackages = $runtime_packages;
$this->devPackages = $dev_packages;
parent::__construct($stage);
}
/**
* Gets the runtime (i.e., non-dev) packages.
*
* @return string[]
* An array of packages where the values are version constraints and keys
* are package names in the form `vendor/name`. Packages without a version
* constraint will default to `*`.
*/
public function getRuntimePackages(): array {
return $this->getKeyedPackages($this->runtimePackages);
}
/**
* Gets the dev packages.
*
* @return string[]
* An array of packages where the values are version constraints and keys
* are package names in the form `vendor/name`. Packages without a version
* constraint will default to `*`.
*/
public function getDevPackages(): array {
return $this->getKeyedPackages($this->devPackages);
}
/**
* Gets packages as a keyed array.
*
* @param string[] $packages
* The packages, in the form 'vendor/name:version'.
*
* @return string[]
* An array of packages where the values are version constraints and keys
* are package names in the form `vendor/name`. Packages without a version
* constraint will default to `*`.
*/
private function getKeyedPackages(array $packages): array {
$keyed_packages = [];
foreach ($packages as $package) {
if (strpos($package, ':') > 0) {
[$name, $constraint] = explode(':', $package);
}
else {
[$name, $constraint] = [$package, '*'];
}
$keyed_packages[$name] = $constraint;
}
return $keyed_packages;
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Event;
use Drupal\package_manager\Stage;
use Drupal\package_manager\StageBase;
use Symfony\Contracts\EventDispatcher\Event;
/**
* Base class for all events related to the life cycle of the staging area.
* Base class for all events related to the life cycle of the stage.
*/
abstract class StageEvent extends Event {
/**
* The stage which fired this event.
*
* @var \Drupal\package_manager\Stage
*/
protected $stage;
/**
* Constructs a StageEvent object.
*
* @param \Drupal\package_manager\Stage $stage
* The stage which fired this event.
*/
public function __construct(Stage $stage) {
$this->stage = $stage;
}
/**
* Returns the stage which fired this event.
*
* @return \Drupal\package_manager\Stage
* @param \Drupal\package_manager\StageBase $stage
* The stage which fired this event.
*/
public function getStage(): Stage {
return $this->stage;
public function __construct(public readonly StageBase $stage) {
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Event;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\package_manager\ImmutablePathList;
use Drupal\package_manager\StageBase;
use Drupal\package_manager\ValidationResult;
use PhpTuf\ComposerStager\API\Path\Value\PathListInterface;
/**
* Event fired to check the status of the system to use Package Manager.
*
* The event's stage will be set with the type of stage that will perform the
* operations. The stage may or may not be currently in use.
*/
final class StatusCheckEvent extends PreOperationStageEvent {
/**
* The paths to exclude, or NULL if there was an error collecting them.
*
* @var \Drupal\package_manager\ImmutablePathList|null
*
* @see ::__construct()
*/
public readonly ?ImmutablePathList $excludedPaths;
/**
* Constructs a StatusCheckEvent object.
*
* @param \Drupal\package_manager\StageBase $stage
* The stage which fired this event.
* @param \PhpTuf\ComposerStager\API\Path\Value\PathListInterface|\Throwable $excluded_paths
* The list of paths to exclude or, if an error occurred while they were
* being collected, the throwable from that error. If this is a throwable,
* it will be converted to a validation error.
*/
public function __construct(StageBase $stage, PathListInterface|\Throwable $excluded_paths) {
parent::__construct($stage);
// If there was an error collecting the excluded paths, convert it to a
// validation error so we can still run status checks that don't need to
// examine the list of excluded paths.
if ($excluded_paths instanceof \Throwable) {
$this->addErrorFromThrowable($excluded_paths);
$excluded_paths = NULL;
}
else {
$excluded_paths = new ImmutablePathList($excluded_paths);
}
$this->excludedPaths = $excluded_paths;
}
/**
* Adds warning information to the event.
*
* @param \Drupal\Core\StringTranslation\TranslatableMarkup[] $messages
* One or more warning messages.
* @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $summary
* A summary of warning messages. Required if there is more than one
* message, optional otherwise.
*/
public function addWarning(array $messages, ?TranslatableMarkup $summary = NULL): void {
$this->addResult(ValidationResult::createWarning($messages, $summary));
}
/**
* {@inheritdoc}
*/
public function addResult(ValidationResult $result): void {
// Override the parent to also allow warnings.
$this->results[] = $result;
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\EventSubscriber;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\package_manager\Event\PostApplyEvent;
use Drupal\package_manager\Event\PostRequireEvent;
use Drupal\package_manager\ComposerInspector;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\PathLocator;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Event subscriber to log changes that happen during the stage life cycle.
*
* @internal
* This is an internal part of Package Manager and may be changed or removed
* at any time without warning. External code should not interact with this
* class.
*/
final class ChangeLogger implements EventSubscriberInterface, LoggerAwareInterface {
use LoggerAwareTrait;
use StringTranslationTrait;
/**
* The metadata key under which to store the installed packages at start.
*
* @var string
*
* @see ::recordInstalledPackages()
*/
private const INSTALLED_PACKAGES_KEY = 'package_manager_installed_packages';
/**
* The metadata key under which to store the requested package versions.
*
* @var string
*
* @see ::recordRequestedPackageVersions()
*/
private const REQUESTED_PACKAGES_KEY = 'package_manager_requested_packages';
/**
* Constructs a ChangeLogger object.
*
* @param \Drupal\package_manager\ComposerInspector $composerInspector
* The Composer inspector service.
* @param \Drupal\package_manager\PathLocator $pathLocator
* The path locator service.
*/
public function __construct(
private readonly ComposerInspector $composerInspector,
private readonly PathLocator $pathLocator,
) {}
/**
* Records packages installed in the project root.
*
* We need to do this before the stage has been created, so that we have a
* complete picture of which requested packages are merely being updated, and
* which are being newly added. Once the stage has been created, the installed
* packages won't change -- if they do, a validation error will be raised.
*
* @param \Drupal\package_manager\Event\PreCreateEvent $event
* The event being handled.
*
* @see \Drupal\package_manager\Validator\LockFileValidator
*/
public function recordInstalledPackages(PreCreateEvent $event): void {
$packages = $this->composerInspector->getInstalledPackagesList($this->pathLocator->getProjectRoot());
$event->stage->setMetadata(static::INSTALLED_PACKAGES_KEY, $packages);
}
/**
* Records requested packages.
*
* @param \Drupal\package_manager\Event\PostRequireEvent $event
* The event object.
*/
public function recordRequestedPackageVersions(PostRequireEvent $event): void {
// There could be multiple require operations, so overlay the requested
// packages from the current operation onto the requested packages from any
// previous require operation.
$requested_packages = array_merge(
$event->stage->getMetadata(static::REQUESTED_PACKAGES_KEY) ?? [],
$event->getRuntimePackages(),
$event->getDevPackages(),
);
$event->stage->setMetadata(static::REQUESTED_PACKAGES_KEY, $requested_packages);
}
/**
* Logs all Package Manager changes.
*
* @param \Drupal\package_manager\Event\PostApplyEvent $event
* The event being handled.
*/
public function logChanges(PostApplyEvent $event): void {
$installed_at_start = $event->stage->getMetadata(static::INSTALLED_PACKAGES_KEY);
$installed_post_apply = $this->composerInspector->getInstalledPackagesList($this->pathLocator->getProjectRoot());
// Compare the packages which were installed when the stage was created
// against the package versions that were requested over all of the stage's
// require operations, and create a log entry listing all of it.
$requested_log = [];
$requested_packages = $event->stage->getMetadata(static::REQUESTED_PACKAGES_KEY) ?? [];
// Sort the requested packages by name, to make it easier to review a large
// change list.
ksort($requested_packages, SORT_NATURAL);
foreach ($requested_packages as $name => $constraint) {
$installed_version = $installed_at_start[$name]?->version;
if ($installed_version === NULL) {
// For clarity, make the "any version" constraint human-readable.
if ($constraint === '*') {
$constraint = $this->t('* (any version)');
}
$requested_log[] = $this->t('- Install @name @constraint', [
'@name' => $name,
'@constraint' => $constraint,
]);
}
else {
$requested_log[] = $this->t('- Update @name from @installed_version to @constraint', [
'@name' => $name,
'@installed_version' => $installed_version,
'@constraint' => $constraint,
]);
}
}
// It's possible that $requested_log will be empty -- for example, a custom
// stage that only does removals, or some other operation, and never
// dispatches PostRequireEvent.
if ($requested_log) {
$message = $this->t("Requested changes:\n@change_list", [
'@change_list' => implode("\n", array_map('strval', $requested_log)),
]);
$this->logger->info($message);
}
// Create a separate log entry listing everything that actually changed.
$applied_log = [];
$updated_packages = $installed_post_apply->getPackagesWithDifferentVersionsIn($installed_at_start);
// Sort the packages by name to make it easier to review large change sets.
$updated_packages->ksort(SORT_NATURAL);
foreach ($updated_packages as $name => $package) {
$applied_log[] = $this->t('- Updated @name from @installed_version to @updated_version', [
'@name' => $name,
'@installed_version' => $installed_at_start[$name]->version,
'@updated_version' => $package->version,
]);
}
$added_packages = $installed_post_apply->getPackagesNotIn($installed_at_start);
$added_packages->ksort(SORT_NATURAL);
foreach ($added_packages as $name => $package) {
$applied_log[] = $this->t('- Installed @name @version', [
'@name' => $name,
'@version' => $package->version,
]);
}
$removed_packages = $installed_at_start->getPackagesNotIn($installed_post_apply);
$removed_packages->ksort(SORT_NATURAL);
foreach ($installed_at_start->getPackagesNotIn($installed_post_apply) as $name => $package) {
$applied_log[] = $this->t('- Uninstalled @name', ['@name' => $name]);
}
$message = $this->t("Applied changes:\n@change_list", [
'@change_list' => implode("\n", array_map('strval', $applied_log)),
]);
$this->logger->info($message);
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
return [
PreCreateEvent::class => ['recordInstalledPackages'],
PostRequireEvent::class => ['recordRequestedPackageVersions'],
PostApplyEvent::class => ['logChanges'],
];
}
}
<?php
namespace Drupal\package_manager\EventSubscriber;
use Drupal\Core\Database\Connection;
use Drupal\Core\StreamWrapper\LocalStream;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Drupal\package_manager\Event\PreApplyEvent;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\Event\StageEvent;
use Drupal\package_manager\PathLocator;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
/**
* Defines an event subscriber to exclude certain paths from staging areas.
*/
class ExcludedPathsSubscriber implements EventSubscriberInterface {
/**
* The current site path, relative to the Drupal root.
*
* @var string
*/
protected $sitePath;
/**
* The Symfony file system service.
*
* @var \Symfony\Component\Filesystem\Filesystem
*/
protected $fileSystem;
/**
* The stream wrapper manager service.
*
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
*/
protected $streamWrapperManager;
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The path locator service.
*
* @var \Drupal\package_manager\PathLocator
*/
protected $pathLocator;
/**
* Constructs an ExcludedPathsSubscriber.
*
* @param string $site_path
* The current site path, relative to the Drupal root.
* @param \Symfony\Component\Filesystem\Filesystem $file_system
* The Symfony file system service.
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
* The stream wrapper manager service.
* @param \Drupal\Core\Database\Connection $database
* The database connection.
* @param \Drupal\package_manager\PathLocator $path_locator
* The path locator service.
*/
public function __construct(string $site_path, Filesystem $file_system, StreamWrapperManagerInterface $stream_wrapper_manager, Connection $database, PathLocator $path_locator) {
$this->sitePath = $site_path;
$this->fileSystem = $file_system;
$this->streamWrapperManager = $stream_wrapper_manager;
$this->database = $database;
$this->pathLocator = $path_locator;
}
/**
* Flags paths to be excluded, relative to the web root.
*
* This should only be used for paths that, if they exist at all, are
* *guaranteed* to exist within the web root.
*
* @param \Drupal\package_manager\Event\PreCreateEvent|\Drupal\package_manager\Event\PreApplyEvent $event
* The event object.
* @param string[] $paths
* The paths to exclude. These should be relative to the web root, and will
* be made relative to the project root.
*/
protected function excludeInWebRoot(StageEvent $event, array $paths): void {
$web_root = $this->pathLocator->getWebRoot();
if ($web_root) {
$web_root .= '/';
}
foreach ($paths as $path) {
// Make the path relative to the project root by prefixing the web root.
$event->excludePath($web_root . $path);
}
}
/**
* Flags paths to be excluded, relative to the project root.
*
* @param \Drupal\package_manager\Event\PreCreateEvent|\Drupal\package_manager\Event\PreApplyEvent $event
* The event object.
* @param string[] $paths
* The paths to exclude. Absolute paths will be made relative to the project
* root; relative paths will be assumed to already be relative to the
* project root, and excluded as given.
*/
protected function excludeInProjectRoot(StageEvent $event, array $paths): void {
$project_root = $this->pathLocator->getProjectRoot();
foreach ($paths as $path) {
// Make absolute paths relative to the project root.
$path = str_replace($project_root, NULL, $path);
$path = ltrim($path, '/');
$event->excludePath($path);
}
}
/**
* Excludes common paths from staging operations.
*
* @param \Drupal\package_manager\Event\PreApplyEvent|\Drupal\package_manager\Event\PreCreateEvent $event
* The event object.
*
* @see \Drupal\package_manager\Event\ExcludedPathsTrait::excludePath()
*/
public function ignoreCommonPaths(StageEvent $event): void {
// Compile two lists of paths to exclude: paths that are relative to the
// project root, and paths that are relative to the web root.
$web = $project = [];
// Always ignore automated test directories. If they exist, they will be in
// the web root.
$web[] = 'sites/simpletest';
// If the core-vendor-hardening plugin (used in the legacy-project template)
// is present, it may have written security hardening files in the vendor
// directory. They should always be ignored.
$vendor_dir = $this->pathLocator->getVendorDirectory();
$project[] = $vendor_dir . '/web.config';
$project[] = $vendor_dir . '/.htaccess';
// Ignore public and private files. These paths could be either absolute or
// relative, depending on site settings. If they are absolute, treat them
// as relative to the project root. Otherwise, treat them as relative to
// the web root.
$files = array_filter([
$this->getFilesPath('public'),
$this->getFilesPath('private'),
]);
foreach ($files as $path) {
if ($this->fileSystem->isAbsolutePath($path)) {
$project[] = $path;
}
else {
$web[] = $path;
}
}
// Ignore site-specific settings files, which are always in the web root.
$settings_files = [
'settings.php',
'settings.local.php',
'services.yml',
];
foreach ($settings_files as $settings_file) {
$web[] = $this->sitePath . '/' . $settings_file;
$web[] = 'sites/default/' . $settings_file;
}
// If the database is SQLite, it might be located in the active directory
// and we should ignore it. Always treat it as relative to the project root.
if ($this->database->driver() === 'sqlite') {
$options = $this->database->getConnectionOptions();
$project[] = $options['database'];
$project[] = $options['database'] . '-shm';
$project[] = $options['database'] . '-wal';
}
// Find all .git directories in the project and exclude them. We cannot do
// this with FileSystemInterface::scanDirectory() because it unconditionally
// excludes anything starting with a dot.
$finder = Finder::create()
->in($this->pathLocator->getProjectRoot())
->directories()
->name('.git')
->ignoreVCS(FALSE)
->ignoreDotFiles(FALSE)
->ignoreUnreadableDirs();
foreach ($finder as $git_directory) {
$project[] = $git_directory->getPathname();
}
$this->excludeInWebRoot($event, $web);
$this->excludeInProjectRoot($event, $project);
}
/**
* Reacts before staged changes are committed the active directory.
*
* @param \Drupal\package_manager\Event\PreApplyEvent $event
* The event object.
*/
public function preApply(PreApplyEvent $event): void {
// Don't copy anything from the staging area's sites/default.
// @todo Make this a lot smarter in https://www.drupal.org/i/3228955.
$this->excludeInWebRoot($event, ['sites/default']);
$this->ignoreCommonPaths($event);
}
/**
* Returns the storage path for a stream wrapper.
*
* This will only work for stream wrappers that extend
* \Drupal\Core\StreamWrapper\LocalStream, which includes the stream wrappers
* for public and private files.
*
* @param string $scheme
* The stream wrapper scheme.
*
* @return string|null
* The storage path for files using the given scheme, relative to the Drupal
* root, or NULL if the stream wrapper does not extend
* \Drupal\Core\StreamWrapper\LocalStream.
*/
private function getFilesPath(string $scheme): ?string {
$wrapper = $this->streamWrapperManager->getViaScheme($scheme);
if ($wrapper instanceof LocalStream) {
return $wrapper->getDirectoryPath();
}
return NULL;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
PreCreateEvent::class => 'ignoreCommonPaths',
PreApplyEvent::class => 'preApply',
];
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\EventSubscriber;
use Drupal\package_manager\Event\PostApplyEvent;
......@@ -8,32 +10,29 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Clears stale update data once staged changes have been applied.
*
* @internal
* This is an internal part of Package Manager and may be changed or removed
* at any time without warning. External code should not interact with this
* class.
*/
class UpdateDataSubscriber implements EventSubscriberInterface {
/**
* The update manager service.
*
* @var \Drupal\update\UpdateManagerInterface
*/
protected $updateManager;
final class UpdateDataSubscriber implements EventSubscriberInterface {
/**
* Constructs an UpdateRefreshSubscriber object.
* Constructs an UpdateDataSubscriber object.
*
* @param \Drupal\update\UpdateManagerInterface $update_manager
* @param \Drupal\update\UpdateManagerInterface $updateManager
* The update manager service.
*/
public function __construct(UpdateManagerInterface $update_manager) {
$this->updateManager = $update_manager;
public function __construct(private readonly UpdateManagerInterface $updateManager) {
}
/**
* Clears stale update data.
*
* This will always run after any staging area is applied to the active
* directory, since it's likely that core and/or multiple extensions have been
* added, removed, or updated.
* This will always run after any stage directory changes are applied to the
* active directory, since it's likely that core and/or multiple extensions
* have been added, removed, or updated.
*/
public function clearData(): void {
$this->updateManager->refreshUpdateData();
......@@ -43,7 +42,7 @@ class UpdateDataSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
public static function getSubscribedEvents(): array {
return [
PostApplyEvent::class => ['clearData', 1000],
];
......
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Exception;
/**
* Exception thrown if a stage encounters an error applying an update.
*
* If this exception is thrown it indicates that an update of the active
* codebase was attempted but failed. If this happens the site code is in an
* indeterminate state. Package Manager does not provide a method for recovering
* from this state. The site code should be restored from a backup.
*
* This exception is different from StageFailureMarkerException in that it is
* thrown if an error happens *during* the apply operation, rather than before
* or after it.
*
* Should not be thrown by external code.
*/
final class ApplyFailedException extends StageException {
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Exception;
/**
* Exception thrown if we cannot reliably use Composer.
*
* Should not be thrown by external code.
*
* @see \Drupal\package_manager\ComposerInspector::validate()
*/
final class ComposerNotReadyException extends \RuntimeException {
/**
* Constructs an ComposerNotReadyException object.
*
* @param string|null $workingDir
* The directory where Composer was run , or NULL if the errors are related
* to the Composer executable itself.
* @param array $messages
* An array of messages explaining why Composer cannot be run correctly.
* @param int $code
* (optional) The exception code. Defaults to 0.
* @param \Throwable|null $previous
* (optional) The previous exception, for exception chaining.
*/
public function __construct(public readonly ?string $workingDir, array $messages, int $code = 0, ?\Throwable $previous = NULL) {
parent::__construct(implode("\n", $messages), $code, $previous);
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Exception;
use Drupal\package_manager\Event\PreOperationStageEvent;
use Drupal\package_manager\Event\StageEvent;
/**
* Exception thrown if an error related to an event occurs.
*
* This exception is thrown when an error strictly associated with an event
* occurs. This is also what makes it different from StageException.
*
* Should not be thrown by external code.
*/
class StageEventException extends StageException {
/**
* Constructs a StageEventException object.
*
* @param \Drupal\package_manager\Event\StageEvent $event
* The stage event during which this exception is thrown.
* @param string|null $message
* (optional) The exception message. Defaults to a plain text representation
* of the validation results.
* @param mixed ...$arguments
* Additional arguments to pass to the parent constructor.
*/
public function __construct(public readonly StageEvent $event, ?string $message = NULL, ...$arguments) {
parent::__construct($event->stage, $message ?: $this->getResultsAsText(), ...$arguments);
}
/**
* Formats the validation results, if any, as plain text.
*
* @return string
* The results, formatted as plain text.
*/
protected function getResultsAsText(): string {
$text = '';
if ($this->event instanceof PreOperationStageEvent) {
foreach ($this->event->getResults() as $result) {
$messages = $result->messages;
$summary = $result->summary;
if ($summary) {
array_unshift($messages, $summary);
}
$text .= implode("\n", $messages) . "\n";
}
}
return $text;
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Exception;
use Drupal\package_manager\StageBase;
/**
* Base class for all exceptions related to staging operations.
* Base class for all exceptions related to stage operations.
*
* Should not be thrown by external code.
*/
class StageException extends \RuntimeException {
/**
* Constructs a StageException object.
*
* @param \Drupal\package_manager\StageBase $stage
* The stage.
* @param mixed ...$arguments
* Additional arguments to pass to the parent constructor.
*/
public function __construct(public readonly StageBase $stage, ...$arguments) {
parent::__construct(...$arguments);
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Exception;
/**
* Exception thrown if a stage can't be created due to an earlier failed commit.
*
* If this exception is thrown it indicates that an earlier commit operation had
* failed. If this happens the site code is in an indeterminate state. Package
* Manager does not provide a method for recovering from this state. The site
* code should be restored from a backup.
*
* We are extending RuntimeException rather than StageException which makes it
* clearer that it's unrelated to the stage life cycle.
*
* This exception is different from ApplyFailedException as it focuses on
* the failure marker being detected outside the stage lifecycle.
*/
final class StageFailureMarkerException extends \RuntimeException {
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager\Exception;
/**
......@@ -7,5 +9,5 @@ namespace Drupal\package_manager\Exception;
*
* Should not be thrown by external code.
*/
class StageOwnershipException extends StageException {
final class StageOwnershipException extends StageException {
}
<?php
namespace Drupal\package_manager\Exception;
/**
* Exception thrown if a stage has validation errors.
*
* Should not be thrown by external code.
*/
class StageValidationException extends StageException {
/**
* Any relevant validation results.
*
* @var \Drupal\package_manager\ValidationResult[]
*/
protected $results = [];
/**
* Constructs a StageException object.
*
* @param \Drupal\package_manager\ValidationResult[] $results
* Any relevant validation results.
* @param mixed ...$arguments
* Arguments to pass to the parent constructor.
*/
public function __construct(array $results = [], ...$arguments) {
$this->results = $results;
parent::__construct(...$arguments);
}
/**
* Gets the validation results.
*
* @return \Drupal\package_manager\ValidationResult[]
* The validation results.
*/
public function getResults(): array {
return $this->results;
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager;
use Drupal\Core\Config\ConfigFactoryInterface;
use PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface;
use PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinder as StagerExecutableFinder;
use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder;
use PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface;
/**
* An executable finder which looks for executable paths in configuration.
*
* @internal
* This is an internal part of Package Manager and may be changed or removed
* at any time without warning. External code should not interact with this
* class.
*/
class ExecutableFinder implements ExecutableFinderInterface {
/**
* The decorated executable finder.
*
* @var \PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinder
*/
private $decorated;
/**
* The config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
private $configFactory;
final class ExecutableFinder implements ExecutableFinderInterface {
/**
* Constructs an ExecutableFinder object.
*
* @param \Symfony\Component\Process\ExecutableFinder $symfony_executable_finder
* The Symfony executable finder.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* @param \PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface $decorated
* The decorated executable finder.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
*/
public function __construct(SymfonyExecutableFinder $symfony_executable_finder, ConfigFactoryInterface $config_factory) {
$this->decorated = new StagerExecutableFinder($symfony_executable_finder);
$this->configFactory = $config_factory;
}
public function __construct(
private readonly ExecutableFinderInterface $decorated,
private readonly ConfigFactoryInterface $configFactory
) {}
/**
* {@inheritdoc}
......
<?php
declare(strict_types = 1);
namespace Drupal\package_manager;
use Drupal\package_manager\Event\CollectPathsToExcludeEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\package_manager\Exception\StageFailureMarkerException;
/**
* Handles failure marker file operation.
*
* The failure marker is a file placed in the active directory while staged
* code is copied back into it, and then removed afterwards. This allows us to
* know if a commit operation failed midway through, which could leave the site
* code base in an indeterminate state -- which, in the worst case scenario,
* might render Drupal being unable to boot.
*
* @internal
* This is an internal part of Package Manager and may be changed or removed
* at any time without warning. External code should not interact with this
* class.
*/
final class FailureMarker implements EventSubscriberInterface {
/**
* Constructs a FailureMarker object.
*
* @param \Drupal\package_manager\PathLocator $pathLocator
* The path locator service.
*/
public function __construct(private readonly PathLocator $pathLocator) {
}
/**
* Gets the marker file path.
*
* @return string
* The absolute path of the marker file.
*/
public function getPath(): string {
return $this->pathLocator->getProjectRoot() . '/PACKAGE_MANAGER_FAILURE.yml';
}
/**
* Deletes the marker file.
*/
public function clear(): void {
unlink($this->getPath());
}
/**
* Writes data to marker file.
*
* @param \Drupal\package_manager\StageBase $stage
* The stage.
* @param \Drupal\Core\StringTranslation\TranslatableMarkup $message
* Failure message to be added.
* @param \Throwable $throwable
* (optional) The throwable that caused the failure.
*/
public function write(StageBase $stage, TranslatableMarkup $message, \Throwable $throwable = NULL): void {
$data = [
'stage_class' => get_class($stage),
'stage_type' => $stage->getType(),
'stage_file' => (new \ReflectionObject($stage))->getFileName(),
'message' => (string) $message,
'throwable_class' => $throwable ? get_class($throwable) : FALSE,
'throwable_message' => $throwable?->getMessage() ?? 'Not available',
'throwable_backtrace' => $throwable?->getTraceAsString() ?? 'Not available.',
];
file_put_contents($this->getPath(), Yaml::dump($data));
}
/**
* Gets the data from the file if it exists.
*
* @return array|null
* The data from the file if it exists.
*
* @throws \Drupal\package_manager\Exception\StageFailureMarkerException
* Thrown if failure marker exists but cannot be decoded.
*/
private function getData(): ?array {
$path = $this->getPath();
if (file_exists($path)) {
$data = file_get_contents($path);
try {
return Yaml::parse($data);
}
catch (ParseException $exception) {
throw new StageFailureMarkerException('Failure marker file exists but cannot be decoded.', $exception->getCode(), $exception);
}
}
return NULL;
}
/**
* Gets the message from the file if it exists.
*
* @param bool $include_backtrace
* Whether to include the backtrace in the message. Defaults to TRUE. May be
* set to FALSE in a context where it does not make sense to include, such
* as emails.
*
* @return string|null
* The message from the file if it exists, otherwise NULL.
*
* @throws \Drupal\package_manager\Exception\StageFailureMarkerException
* Thrown if failure marker exists but cannot be decoded.
*/
public function getMessage(bool $include_backtrace = TRUE): ?string {
$data = $this->getData();
if ($data === NULL) {
return NULL;
}
$message = $data['message'];
if ($data['throwable_class']) {
$message .= sprintf(
' Caused by %s, with this message: %s',
$data['throwable_class'],
$data['throwable_message'],
);
if ($include_backtrace) {
$message .= "\nBacktrace:\n" . $data['throwable_backtrace'];
}
}
return $message;
}
/**
* Asserts the failure file doesn't exist.
*
* @throws \Drupal\package_manager\Exception\StageFailureMarkerException
* Thrown if the marker file exists.
*/
public function assertNotExists(): void {
if ($message = $this->getMessage()) {
throw new StageFailureMarkerException($message);
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
return [
CollectPathsToExcludeEvent::class => 'excludeMarkerFile',
];
}
/**
* Excludes the failure marker file from stage operations.
*
* @param \Drupal\package_manager\Event\CollectPathsToExcludeEvent $event
* The event being handled.
*/
public function excludeMarkerFile(CollectPathsToExcludeEvent $event): void {
$event->addPathsRelativeToProjectRoot([
$this->getPath(),
]);
}
}
<?php
declare(strict_types = 1);
namespace Drupal\package_manager;
use Drupal\Core\Config\ConfigFactoryInterface;
use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerFactoryInterface;
use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerFactory as StagerFileSyncerFactory;
use Symfony\Component\Process\ExecutableFinder;
use PhpTuf\ComposerStager\API\FileSyncer\Factory\FileSyncerFactoryInterface;
use PhpTuf\ComposerStager\API\FileSyncer\Service\FileSyncerInterface;
use PhpTuf\ComposerStager\API\FileSyncer\Service\PhpFileSyncerInterface;
use PhpTuf\ComposerStager\API\FileSyncer\Service\RsyncFileSyncerInterface;
/**
* A file syncer factory which creates a file syncer according to configuration.
*
* @internal
* This is an internal part of Package Manager and may be changed or removed
* at any time without warning. External code should not interact with this
* class.
*/
class FileSyncerFactory implements FileSyncerFactoryInterface {
/**
* The decorated file syncer factory.
*
* @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerFactoryInterface
*/
protected $decorated;
/**
* The PHP file syncer service.
*
* @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface
*/
protected $phpFileSyncer;
final class FileSyncerFactory implements FileSyncerFactoryInterface {
/**
* The rsync file syncer service.
* Constructs a FileSyncerFactory object.
*
* @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface
*/
protected $rsyncFileSyncer;
/**
* The config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* Constructs a FileCopierFactory object.
*
* @param \Symfony\Component\Process\ExecutableFinder $executable_finder
* The Symfony executable finder.
* @param \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface $php_file_syncer
* @param \PhpTuf\ComposerStager\API\FileSyncer\Factory\FileSyncerFactoryInterface $decorated
* The decorated file syncer factory.
* @param \PhpTuf\ComposerStager\API\FileSyncer\Service\PhpFileSyncerInterface $phpFileSyncer
* The PHP file syncer service.
* @param \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface $rsync_file_syncer
* @param \PhpTuf\ComposerStager\API\FileSyncer\Service\RsyncFileSyncerInterface $rsyncFileSyncer
* The rsync file syncer service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
*/
public function __construct(ExecutableFinder $executable_finder, FileSyncerInterface $php_file_syncer, FileSyncerInterface $rsync_file_syncer, ConfigFactoryInterface $config_factory) {
$this->decorated = new StagerFileSyncerFactory($executable_finder, $php_file_syncer, $rsync_file_syncer);
$this->phpFileSyncer = $php_file_syncer;
$this->rsyncFileSyncer = $rsync_file_syncer;
$this->configFactory = $config_factory;
}
public function __construct(
private readonly FileSyncerFactoryInterface $decorated,
private readonly PhpFileSyncerInterface $phpFileSyncer,
private readonly RsyncFileSyncerInterface $rsyncFileSyncer,
private readonly ConfigFactoryInterface $configFactory,
) {}
/**
* {@inheritdoc}
......