diff --git a/composer.json b/composer.json
index d94ede2..5fbc58c 100644
--- a/composer.json
+++ b/composer.json
@@ -7,6 +7,7 @@
"php": ">=5.4.2",
"sdboyer/gliph": "0.1.*",
"symfony/class-loader": "2.4.*",
+ "symfony/console": "*",
"symfony/dependency-injection": "2.4.*",
"symfony/event-dispatcher": "2.4.*",
"symfony/http-foundation": "2.4.*",
@@ -28,6 +29,7 @@
"autoload": {
"psr-0": {
"Drupal\\Core": "core/lib/",
+ "Drupal\\Command": "core/lib/",
"Drupal\\Component": "core/lib/",
"Drupal\\Driver": "drivers/lib/"
},
diff --git a/core/console b/core/console
new file mode 100755
index 0000000..e8a7098
--- /dev/null
+++ b/core/console
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+addCommands($commands);
+$application->getDefinition()->addOption($env_opt);
+$application->run();
diff --git a/core/lib/Drupal/Command/CacheClearCommand.php b/core/lib/Drupal/Command/CacheClearCommand.php
new file mode 100644
index 0000000..7ddce51
--- /dev/null
+++ b/core/lib/Drupal/Command/CacheClearCommand.php
@@ -0,0 +1,35 @@
+setName('cache:clear')
+ ->setDescription('Clear all caches.');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ if ($this->bootstrap($input, $output)) {
+ $output->writeln('Clearing all caches...');
+ \drupal_flush_all_caches();
+ }
+ }
+
+}
diff --git a/core/lib/Drupal/Command/CommandBootstrapBase.php b/core/lib/Drupal/Command/CommandBootstrapBase.php
new file mode 100644
index 0000000..0b7c461
--- /dev/null
+++ b/core/lib/Drupal/Command/CommandBootstrapBase.php
@@ -0,0 +1,63 @@
+getOption('environment');
+ // Yes, we have to require_once.
+ require_once __DIR__ . '/../../../includes/bootstrap.inc';
+ try {
+ // This boot strategy ripped from drupal_handle_request().
+ // This should be about four lines of code, but it's not properly
+ // refactored at the kernel level.
+ drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
+
+ $kernel = new DrupalKernel($env, \drupal_classloader(), TRUE);
+ $kernel->boot();
+
+ // Create a request object. We shouldn't really need this but Drupal
+ // complains if it's not present.
+ $request = Request::createFromGlobals();
+ $container = \Drupal::getContainer();
+ $container->set('request', $request);
+ $container->get('request_stack')->push($request);
+
+ drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
+ return TRUE;
+ }
+ catch (\Exception $e) {
+ $formatter = $this->getHelperSet()->get('formatter');
+ $errorMessages = array(
+ 'Insufficient Drupal to proceed.',
+ 'This command requires a bootable Drupal installation.',
+ );
+ $formattedBlock = $formatter->formatBlock($errorMessages, 'error', TRUE);
+ $output->writeln($formattedBlock);
+ }
+ return FALSE;
+ }
+
+}
diff --git a/core/lib/Drupal/Command/InstallCommand.php b/core/lib/Drupal/Command/InstallCommand.php
new file mode 100644
index 0000000..b0d888c
--- /dev/null
+++ b/core/lib/Drupal/Command/InstallCommand.php
@@ -0,0 +1,78 @@
+setName('module:install')
+ ->setDescription('Install a module.')
+ ->addArgument(
+ 'name', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Machine name for the module.'
+ )
+ ->addOption(
+ 'install-dependencies',
+ 'd',
+ InputOption::VALUE_NONE,
+ 'If set, try to install all dependencies.'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $install_these_modules = $input->getArgument('name');
+ $install_dependencies = $input->getOption('install-dependencies');
+
+ $output->writeln('Trying to install: ' . implode(', ', $install_these_modules));
+
+ if ($this->bootstrap($input, $output)) {
+ $module_handler = \Drupal::moduleHandler();
+
+ $previously_installed = array();
+ $not_installed = array();
+ $installed = array_keys($module_handler->getModuleList());
+ foreach ($install_these_modules as $module) {
+ if (in_array($module, $installed)) {
+ $previously_installed[] = $module;
+ }
+ else {
+ $not_installed[] = $module;
+ }
+ }
+ if (count($previously_installed)) {
+ $output->writeln('Already installed: ' . implode(', ', $previously_installed));
+ }
+ if (count($previously_installed) == count($install_these_modules)) {
+ $output->writeln('All modules already installed.');
+ return;
+ }
+
+ if ($module_handler->install($not_installed, $install_dependencies)) {
+ $output->writeln('Installed: ' . implode(', ', $not_installed));
+ }
+ else {
+ $output->writeln('Unable to install: ' . implode(', ', $not_installed));
+ }
+ return;
+ }
+ $output->writeln('Unable to install modules.');
+ }
+
+}
diff --git a/core/lib/Drupal/Command/UninstallCommand.php b/core/lib/Drupal/Command/UninstallCommand.php
new file mode 100644
index 0000000..75febbc
--- /dev/null
+++ b/core/lib/Drupal/Command/UninstallCommand.php
@@ -0,0 +1,78 @@
+setName('module:uninstall')
+ ->setDescription('Uninstall a module.')
+ ->addArgument(
+ 'name', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Machine name for the module.'
+ )
+ ->addOption(
+ 'uninstall-dependencies',
+ 'd',
+ InputOption::VALUE_NONE,
+ 'If set, try to remove unused dependencies.'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $uninstall_these_modules = $input->getArgument('name');
+ $uninstall_dependencies = $input->getOption('uninstall-dependencies');
+
+ $output->writeln('Trying to uninstall: ' . implode(', ', $uninstall_these_modules));
+
+ if ($this->bootstrap($input, $output)) {
+ $module_handler = \Drupal::moduleHandler();
+
+ $previously_installed = array();
+ $not_installed = array();
+ $installed = array_keys($module_handler->getModuleList());
+ foreach ($uninstall_these_modules as $module) {
+ if (in_array($module, $installed)) {
+ $previously_installed[] = $module;
+ }
+ else {
+ $not_installed[] = $module;
+ }
+ }
+ if (count($not_installed)) {
+ $output->writeln('Not installed: ' . implode(', ', $not_installed));
+ }
+ if (count($not_installed) == count($uninstall_these_modules)) {
+ $output->writeln('None of the modules are installed.');
+ return;
+ }
+
+ if ($module_handler->uninstall($previously_installed, $uninstall_dependencies)) {
+ $output->writeln('Uninstalled: ' . implode(', ', $previously_installed));
+ }
+ else {
+ $output->writeln('Unable to uninstall: ' . implode(', ', $previously_installed));
+ }
+ return;
+ }
+ $output->writeln('Unable to uninstall modules.');
+ }
+
+}
diff --git a/core/lib/Drupal/Command/UserLoginCommand.php b/core/lib/Drupal/Command/UserLoginCommand.php
new file mode 100644
index 0000000..27e8399
--- /dev/null
+++ b/core/lib/Drupal/Command/UserLoginCommand.php
@@ -0,0 +1,47 @@
+setName('user:login')
+ ->setDescription("Provide 'forgot password' URL for user.")
+ ->addArgument(
+ 'uid',
+ InputArgument::OPTIONAL,
+ 'User ID number of user to login.',
+ 1
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $uid = $input->getArgument('uid');
+ if ($this->bootstrap($input, $output)) {
+ $account = user_load($uid);
+ if ($account) {
+ $output->writeln(user_pass_reset_url($account, array('langcode' => NULL)));
+ return;
+ }
+ }
+ $output->writeln('Unable to generate one-time login for user id: ' . $uid . '');
+ }
+
+}