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
Commits on Source (11)
Showing
with 283 additions and 160 deletions
......@@ -133,6 +133,10 @@ services:
class: Drupal\automatic_updates\Validator\XdebugValidator
tags:
- { name: event_subscriber }
automatic_updates.validator.installed_version:
class: Drupal\automatic_updates\Validator\InstalledVersionValidator
tags:
- { name: event_subscriber }
automatic_updates.validator.target_release:
class: Drupal\automatic_updates\Validator\UpdateReleaseValidator
tags:
......
......@@ -64,7 +64,12 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
protected function setUp(): void {
parent::setUp();
$this->setReleaseMetadata(__DIR__ . '/../../fixtures/release-history/semver_test.1.1.xml');
$this->drupalLogin($this->rootUser);
$user = $this->createUser([
'administer site configuration',
'administer software updates',
'access site in maintenance mode',
]);
$this->drupalLogin($user);
$this->drupalPlaceBlock('local_tasks_block', ['primary' => TRUE]);
}
......
......@@ -3,10 +3,9 @@
namespace Drupal\Tests\automatic_updates_extensions\Kernel;
use Drupal\automatic_updates_extensions\ExtensionUpdater;
use Drupal\package_manager\Event\StageEvent;
use Drupal\package_manager\Exception\StageException;
use Drupal\package_manager\Exception\StageValidationException;
use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase;
use Drupal\Tests\package_manager\Kernel\TestStageTrait;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
......@@ -122,33 +121,6 @@ abstract class AutomaticUpdatesExtensionsKernelTestBase extends AutomaticUpdates
*/
class TestExtensionUpdater extends ExtensionUpdater {
/**
* The directory where staging areas will be created.
*
* @var string
*/
public static $stagingRoot;
/**
* {@inheritdoc}
*/
public function getStagingRoot(): string {
return static::$stagingRoot ?: parent::getStagingRoot();
}
/**
* {@inheritdoc}
*/
protected function dispatch(StageEvent $event, callable $on_error = NULL): void {
try {
parent::dispatch($event, $on_error);
}
catch (StageException $e) {
// Attach the event object to the exception so that test code can verify
// that the exception was thrown when a specific event was dispatched.
$e->event = $event;
throw $e;
}
}
use TestStageTrait;
}
......@@ -8,7 +8,7 @@
/**
* Implements hook_requirements().
*/
function package_manager_requirements() {
function package_manager_requirements(string $phase) {
$requirements = [];
if (!class_exists('PhpTuf\ComposerStager\Domain\Beginner')) {
......@@ -18,7 +18,7 @@ function package_manager_requirements() {
'severity' => REQUIREMENT_ERROR,
];
}
if (extension_loaded('xdebug')) {
if ($phase === 'runtime' && extension_loaded('xdebug')) {
$requirements['package_manager_xdebug'] = [
'title' => 'Xdebug enabled',
'description' => t('Xdebug is enabled, which may have a negative performance impact on Package Manager and any modules that use it.'),
......
......@@ -18,7 +18,12 @@ function package_manager_help($route_name, RouteMatchInterface $route_match) {
$output .= '<p>' . t('Package Manager is a framework for updating Drupal core and installing contributed modules and themes via Composer. It has no user interface, but it provides an API for creating a temporary copy of the current site, making changes to the copy, and then syncing those changes back into the live site.') . '</p>';
$output .= '<p>' . t('Package Manager dispatches events before and after various operations, and external code can integrate with it by subscribing to those events. For more information, see <code>package_manager.api.php</code>.') . '</p>';
$output .= '<h3 id="package-manager-requirements">' . t('Requirements') . '</h3>';
$output .= '<p>' . t('Package Manager requires Composer @version or later available as an executable, and PHP must have permission to run it. The path to the executable may be set in the <code>package_manager.settings:executables.composer</code> config setting, or it will be automatically detected.', ['@version' => ComposerExecutableValidator::MINIMUM_COMPOSER_VERSION]) . '</p>';
$output .= '<p>' . t('Package Manager requires Composer @version or later available as an executable, and PHP must have permission to run it. The path to the executable may be stored in config, or it will be automatically detected. To set the path to Composer, you can add the following line to settings.php:', ['@version' => ComposerExecutableValidator::MINIMUM_COMPOSER_VERSION]) . '</p>';
$output .= "<p><code>\$config['package_manager.settings']['executables']['composer'] = '/full/path/to/composer';</code></p>";
// BEGIN: DELETE FROM CORE MERGE REQUEST
$output .= '<p>' . t('Or, if using Drush, you can run the following command:') . '</p>';
$output .= '<p><code>drush config:set package_manager.settings executables.composer /full/path/to/composer</code></p>';
// END: DELETE FROM CORE MERGE REQUEST
$output .= '<h3>' . t('Limitations') . '</h3>';
$output .= '<p>' . t("Because Package Manager modifies the current site's code base, it is intentionally limited in certain ways to prevent unexpected changes from being made to the live site:") . '</p>';
$output .= '<ul>';
......
services:
# Underlying Symfony utilities.
package_manager.symfony_file_system:
class: Symfony\Component\Filesystem\Filesystem
package_manager.symfony_executable_finder:
class: Symfony\Component\Process\ExecutableFinder
# Underlying Symfony utilities for Composer Stager.
Symfony\Component\Filesystem\Filesystem:
public: false
Symfony\Component\Process\ExecutableFinder:
public: false
# Basic infrastructure services.
package_manager.process_factory:
class: Drupal\package_manager\ProcessFactory
# Basic infrastructure services for Composer Stager.
Drupal\package_manager\ProcessFactory:
arguments:
- '@file_system'
- '@config.factory'
package_manager.file_system:
class: PhpTuf\ComposerStager\Infrastructure\Filesystem\Filesystem
arguments:
- '@package_manager.symfony_file_system'
package_manager.executable_finder:
class: Drupal\package_manager\ExecutableFinder
arguments:
- '@package_manager.symfony_executable_finder'
- '@config.factory'
public: false
PhpTuf\ComposerStager\Infrastructure\Filesystem\Filesystem:
autowire: true
public: false
Drupal\package_manager\ExecutableFinder:
arguments:
$config_factory: '@config.factory'
autowire: true
public: false
PhpTuf\ComposerStager\Infrastructure\Process\ProcessFactoryInterface:
alias: 'Drupal\package_manager\ProcessFactory'
PhpTuf\ComposerStager\Domain\Filesystem\FilesystemInterface:
alias: 'PhpTuf\ComposerStager\Infrastructure\Filesystem\Filesystem'
PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface:
alias: 'Drupal\package_manager\ExecutableFinder'
# Executable runners.
package_manager.rsync_runner:
class: PhpTuf\ComposerStager\Infrastructure\Process\Runner\RsyncRunner
arguments:
- '@package_manager.executable_finder'
- '@package_manager.process_factory'
package_manager.composer_runner:
class: PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunner
arguments:
- '@package_manager.executable_finder'
- '@package_manager.process_factory'
# Executable runners for Composer Stager.
PhpTuf\ComposerStager\Infrastructure\Process\Runner\RsyncRunner:
autowire: true
public: false
PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunner:
autowire: true
public: false
PhpTuf\ComposerStager\Domain\Process\Runner\RsyncRunnerInterface:
alias: 'PhpTuf\ComposerStager\Infrastructure\Process\Runner\RsyncRunner'
PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface:
alias: 'PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunner'
# File syncers.
package_manager.file_syncer.rsync:
class: PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer
arguments:
- '@package_manager.file_system'
- '@package_manager.rsync_runner'
package_manager.file_syncer.php:
class: PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer
arguments:
- '@package_manager.file_system'
package_manager.file_syncer.factory:
class: Drupal\package_manager\FileSyncerFactory
arguments:
- '@package_manager.symfony_executable_finder'
- '@package_manager.file_syncer.php'
- '@package_manager.file_syncer.rsync'
- '@config.factory'
package_manager.file_syncer:
class: PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface
factory: ['@package_manager.file_syncer.factory', 'create']
# File syncers for Composer Stager.
PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer:
autowire: true
PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer:
autowire: true
Drupal\package_manager\FileSyncerFactory:
arguments:
$config_factory: '@config.factory'
autowire: true
public: false
PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface:
factory: ['@Drupal\package_manager\FileSyncerFactory', 'create']
# Domain services.
# Services provided to Drupal by Package Manager.
package_manager.beginner:
class: PhpTuf\ComposerStager\Domain\Beginner
arguments:
- '@package_manager.file_syncer'
- '@package_manager.file_system'
autowire: true
package_manager.stager:
class: PhpTuf\ComposerStager\Domain\Stager
arguments:
- '@package_manager.composer_runner'
- '@package_manager.file_system'
autowire: true
package_manager.committer:
class: PhpTuf\ComposerStager\Domain\Committer
arguments:
- '@package_manager.file_syncer'
- '@package_manager.file_system'
autowire: true
package_manager.path_locator:
class: Drupal\package_manager\PathLocator
arguments:
......@@ -79,7 +70,7 @@ services:
package_manager.validator.composer_executable:
class: Drupal\package_manager\Validator\ComposerExecutableValidator
arguments:
- '@package_manager.composer_runner'
- '@PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface'
- '@module_handler'
- '@string_translation'
tags:
......@@ -143,11 +134,11 @@ services:
package_manager.site_files_excluder:
class: Drupal\package_manager\PathExcluder\SiteFilesExcluder
arguments:
- '@package_manager.path_locator'
- '@stream_wrapper_manager'
- '@package_manager.symfony_file_system'
$path_locator: '@package_manager.path_locator'
$stream_wrapper_manager: '@stream_wrapper_manager'
tags:
- { name: event_subscriber }
autowire: true
package_manager.sqlite_excluder:
class: Drupal\package_manager\PathExcluder\SqliteDatabaseExcluder
arguments:
......
......@@ -6,6 +6,8 @@ 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 PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer;
use Symfony\Component\Process\ExecutableFinder;
/**
......@@ -23,14 +25,14 @@ class FileSyncerFactory implements FileSyncerFactoryInterface {
/**
* The PHP file syncer service.
*
* @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface
* @var \PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer
*/
protected $phpFileSyncer;
/**
* The rsync file syncer service.
*
* @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface
* @var \PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer
*/
protected $rsyncFileSyncer;
......@@ -46,14 +48,14 @@ class FileSyncerFactory implements FileSyncerFactoryInterface {
*
* @param \Symfony\Component\Process\ExecutableFinder $executable_finder
* The Symfony executable finder.
* @param \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface $php_file_syncer
* @param \PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer $php_file_syncer
* The PHP file syncer service.
* @param \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface $rsync_file_syncer
* @param \PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer $rsync_file_syncer
* The rsync file syncer service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service.
*/
public function __construct(ExecutableFinder $executable_finder, FileSyncerInterface $php_file_syncer, FileSyncerInterface $rsync_file_syncer, ConfigFactoryInterface $config_factory) {
public function __construct(ExecutableFinder $executable_finder, PhpFileSyncer $php_file_syncer, RsyncFileSyncer $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;
......
......@@ -3,7 +3,6 @@
namespace Drupal\package_manager;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Component\FileSystem\FileSystem;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\File\Exception\FileException;
......@@ -67,6 +66,15 @@ class Stage {
*/
protected const TEMPSTORE_METADATA_KEY = 'metadata';
/**
* The tempstore key under which to store the path of the staging root.
*
* @var string
*
* @see ::getStagingRoot()
*/
private const TEMPSTORE_STAGING_ROOT_KEY = 'staging_root';
/**
* The tempstore key under which to store the time that ::apply() was called.
*
......@@ -238,6 +246,11 @@ class Stage {
* call ::claim(). However, if it was created during another request, the
* stage must be claimed before operations can be performed on it.
*
* @param int|null $timeout
* (optional) How long to allow the file copying operation to run before
* timing out, in seconds, or NULL to never time out. Defaults to 300
* seconds.
*
* @return string
* Unique ID for the stage, which can be used to claim the stage before
* performing other operations on it. Calling code should store this ID for
......@@ -248,7 +261,7 @@ class Stage {
*
* @see ::claim()
*/
public function create(): string {
public function create(?int $timeout = 300): string {
if (!$this->isAvailable()) {
throw new StageException('Cannot create a new stage because one already exists.');
}
......@@ -270,7 +283,7 @@ class Stage {
// available.
$this->dispatch($event, [$this, 'markAsAvailable']);
$this->beginner->begin($active_dir, $stage_dir, $event->getExcludedPaths());
$this->beginner->begin($active_dir, $stage_dir, $event->getExcludedPaths(), NULL, $timeout);
$this->dispatch(new PostCreateEvent($this));
return $id;
}
......@@ -313,8 +326,13 @@ class Stage {
/**
* Applies staged changes to the active directory.
*
* @param int|null $timeout
* (optional) How long to allow the file copying operation to run before
* timing out, in seconds, or NULL to never time out. Defaults to 600
* seconds.
*/
public function apply(): void {
public function apply(?int $timeout = 600): void {
$this->checkOwnership();
$active_dir = $this->pathLocator->getProjectRoot();
......@@ -331,7 +349,7 @@ class Stage {
$this->tempStore->set(self::TEMPSTORE_APPLY_TIME_KEY, $this->time->getRequestTime());
$this->dispatch($event, $release_apply);
$this->committer->commit($stage_dir, $active_dir, $event->getExcludedPaths());
$this->committer->commit($stage_dir, $active_dir, $event->getExcludedPaths(), NULL, $timeout);
// Rebuild the container and clear all caches, to ensure that new services
// are picked up.
......@@ -390,6 +408,7 @@ class Stage {
protected function markAsAvailable(): void {
$this->tempStore->delete(static::TEMPSTORE_METADATA_KEY);
$this->tempStore->delete(static::TEMPSTORE_LOCK_KEY);
$this->tempStore->delete(self::TEMPSTORE_STAGING_ROOT_KEY);
$this->lock = NULL;
}
......@@ -541,9 +560,17 @@ class Stage {
* The absolute path of the directory containing the staging areas managed
* by this class.
*/
protected function getStagingRoot(): string {
$site_id = $this->configFactory->get('system.site')->get('uuid');
return FileSystem::getOsTemporaryDirectory() . DIRECTORY_SEPARATOR . '.package_manager' . $site_id;
private function getStagingRoot(): string {
// Since the staging root can depend on site settings, store it so that
// things won't break if the settings change during this stage's life
// cycle.
$dir = $this->tempStore->get(self::TEMPSTORE_STAGING_ROOT_KEY);
if (empty($dir)) {
$site_id = $this->configFactory->get('system.site')->get('uuid');
$dir = $this->fileSystem->getTempDirectory() . DIRECTORY_SEPARATOR . '.package_manager' . $site_id;
$this->tempStore->set(self::TEMPSTORE_STAGING_ROOT_KEY, $dir);
}
return $dir;
}
/**
......
{
"packages": [
{
"name": "drupal/core",
"version": "9.8.0"
}
]
}
......@@ -14,7 +14,7 @@ class Beginner extends InvocationRecorderBase implements BeginnerInterface {
* {@inheritdoc}
*/
public function begin(string $activeDir, string $stagingDir, ?array $exclusions = [], ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void {
$this->saveInvocationArguments($activeDir, $stagingDir, $exclusions);
$this->saveInvocationArguments($activeDir, $stagingDir, $exclusions, $timeout);
}
}
......@@ -31,7 +31,7 @@ class Committer extends InvocationRecorderBase implements CommitterInterface {
* {@inheritdoc}
*/
public function commit(string $stagingDir, string $activeDir, ?array $exclusions = [], ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void {
$this->saveInvocationArguments($activeDir, $stagingDir, $exclusions);
$this->saveInvocationArguments($stagingDir, $activeDir, $exclusions, $timeout);
}
/**
......
......@@ -18,9 +18,11 @@ class PackageManagerBypassServiceProvider extends ServiceProviderBase {
parent::alter($container);
$container->getDefinition('package_manager.beginner')
->setClass(Beginner::class);
->setClass(Beginner::class)
->setArguments([]);
$container->getDefinition('package_manager.stager')
->setClass(Stager::class);
->setClass(Stager::class)
->setArguments([]);
$container->register('package_manager_bypass.committer')
->setClass(Committer::class)
......
......@@ -3,6 +3,6 @@ services:
class: Drupal\package_manager_test_fixture\EventSubscriber\FixtureStager
arguments:
- '@state'
- '@package_manager.symfony_file_system'
- '@Symfony\Component\Filesystem\Filesystem'
tags:
- { name: event_subscriber }
......@@ -57,12 +57,27 @@ class FixtureStager implements EventSubscriberInterface {
* @see \Drupal\Tests\automatic_updates\Functional\AutomaticUpdatesFunctionalTestBase::tearDown()
*/
public function copyFilesFromFixture(PostRequireEvent $event): void {
$fixturePath = $this->state->get(static::class);
[$fixturePath, $changeLock] = $this->state->get(static::class);
if ($fixturePath && is_dir($fixturePath)) {
$this->fileSystem->mirror($fixturePath, $event->getStage()->getStageDirectory(), NULL, [
$destination = $event->getStage()->getStageDirectory();
$this->fileSystem->mirror($fixturePath, $destination, NULL, [
'override' => TRUE,
'delete' => TRUE,
]);
// Modify the lock file in the staging area, to simulate that a package
// was added, updated, or removed. Otherwise, tests must remember to
// disable the lock file validator.
// @see \Drupal\package_manager\Validator\LockFileValidator
$lock = $destination . '/composer.lock';
if ($changeLock && file_exists($lock)) {
$data = file_get_contents($lock);
$data = json_decode($data);
$data->_time = microtime();
file_put_contents($lock, json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
}
}
......@@ -80,9 +95,12 @@ class FixtureStager implements EventSubscriberInterface {
*
* @param string $path
* The path of the fixture to copy into the staging area.
* @param bool $change_lock
* (optional) Whether to change the lock file, in order to simulate the
* addition, updating, or removal of a package. Defaults to TRUE.
*/
public static function setFixturePath(string $path): void {
\Drupal::state()->set(static::class, $path);
public static function setFixturePath(string $path, bool $change_lock = TRUE): void {
\Drupal::state()->set(static::class, [$path, $change_lock]);
}
}
......@@ -2,12 +2,13 @@
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Url;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\Validator\ComposerExecutableValidator;
use Drupal\package_manager\ValidationResult;
use PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface;
use PhpTuf\ComposerStager\Exception\IOException;
use PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface;
use Prophecy\Argument;
/**
......@@ -17,19 +18,42 @@ use Prophecy\Argument;
*/
class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
/**
* The mocked Composer runner.
*
* @var \Prophecy\Prophecy\ObjectProphecy|\PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface
*/
private $composerRunner;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
$this->composerRunner = $this->prophesize(ComposerRunnerInterface::class);
parent::setUp();
}
/**
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
parent::register($container);
$container->getDefinition('package_manager.validator.composer_executable')
->setArgument('$composer', $this->composerRunner->reveal());
}
/**
* Tests that an error is raised if the Composer executable isn't found.
*/
public function testErrorIfComposerNotFound(): void {
$exception = new IOException("This is your regularly scheduled error.");
// The executable finder throws an exception if it can't find the requested
// executable.
$exec_finder = $this->prophesize(ExecutableFinderInterface::class);
$exec_finder->find('composer')
// If the Composer executable isn't found, the executable finder will throw
// an exception, which will not be caught by the Composer runner.
$this->composerRunner->run(Argument::cetera())
->willThrow($exception)
->shouldBeCalled();
$this->container->set('package_manager.executable_finder', $exec_finder->reveal());
// The validator should translate that exception into an error.
$error = ValidationResult::createError([
......@@ -38,7 +62,6 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
$this->assertResults([$error], PreCreateEvent::class);
$this->enableModules(['help']);
$this->container->set('package_manager.executable_finder', $exec_finder->reveal());
$this->assertResultsWithHelp([$error], PreCreateEvent::class);
}
......@@ -122,10 +145,7 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
// Mock the output of `composer --version`, will be passed to the validator,
// which is itself a callback function that gets called repeatedly as
// Composer produces output.
/** @var \PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface|\Prophecy\Prophecy\ObjectProphecy $runner */
$runner = $this->prophesize('\PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface');
$runner->run(['--version'], Argument::type(ComposerExecutableValidator::class))
$this->composerRunner->run(['--version'], Argument::type(ComposerExecutableValidator::class))
// Whatever is passed to ::run() will be passed to this mock callback in
// $arguments, and we know exactly what that will contain: an array of
// command arguments for Composer, and the validator object.
......@@ -137,14 +157,12 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
// recognized, supported version number out of this output.
$validator($validator::OUT, "Composer version $reported_version");
});
$this->container->set('package_manager.composer_runner', $runner->reveal());
// If the validator can't find a recognized, supported version of Composer,
// it should produce errors.
$this->assertResults($expected_results, PreCreateEvent::class);
$this->enableModules(['help']);
$this->container->set('package_manager.composer_runner', $runner->reveal());
$this->assertResultsWithHelp($expected_results, PreCreateEvent::class);
}
......
......@@ -2,6 +2,9 @@
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\package_manager\ExecutableFinder;
use PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface;
use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder;
/**
......@@ -12,10 +15,11 @@ use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder;
class ExecutableFinderTest extends PackageManagerKernelTestBase {
/**
* Tests that the executable finder looks for paths in configuration.
* {@inheritdoc}
*/
public function testCheckConfigurationForExecutablePath(): void {
$symfony_executable_finder = new class () extends SymfonyExecutableFinder {
public function register(ContainerBuilder $container) {
// Mock a Symfony executable finder that always returns /dev/null.
$symfony_executable_finder = new class extends SymfonyExecutableFinder {
/**
* {@inheritdoc}
......@@ -25,13 +29,19 @@ class ExecutableFinderTest extends PackageManagerKernelTestBase {
}
};
$this->container->set('package_manager.symfony_executable_finder', $symfony_executable_finder);
$container->getDefinition(ExecutableFinder::class)
->setArgument('$symfony_executable_finder', $symfony_executable_finder);
}
/**
* Tests that the executable finder looks for paths in configuration.
*/
public function testCheckConfigurationForExecutablePath(): void {
$this->config('package_manager.settings')
->set('executables.composer', '/path/to/composer')
->save();
$executable_finder = $this->container->get('package_manager.executable_finder');
$executable_finder = $this->container->get(ExecutableFinderInterface::class);
$this->assertSame('/path/to/composer', $executable_finder->find('composer'));
$this->assertSame('/dev/null', $executable_finder->find('rsync'));
}
......
......@@ -3,6 +3,9 @@
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\KernelTests\KernelTestBase;
use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer;
/**
* @covers \Drupal\package_manager\FileSyncerFactory
......@@ -40,19 +43,17 @@ class FileSyncerFactoryTest extends KernelTestBase {
* @dataProvider providerFactory
*/
public function testFactory(?string $configured_syncer): void {
$factory = $this->container->get('package_manager.file_syncer.factory');
switch ($configured_syncer) {
case 'rsync':
$expected_syncer = $this->container->get('package_manager.file_syncer.rsync');
$expected_syncer = RsyncFileSyncer::class;
break;
case 'php':
$expected_syncer = $this->container->get('package_manager.file_syncer.php');
$expected_syncer = PhpFileSyncer::class;
break;
default:
$expected_syncer = $factory->create();
$expected_syncer = FileSyncerInterface::class;
break;
}
......@@ -60,7 +61,7 @@ class FileSyncerFactoryTest extends KernelTestBase {
->set('file_syncer', $configured_syncer)
->save();
$this->assertSame($expected_syncer, $factory->create());
$this->assertInstanceOf($expected_syncer, $this->container->get(FileSyncerInterface::class));
}
}
......@@ -2,12 +2,12 @@
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\package_manager\Event\PostRequireEvent;
use Drupal\package_manager\Event\PreApplyEvent;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\Event\PreRequireEvent;
use Drupal\package_manager\Validator\LockFileValidator;
use Drupal\package_manager\ValidationResult;
use Drupal\package_manager_test_fixture\EventSubscriber\FixtureStager;
/**
* @coversDefaultClass \Drupal\package_manager\Validator\LockFileValidator
......@@ -56,7 +56,7 @@ class LockFileValidatorTest extends PackageManagerKernelTestBase {
// Change the lock file to ensure the stored hash of the previous version
// has been deleted.
file_put_contents($this->activeDir . '/composer.lock', 'changed');
file_put_contents($this->activeDir . '/composer.lock', '{"changed": true}');
$this->assertResults([]);
}
......@@ -124,11 +124,11 @@ class LockFileValidatorTest extends PackageManagerKernelTestBase {
* Tests validation when the staged and active lock files are identical.
*/
public function testApplyWithNoChange(): void {
$this->addListener(PostRequireEvent::class, function (PostRequireEvent $event) {
$stage_dir = $event->getStage()->getStageDirectory();
mkdir($stage_dir);
copy("$this->activeDir/composer.lock", "$stage_dir/composer.lock");
});
// Ensure the lock file is not changed when the active directory is copied
// into the virtual staging area.
// @see \Drupal\package_manager_test_fixture\EventSubscriber\FixtureStager
FixtureStager::setFixturePath($this->activeDir, FALSE);
$result = ValidationResult::createError([
'There are no pending Composer operations.',
]);
......
......@@ -10,6 +10,7 @@ use Drupal\package_manager\Exception\StageException;
use Drupal\package_manager\Exception\StageValidationException;
use Drupal\package_manager\PathLocator;
use Drupal\package_manager\Stage;
use Drupal\package_manager_test_fixture\EventSubscriber\FixtureStager;
use Drupal\Tests\package_manager\Traits\ValidationTestTrait;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
......@@ -29,8 +30,20 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
protected static $modules = [
'package_manager',
'package_manager_bypass',
'package_manager_test_fixture',
];
/**
* The test staging root.
*
* This value must be set before creating a test stage instance.
*
* @var string
*
* @see \Drupal\Tests\package_manager\Kernel\TestStageTrait::__construct()
*/
public static $testStagingRoot;
/**
* The service IDs of any validators to disable.
*
......@@ -175,9 +188,14 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
// Create a staging root directory alongside the active directory.
$stage_dir = vfsStream::newDirectory('stage');
$this->vfsRoot->addChild($stage_dir);
TestStage::$stagingRoot = $stage_dir->url();
static::$testStagingRoot = $stage_dir->url();
$path_locator = $this->mockPathLocator($active_dir->url());
$active_dir = $active_dir->url();
$path_locator = $this->mockPathLocator($active_dir);
// Ensure that the active directory is copied into the virtual staging area,
// even if Package Manager's operations are bypassed.
FixtureStager::setFixturePath($active_dir);
// Since the path locator now points to a virtual file system, we need to
// replace the disk space validator with a test-only version that bypasses
......@@ -230,9 +248,9 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
}
/**
* Defines a stage specifically for testing purposes.
* Common functions for test stages.
*/
class TestStage extends Stage {
trait TestStageTrait {
/**
* The directory where staging areas will be created.
......@@ -244,8 +262,10 @@ class TestStage extends Stage {
/**
* {@inheritdoc}
*/
public function getStagingRoot(): string {
return static::$stagingRoot ?: parent::getStagingRoot();
public function __construct(...$arguments) {
parent::__construct(...$arguments);
$mirror = new \ReflectionClass(Stage::class);
$this->tempStore->set($mirror->getConstant('TEMPSTORE_STAGING_ROOT_KEY'), PackageManagerKernelTestBase::$testStagingRoot);
}
/**
......@@ -263,6 +283,14 @@ class TestStage extends Stage {
}
}
}
/**
* Defines a stage specifically for testing purposes.
*/
class TestStage extends Stage {
use TestStageTrait;
}
/**
......
......@@ -3,8 +3,10 @@
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Component\Datetime\Time;
use Drupal\Component\FileSystem\FileSystem;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Extension\ModuleUninstallValidatorException;
use Drupal\Core\Site\Settings;
use Drupal\package_manager\Event\PostApplyEvent;
use Drupal\package_manager\Event\PreApplyEvent;
use Drupal\package_manager\Event\StageEvent;
......@@ -63,15 +65,21 @@ class StageTest extends PackageManagerKernelTestBase {
$stage = $this->createStage();
$id = $stage->create();
$this->assertStringEndsWith("/.package_manager$site_id/$id", $stage->getStageDirectory());
// If the file_temp_path setting is empty, the stage directory should be
// created in the OS's temporary directory.
$this->assertEmpty(Settings::get('file_temp_path'));
$expected_dir = FileSystem::getOsTemporaryDirectory() . "/.package_manager$site_id/$id";
$this->assertSame($expected_dir, $stage->getStageDirectory());
// If the file_temp_path setting is changed, the existing stage shouldn't be
// affected...
$this->setSetting('file_temp_path', '/junk/drawer');
$this->assertSame($expected_dir, $stage->getStageDirectory());
$stage->destroy();
// ...but a new stage should be.
$stage = $this->createStage();
$another_id = $stage->create();
// The new stage ID should be unique, but the parent directory should be
// unchanged.
$this->assertNotSame($id, $another_id);
$this->assertStringEndsWith("/.package_manager$site_id/$another_id", $stage->getStageDirectory());
$this->assertSame("/junk/drawer/.package_manager$site_id/$another_id", $stage->getStageDirectory());
}
/**
......@@ -208,6 +216,30 @@ class StageTest extends PackageManagerKernelTestBase {
$stage->apply();
}
/**
* Tests that Composer Stager is invoked with a long timeout.
*/
public function testTimeouts(): void {
$stage = $this->createStage();
$stage->create(420);
$stage->apply();
$timeouts = [
// The beginner was given an explicit timeout.
'package_manager.beginner' => 420,
// The committer should have been called with a longer timeout than
// Composer Stager's default of 120 seconds.
'package_manager.committer' => 600,
];
foreach ($timeouts as $service_id => $expected_timeout) {
$invocations = $this->container->get($service_id)->getInvocationArguments();
// The service should have been called with the expected timeout.
$this->assertCount(1, $invocations);
$this->assertSame($expected_timeout, end($invocations[0]));
}
}
}
/**
......