ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
MigrateCommand.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 2016 Richard Klees <richard.klees@concepts-and-training.de> Extended GPL, see docs/LICENSE */
3 
4 namespace ILIAS\Setup\CLI;
5 
16 
20 class MigrateCommand extends Command
21 {
22  use HasAgent;
23  use ObjectiveHelper;
24 
25  protected static $defaultName = "migrate";
26 
30  protected $preconditions;
31 
35  public function __construct(AgentFinder $agent_finder, array $preconditions)
36  {
38  $this->agent_finder = $agent_finder;
39  $this->preconditions = $preconditions;
40  }
41 
42  public function configure()
43  {
44  $this->setDescription("Starts and manages migrations needed after an update of ILIAS");
45  $this->addOption("yes", "y", InputOption::VALUE_NONE, "Confirm every message of the installation.");
46  $this->addOption("run", "R", InputOption::VALUE_REQUIRED, "Run the migration with the name given.");
47  $this->addOption(
48  "steps",
49  "S",
50  InputOption::VALUE_REQUIRED,
51  "Run the selected migration with X steps. Pass " . Migration::INFINITE . " for all remaining steps."
52  );
54  }
55 
56  public function execute(InputInterface $input, OutputInterface $output)
57  {
58  $io = new IOWrapper($input, $output);
59  $io->printLicenseMessage();
60  $io->title("Trigger migrations in ILIAS");
61 
62  // Dispatching further sub-commands
63  if ($input->hasOption('run') && !empty($input->getOption('run'))) {
64  $this->runMigration($input, $io);
65  } else {
66  $this->listMigrations($input, $io);
67  }
68  }
69 
70  protected function runMigration(InputInterface $input, IOWrapper $io) : void
71  {
72  $agent = $this->getRelevantAgent($input);
73 
74  $migration_name = $input->getOption('run');
75  $migrations = $agent->getMigrations();
76  if (!isset($migrations[$migration_name]) || !($migrations[$migration_name] instanceof Migration)) {
77  $io->error("Aborting Migration, did not find {$migration_name}.");
78  return;
79  }
80  $migration = $migrations[$migration_name];
81 
82  $steps = (int)$input->getOption('steps');
83 
84  switch ($steps) {
86  $io->text("Determined infinite steps to run.");
87  break;
88  case 0:
89  $steps = $migration->getDefaultAmountOfStepsPerRun();
90  $io->text("no --steps option found, fallback to default amount of steps of migration. ($steps)");
91  break;
92  default:
93  $io->text("Determined $steps step(s) to run.");
94  break;
95 
96  }
97  $objective = new Objective\MigrationObjective($migration, $steps);
98 
99  $env = new ArrayEnvironment([
101  ]);
102 
103  $preconditions = $migration->getPreconditions($env);
104  if (count($preconditions) > 0) {
105  $objective = new Objective\ObjectiveWithPreconditions(
106  $objective,
107  ...$preconditions
108  );
109  }
110  $steps_text = $steps === Migration::INFINITE ? 'all' : (string)$steps;
111  $io->inform("Preparing Environment for {$steps_text} steps in {$migration_name}");
112  try {
113  $this->achieveObjective($objective, $env, $io);
114  } catch (NoConfirmationException $e) {
115  $io->error("Aborting Migration, a necessary confirmation is missing:\n\n" . $e->getRequestedConfirmation());
116  }
117  }
118 
119  protected function listMigrations(InputInterface $input, IOWrapper $io) : void
120  {
121  $agent = $this->getRelevantAgent($input);
122  $migrations = $agent->getMigrations();
123  $count = count($migrations);
124  if ($count === 0) {
125  $io->inform("There are currently no migrations to run.");
126  return;
127  }
128 
129  $env = new ArrayEnvironment([
131  ]);
132 
133  $io->inform("There are {$count} to run:");
134  foreach ($migrations as $migration_key => $migration) {
135  $env = $this->prepareEnvironmentForMigration($env, $migration);
136  $migration->prepare($env);
137  $steps = $migration->getRemainingAmountOfSteps();
138  $status = $steps === 0 ? "[done]" : "[remaining steps: {$steps}]";
139  $io->text($migration_key . ": " . $migration->getLabel() . " " . $status);
140  }
141  $io->inform("Run them by passing --run <migration_id>, e.g. --run $migration_key");
142  }
143 
144  protected function prepareEnvironmentForMigration(
145  Environment $environment,
146  Migration $migration
147  ) : Environment {
148  $preconditions = $migration->getPreconditions($environment);
149  if (count($preconditions) > 0) {
150  $objective = new Objective\ObjectiveWithPreconditions(
151  new Objective\NullObjective(),
152  ...$preconditions
153  );
154 
155  $environment = $this->achieveObjective($objective, $environment);
156  }
157 
158  return $environment;
159  }
160 }
Wrapper around symfonies input and output facilities to provide just the functionality required for t...
Definition: IOWrapper.php:16
An objective is a desired state of the system that is supposed to be created by the setup...
Definition: Objective.php:14
A migration is a potentially long lasting operation that can be broken into discrete steps...
Definition: Migration.php:12
execute(InputInterface $input, OutputInterface $output)
__construct(AgentFinder $agent_finder, array $preconditions)
A non-objective, nothing to do to achieve it...
getRelevantAgent(InputInterface $input)
Definition: HasAgent.php:28
prepareEnvironmentForMigration(Environment $environment, Migration $migration)
runMigration(InputInterface $input, IOWrapper $io)
$steps
Definition: latex.php:3
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
An environment holds resources to be used in the setup process.
Definition: Environment.php:11
configureCommandForPlugins()
Definition: HasAgent.php:21
__construct(Container $dic, ilPlugin $plugin)
trait HasAgent
Add this to an Command that has an agent.
Definition: HasAgent.php:15
listMigrations(InputInterface $input, IOWrapper $io)
Signals that a necessary confirmation from the admin is missing.
inform(string $message)
Definition: IOWrapper.php:74
getPreconditions(Environment $environment)
Objectives the migration depend on.