• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yast / yast-packager / 15441808734

04 Jun 2025 12:05PM UTC coverage: 37.221% (-0.2%) from 37.407%
15441808734

push

github

web-flow
Merge pull request #659 from yast/huha-no-baseurl-crash

Prevent a crash if a repo doesn't have a baseurl

1 of 1 new or added line in 1 file covered. (100.0%)

123 existing lines in 11 files now uncovered.

4366 of 11730 relevant lines covered (37.22%)

23.4 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.86
/src/modules/SlideShowCallbacks.rb
1
require "yast"
1✔
2
require "pathname"
1✔
3

4
# Yast namespace
5
module Yast
1✔
6
  # Provides the Callbacks for SlideShow
7
  class SlideShowCallbacksClass < Module
1✔
8
    include Yast::Logger
1✔
9

10
    def main
1✔
11
      Yast.import "Pkg"
1✔
12
      Yast.import "UI"
1✔
13

14
      textdomain "packager"
1✔
15

16
      Yast.import "Installation"
1✔
17
      Yast.import "Label"
1✔
18
      Yast.import "Mode"
1✔
19
      Yast.import "Stage"
1✔
20
      Yast.import "PackageCallbacks"
1✔
21
      Yast.import "Popup"
1✔
22
      Yast.import "SlideShow"
1✔
23
      Yast.import "PackageSlideShow"
1✔
24
      Yast.import "Message"
1✔
25
      Yast.import "Directory"
1✔
26
      Yast.import "URL"
1✔
27

28
      @remote_provide = false
1✔
29

30
      @pkg_inprogress = ""
1✔
31

32
      # never show the disk space warning popup during autoinstallation
33
      @ask_again = !Mode.autoinst
1✔
34
      # true == continue with the installation
35
      @user_input = true
1✔
36
    end
37

38
    # Check for user button presses and handle them.
39
    #
40
    # @return true if user wishes to abort
41
    #
42
    def HandleInput
1✔
43
      button = UI.PollInput
×
44

45
      # in case of cancel ask user if he really wants to quit installation
46
      if [:abort, :cancel].include?(button)
×
47
        if Mode.normal
×
48
          SlideShow.SetUserAbort(
×
49
            Popup.AnyQuestion(
50
              Popup.NoHeadline,
51
              # popup yes-no
52
              _("Do you really want\nto quit the installation?"),
53
              Label.YesButton,
54
              Label.NoButton,
55
              :focus_no
56
            )
57
          )
58
        elsif Stage.initial
×
59
          SlideShow.SetUserAbort(Popup.ConfirmAbort(:unusable)) # Mode::update (), Stage::cont ()
×
60
        else
61
          SlideShow.SetUserAbort(Popup.ConfirmAbort(:incomplete))
×
62
        end
63

64
        SlideShow.AppendMessageToInstLog(_("Aborted")) if SlideShow.GetUserAbort
×
65
      else
66
        SlideShow.HandleInput(button)
×
67
      end
68

UNCOV
69
      nil
×
70
    end
71

72
    # Start of file providal.
73
    #
74
    # This can be a download (if the package is provided by a remote
75
    # repository) or simply accessing a local repo, e.g. on the currently
76
    # mounted installation media.
77
    #
78
    def StartProvide(name, archivesize, remote)
1✔
79
      @pkg_inprogress = name
×
80
      @remote_provide = remote
×
81

82
      PackageSlideShow.DownloadStart(name, archivesize) if @remote_provide
×
UNCOV
83
      nil
×
84
    end
85

86
    # Update progress during file providal.
87
    #
88
    # This is meant to update a progress bar for the download percent.
89
    #
90
    def ProgressProvide(percent)
1✔
91
      PackageSlideShow.DownloadProgress(percent) if @remote_provide
×
92
      HandleInput()
×
93
      !SlideShow.GetUserAbort
×
94
    end
95

96
    # Update during package download: Percent, average and current bytes per second.
97
    #
98
    # Notice that there is also ProgressProvide for only the percentage value;
99
    # this callback is meant to update a display of the current data rate and
100
    # possibly predictions about the remaining time based on the data rate.
101
    #
102
    def ProgressDownload(_percent, _bps_avg, _bps_current)
1✔
103
      HandleInput()
×
104
      !SlideShow.GetUserAbort
×
105
    end
106

107
    # End of file providal; used both for success (error == 0) and error (error
108
    # != 0).
109
    #
110
    # If this was a download from a remote repo, this means that the download
111
    # is now finished.
112
    #
113
    def DoneProvide(error, reason, name)
1✔
114
      if @remote_provide
×
115
        if error.zero?
×
116
          PackageSlideShow.DownloadEnd(name)
×
117
        else
118
          PackageSlideShow.DownloadError(error, reason, name)
×
119
        end
120
        @remote_provide = false
×
121
      end
122
      return "C" if SlideShow.GetUserAbort
×
123
      return PackageCallbacks.DoneProvide(error, reason, name) if error.nonzero?
×
124

125
      ""
×
126
    end
127

128
    # A pre- or post-install/uninstall script is started.
129
    #
130
    def ScriptStart(patch_name, patch_version, patch_arch, script_path)
1✔
131
      patch_full_name = PackageCallbacks.FormatPatchName(
×
132
        patch_name,
133
        patch_version,
134
        patch_arch
135
      )
136
      Builtins.y2milestone(
×
137
        "ScriptStart: patch:%1, script:%2",
138
        patch_full_name,
139
        script_path
140
      )
141

142
      # FIXME: maybe use a DelayedProgressPopup here?
143

144
      # reset the progressbar
145
      if UI.WidgetExists(:progressCurrentPackage)
×
146
        # FIXME: This widget does not exist anymore.
147
        UI.ChangeWidget(:progressCurrentPackage, :Label, patch_full_name)
×
148
        UI.ChangeWidget(:progressCurrentPackage, :Value, 0)
×
149
      end
150

151
      # message in the installation log widget, %1 is a patch name which contains the script
152
      log_line = Builtins.sformat(_("Starting script %1"), patch_full_name)
×
153

154
      SlideShow.AppendMessageToInstLog(log_line)
×
155

UNCOV
156
      nil
×
157
    end
158

159
    # Progress during a pre- or post-install/uninstall script.
160
    #
161
    # Since there is no way to find out how far the execution of this script
162
    # has progressed, this is only a "ping" notification, not reporting
163
    # percents.
164
    #
165
    def ScriptProgress(ping, output)
1✔
166
      Builtins.y2milestone("ScriptProgress: ping:%1, output: %2", ping, output)
2✔
167
      # FIXME: maybe use a DelayedProgressPopup here?
168

169
      if !output.nil? && output != ""
2✔
170
        # remove the trailing new line character
171
        if Builtins.substring(output, Ops.subtract(Builtins.size(output), 1), 1) == "\n"
×
172
          output = Builtins.substring(
×
173
            output,
174
            0,
175
            Ops.subtract(Builtins.size(output), 1)
176
          )
177
        end
178

179
        # add the output to the log widget
180
        SlideShow.AppendMessageToInstLog(output)
×
181
      end
182

183
      input = UI.PollInput
2✔
184
      Builtins.y2milestone("input: %1", input)
2✔
185

186
      ![:abort, :close].include?(input)
2✔
187
    end
188

189
    # Error reporting during execution of a pre- or post-install/uninstall script.
190
    #
191
    def ScriptProblem(description)
1✔
192
      # display Abort/Retry/Ignore popup
193
      PackageCallbacks.ScriptProblem(description)
×
194
    end
195

196
    # A pre- or post-install/uninstall script has finished.
197
    #
198
    def ScriptFinish
1✔
199
      Builtins.y2milestone("ScriptFinish")
×
200

UNCOV
201
      nil
×
202
    end
203

204
    def Message(patch_name, patch_version, patch_arch, message)
1✔
205
      patch_full_name = PackageCallbacks.FormatPatchName(
×
206
        patch_name,
207
        patch_version,
208
        patch_arch
209
      )
210
      Builtins.y2milestone("Message (%1): %2", patch_full_name, message)
×
211

212
      if patch_full_name != ""
×
213
        # label, %1 is patch name with version and architecture
214
        patch_full_name = Builtins.sformat(_("Patch %1\n\n"), patch_full_name)
×
215
      end
216

217
      Popup.LongMessage(Ops.add(patch_full_name, message))
×
218

UNCOV
219
      nil
×
220
    end
221

222
    #--------------------------------------------------------------------------
223
    # slide show
224

225
    def YesNoButtonBox
1✔
226
      yes_button = PushButton(Id(:yes), Opt(:key_F10), Label.YesButton)
×
227
      no_button = PushButton(
×
228
        Id(:no),
229
        Opt(:default, :key_F9),
230
        Label.NoButton
231
      )
232

233
      HBox(
×
234
        HStretch(),
235
        HWeight(1, yes_button),
236
        HSpacing(2),
237
        HWeight(1, no_button),
238
        HStretch()
239
      )
240
    end
241

242
    def YesNoAgainWarning(message)
1✔
243
      return @user_input if !@ask_again
×
244

245
      icon = Empty()
×
246

247
      # show the warning icon if possible
248
      ui_capabilities = UI.GetDisplayInfo
×
249

250
      if Ops.get_boolean(ui_capabilities, "HasLocalImageSupport", false)
×
251
        icon = Image("dialog-warning", "")
×
252
      end
253

254
      content = MarginBox(
×
255
        1.5,
256
        0.5,
257
        VBox(
258
          HBox(
259
            VCenter(icon),
260
            HSpacing(1),
261
            VCenter(Heading(Label.WarningMsg)),
262
            HStretch()
263
          ),
264
          VSpacing(0.2),
265
          Left(Label(message)),
266
          VSpacing(0.2),
267
          Left(CheckBox(Id(:dont_ask), Message.DoNotShowMessageAgain)),
268
          VSpacing(0.5),
269
          YesNoButtonBox()
270
        )
271
      )
272

273
      UI.OpenDialog(Opt(:decorated), content)
×
274

275
      ret = UI.UserInput
×
276

277
      @ask_again = !Convert.to_boolean(UI.QueryWidget(Id(:dont_ask), :Value))
×
278

279
      if !@ask_again
×
280
        # remember the user input
281
        @user_input = ret == :yes
×
282
      end
283

284
      UI.CloseDialog
×
285

286
      ret == :yes
×
287
    end
288

289
    # Callback that will be called by the packager for each RPM as it is being installed or deleted.
290
    # Note: The packager doesn't call this directly - the corresponding wrapper callbacks do
291
    # and pass the "deleting" flag as appropriate.
292
    #
293
    def DisplayStartInstall(pkg_name, pkg_location, pkg_description, pkg_size, deleting)
1✔
294
      PackageSlideShow.PkgInstallStart(
6✔
295
        pkg_name,
296
        pkg_location,
297
        pkg_description,
298
        pkg_size,
299
        deleting
300
      )
301
      HandleInput()
6✔
302

303
      # warn user about exhausted diskspace during installation (not if deleting packages)
304
      if !deleting && @ask_again
6✔
305
        pkgdu = Pkg.PkgDU(@pkg_inprogress)
6✔
306

307
        Builtins.y2debug("PkgDU(%1): %2", @pkg_inprogress, pkgdu)
6✔
308

309
        if pkgdu.nil?
6✔
310
          # disk usage for each partition is not known
311
          # assume that all files will be installed into the root directory,
312
          # this is the current free space (in bytes)
313
          disk_available = Pkg.TargetAvailable(Installation.destdir)
3✔
314

315
          Builtins.y2milestone(
3✔
316
            "Available space (%1): %2",
317
            Installation.destdir,
318
            disk_available
319
          )
320

321
          if disk_available < 0
3✔
322
            log.debug("Data overflow, too much free space available, skipping the check")
1✔
323
          elsif disk_available < pkg_size
2✔
324
            Builtins.y2warning(
1✔
325
              "Not enough free space in %1: available: %2, required: %3",
326
              Installation.destdir,
327
              disk_available,
328
              pkg_size
329
            )
330

331
            cont = YesNoAgainWarning(
1✔
332
              # yes-no popup
333
              _(
334
                "The disk space is nearly exhausted.\nContinue with the installation?"
335
              )
336
            )
337

338
            SlideShow.SetUserAbort(true) if !cont
1✔
339
          end
340
        else
341
          # check each mount point
342
          Builtins.foreach(pkgdu) do |part, data|
3✔
343
            # disk sizes from libzypp, in KiB!
344
            _disk_size, used_now, used_future, read_only = *data
3✔
345
            # the size difference, how much the package needs on this partition
346
            required_space = used_future - used_now
3✔
347

348
            # skip read-only partitions, the package cannot be installed anyway
349
            if read_only == 1
3✔
350
              Builtins.y2debug("Skipping read-only partition %1", part)
×
351
              next
×
352
            end
353

354
            # nothing to install on this partition, skip it (bsc#926841)
355
            if required_space <= 0
3✔
356
              log.debug("Nothing to install at #{part}, skipping")
×
357
              next
×
358
            end
359

360
            target_dir = File.join(Installation.destdir, part)
3✔
361

362
            # handle missing directories (not existing yet or incorrect metadata),
363
            # if the directory does not exist then go up, normally it should
364
            # stop at Installation.destdir (but it will stop at "/" at last)
365
            until File.exist?(target_dir)
3✔
366
              log.warn("Directory #{target_dir} does not exist")
×
367
              target_dir = Pathname.new(target_dir).parent.to_s
×
368
              log.info("Checking the parent directory (#{target_dir})")
×
369
            end
370

371
            disk_available = Pkg.TargetAvailable(target_dir)
3✔
372
            Builtins.y2debug(
3✔
373
              "partition: %1 (%2), available: %3",
374
              part,
375
              target_dir,
376
              disk_available
377
            )
378

379
            if disk_available < 0
3✔
380
              log.debug("Data overflow, too much free space available, skipping the check")
1✔
381
              next
1✔
382
            end
383

384
            # we need to convert the size to KiB to compare it with the libzypp size
385
            if (disk_available / 1024) < required_space
2✔
386
              Builtins.y2warning(
1✔
387
                "Not enough free space in %1 (%2): available: %3, required: %4",
388
                part,
389
                target_dir,
390
                disk_available,
391
                required_space
392
              )
393

394
              cont = YesNoAgainWarning(
1✔
395
                # warning popup - %1 is directory name (e.g. /boot)
396
                Builtins.sformat(
397
                  _(
398
                    "The disk space in partition %1 is nearly exhausted.\n" \
399
                    "Continue with the installation?"
400
                  ),
401
                  part
402
                )
403
              )
404

405
              SlideShow.SetUserAbort(true) if !cont
1✔
406

407
              # don't check the other partitions
408
              raise Break
1✔
409
            end
410
          end
411
        end
412
      end
413

414
      nil
6✔
415
    end
416

417
    # Notification that a package starts being installed, updated or removed.
418
    def StartPackage(name, location, summary, install_size, is_delete)
1✔
419
      PackageCallbacks._package_name = name
×
420
      PackageCallbacks._package_size = install_size
×
421
      PackageCallbacks._deleting_package = is_delete
×
422

423
      DisplayStartInstall(name, location, summary, install_size, is_delete)
×
424

UNCOV
425
      nil
×
426
    end
427

428
    # Progress while a package is being installed, updated or removed.
429
    def ProgressPackage(pkg_percent)
1✔
430
      PackageSlideShow.PkgInstallProgress(pkg_percent)
×
431
      HandleInput()
×
432

433
      Builtins.y2milestone("Aborted at %1%%", pkg_percent) if SlideShow.GetUserAbort
×
434

435
      !SlideShow.GetUserAbort
×
436
    end
437

438
    # Notification that a package is finished being installed, updated or removed.
439
    #
440
    # just to override the PackageCallbacks default (which does a 'CloseDialog' :-})
441
    def DonePackage(error, reason)
1✔
442
      return "I" if SlideShow.GetUserAbort
×
443

444
      ret = ""
×
445
      if error.nonzero?
×
446
        ret = PackageCallbacks.DonePackage(error, reason)
×
447
      # put additional rpm output to the installation log
448
      elsif !reason.nil? && Ops.greater_than(Builtins.size(reason), 0)
×
449
        Builtins.y2milestone("Additional RPM output: %1", reason)
×
450
        SlideShow.AppendMessageToInstLog(reason)
×
451
      end
452

453
      if Builtins.size(ret).zero? ||
×
454
          Builtins.tolower(Builtins.substring(ret, 0, 1)) == "i"
455
        PackageSlideShow.PkgInstallDone(
×
456
          PackageCallbacks._package_name,
457
          PackageCallbacks._package_size,
458
          PackageCallbacks._deleting_package
459
        )
460
      end
461
      ret
×
462
    end
463

464
    #  at start of file providal
465
    def StartDeltaProvide(_name, _archivesize)
1✔
UNCOV
466
      nil
×
467
    end
468

469
    #  at start of file providal
470
    def StartDeltaApply(_name)
1✔
UNCOV
471
      nil
×
472
    end
473

474
    # during file providal
475
    def ProgressDeltaApply(_percent)
1✔
UNCOV
476
      nil
×
477
    end
478

479
    #  at end of file providal
480
    def FinishDeltaProvide
1✔
UNCOV
481
      nil
×
482
    end
483

484
    def ProblemDeltaDownload(descr)
1✔
485
      # error in installation log, %1 is detail error description
486
      SlideShow.AppendMessageToInstLog(
×
487
        Builtins.sformat(_("Failed to download delta RPM: %1"), descr)
488
      )
489

UNCOV
490
      nil
×
491
    end
492

493
    def ProblemDeltaApply(descr)
1✔
494
      # error in installation log, %1 is detail error description
495
      SlideShow.AppendMessageToInstLog(
×
496
        Builtins.sformat(_("Failed to apply delta RPM: %1"), descr)
497
      )
498

UNCOV
499
      nil
×
500
    end
501

502
    # change of repository
503
    # source: 0 .. n-1
504
    # media:  1 .. n
505
    #
506
    def CallbackSourceChange(source, media)
1✔
507
      PackageCallbacks.SourceChange(source, media) # inform PackageCallbacks about the change
×
508

509
      # display remaining packages
510
      PackageSlideShow.UpdateTotalProgressText
×
511

UNCOV
512
      nil
×
513
    end
514

515
    def MediaChange(error_code, error, url, product, current, current_label,
1✔
516
      wanted, wanted_label, double_sided, devices, current_device)
517
      devices = deep_copy(devices)
×
518

519
      PackageCallbacks.MediaChange(
×
520
        error_code,
521
        error,
522
        url,
523
        product,
524
        current,
525
        current_label,
526
        wanted,
527
        wanted_label,
528
        double_sided,
529
        devices,
530
        current_device
531
      )
532
    end
533

534
    # Install callbacks for slideshow.
535
    def InstallSlideShowCallbacks
1✔
536
      Builtins.y2milestone("InstallSlideShowCallbacks")
×
537

538
      Pkg.CallbackStartPackage(
×
539
        fun_ref(
540
          method(:StartPackage),
541
          "void (string, string, string, integer, boolean)"
542
        )
543
      )
544
      Pkg.CallbackProgressPackage(
×
545
        fun_ref(method(:ProgressPackage), "boolean (integer)")
546
      )
547
      Pkg.CallbackDonePackage(
×
548
        fun_ref(method(:DonePackage), "string (integer, string)")
549
      )
550

551
      Pkg.CallbackStartProvide(
×
552
        fun_ref(method(:StartProvide), "void (string, integer, boolean)")
553
      )
554
      Pkg.CallbackProgressProvide(
×
555
        fun_ref(method(:ProgressProvide), "boolean (integer)")
556
      )
557
      Pkg.CallbackDoneProvide(
×
558
        fun_ref(method(:DoneProvide), "string (integer, string, string)")
559
      )
560
      Pkg.CallbackProgressDownload(
×
561
        fun_ref(
562
          method(:ProgressDownload),
563
          "boolean (integer, integer, integer)"
564
        )
565
      )
566

567
      Pkg.CallbackSourceChange(
×
568
        fun_ref(method(:CallbackSourceChange), "void (integer, integer)")
569
      )
570

571
      Pkg.CallbackStartDeltaDownload(
×
572
        fun_ref(method(:StartDeltaProvide), "void (string, integer)")
573
      )
574
      Pkg.CallbackProgressDeltaDownload(
×
575
        fun_ref(method(:ProgressProvide), "boolean (integer)")
576
      )
577
      Pkg.CallbackProblemDeltaDownload(
×
578
        fun_ref(method(:ProblemDeltaDownload), "void (string)")
579
      )
580
      Pkg.CallbackFinishDeltaDownload(
×
581
        fun_ref(method(:FinishDeltaProvide), "void ()")
582
      )
583

584
      Pkg.CallbackStartDeltaApply(
×
585
        fun_ref(method(:StartDeltaApply), "void (string)")
586
      )
587
      Pkg.CallbackProgressDeltaApply(
×
588
        fun_ref(method(:ProgressDeltaApply), "void (integer)")
589
      )
590
      Pkg.CallbackProblemDeltaApply(
×
591
        fun_ref(method(:ProblemDeltaApply), "void (string)")
592
      )
593
      Pkg.CallbackFinishDeltaApply(
×
594
        fun_ref(method(:FinishDeltaProvide), "void ()")
595
      )
596

597
      Pkg.CallbackScriptStart(
×
598
        fun_ref(method(:ScriptStart), "void (string, string, string, string)")
599
      )
600
      Pkg.CallbackScriptProgress(
×
601
        fun_ref(method(:ScriptProgress), "boolean (boolean, string)")
602
      )
603
      Pkg.CallbackScriptProblem(
×
604
        fun_ref(method(:ScriptProblem), "string (string)")
605
      )
606
      Pkg.CallbackScriptFinish(fun_ref(method(:ScriptFinish), "void ()"))
×
607

608
      Pkg.CallbackMessage(
×
609
        fun_ref(
610
          PackageCallbacks.method(:Message),
611
          "boolean (string, string, string, string)"
612
        )
613
      )
614

615
      Pkg.CallbackMediaChange(
×
616
        fun_ref(
617
          method(:MediaChange),
618
          "string (string, string, string, string, integer, string, integer, " \
619
          "string, boolean, list <string>, integer)"
620
        )
621
      )
622

UNCOV
623
      nil
×
624
    end
625

626
    # Remove callbacks for slideshow. Should be in SlideShowCallbacks but
627
    # that doesn't work at the moment.
628
    def RemoveSlideShowCallbacks
1✔
629
      Builtins.y2milestone("RemoveSlideShowCallbacks")
×
630

631
      Pkg.CallbackStartPackage(nil)
×
632
      Pkg.CallbackProgressPackage(nil)
×
633
      Pkg.CallbackDonePackage(nil)
×
634

635
      Pkg.CallbackStartProvide(nil)
×
636
      Pkg.CallbackProgressProvide(nil)
×
637
      Pkg.CallbackDoneProvide(nil)
×
638

639
      Pkg.CallbackSourceChange(nil)
×
640

641
      Pkg.CallbackStartDeltaDownload(nil)
×
642
      Pkg.CallbackProgressDeltaDownload(nil)
×
643
      Pkg.CallbackProblemDeltaDownload(nil)
×
644
      Pkg.CallbackFinishDeltaDownload(nil)
×
645

646
      Pkg.CallbackStartDeltaApply(nil)
×
647
      Pkg.CallbackProgressDeltaApply(nil)
×
648
      Pkg.CallbackProblemDeltaApply(nil)
×
649
      Pkg.CallbackFinishDeltaApply(nil)
×
650

651
      Pkg.CallbackScriptStart(nil)
×
652
      Pkg.CallbackScriptProgress(nil)
×
653
      Pkg.CallbackScriptProblem(nil)
×
654
      Pkg.CallbackScriptFinish(nil)
×
655

656
      Pkg.CallbackMessage(nil)
×
657

UNCOV
658
      nil
×
659
    end
660

661
    publish function: :StartProvide, type: "void (string, integer, boolean)"
1✔
662
    publish function: :ProgressProvide, type: "boolean (integer)"
1✔
663
    publish function: :ProgressDownload, type: "boolean (integer, integer, integer)"
1✔
664
    publish function: :DoneProvide, type: "string (integer, string, string)"
1✔
665
    publish function: :ScriptStart, type: "void (string, string, string, string)"
1✔
666
    publish function: :ScriptProgress, type: "boolean (boolean, string)"
1✔
667
    publish function: :ScriptProblem, type: "string (string)"
1✔
668
    publish function: :ScriptFinish, type: "void ()"
1✔
669
    publish function: :Message, type: "void (string, string, string, string)"
1✔
670
    publish function: :DisplayStartInstall, type: "void (string, string, string, integer, boolean)"
1✔
671
    publish function: :StartPackage, type: "void (string, string, string, integer, boolean)"
1✔
672
    publish function: :ProgressPackage, type: "boolean (integer)"
1✔
673
    publish function: :DonePackage, type: "string (integer, string)"
1✔
674
    publish function: :StartDeltaProvide, type: "void (string, integer)"
1✔
675
    publish function: :StartDeltaApply, type: "void (string)"
1✔
676
    publish function: :ProgressDeltaApply, type: "void (integer)"
1✔
677
    publish function: :ProblemDeltaDownload, type: "void (string)"
1✔
678
    publish function: :ProblemDeltaApply, type: "void (string)"
1✔
679
    publish function: :CallbackSourceChange, type: "void (integer, integer)"
1✔
680
    publish function: :MediaChange,
1✔
681
      type:     "string (string, string, string, string, integer, string, integer, " \
682
                "string, boolean, list <string>, integer)"
683
    publish function: :InstallSlideShowCallbacks, type: "void ()"
1✔
684
    publish function: :RemoveSlideShowCallbacks, type: "void ()"
1✔
685
  end
686

687
  SlideShowCallbacks = SlideShowCallbacksClass.new
1✔
688
  SlideShowCallbacks.main
1✔
689
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc