Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a command cache. #1519

Merged
merged 3 commits into from
May 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,4 @@ template/composer.lock

CHANGELOG.partial
build
cache/commands/*
1 change: 1 addition & 0 deletions config/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ blt:
example-local: ${repo.root}/blt/example.project.local.yml
schema-version: ${repo.root}/blt/.schema_version
multisite: ${docroot}/sites/${multisite.name}/site.yml
command-cache-dir: ${blt.root}/cache/commands

composer:
bin: ${repo.root}/${bin.path}
Expand Down
3 changes: 0 additions & 3 deletions scripts/blt/ci/internal/create_blt_project.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ yaml-cli update:value blt/project.yml project.local.hostname '127.0.0.1:8888'
yaml-cli update:value blt/project.yml git.remotes.0 bolt8@svn-5223.devcloud.hosting.acquia.com:bolt8.git
yaml-cli update:value blt/project.yml git.remotes.1 git@github.com:acquia-pso/blted8.git

# BLT added new dependencies for us, so we must update.
composer update

git add -A
git commit -m 'Adding new dependencies from BLT update.' -n
# Create a .travis.yml, just to make sure it works. It won't be executed.
Expand Down
10 changes: 8 additions & 2 deletions src/Robo/Blt.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Acquia\Blt\Robo;

use Acquia\Blt\Robo\Common\Executor;
use Acquia\Blt\Robo\Datastore\FileStore;
use Acquia\Blt\Robo\Filesets\FilesetManager;
use Acquia\Blt\Robo\Inspector\Inspector;
use Acquia\Blt\Robo\Inspector\InspectorAwareInterface;
Expand Down Expand Up @@ -170,7 +171,7 @@ private function addDefaultArgumentsAndOptions(Application $app) {
/**
* Register the necessary classes for BLT.
*/
public static function configureContainer($container) {
public function configureContainer($container) {
$container->share('logStyler', BltLogStyle::class);

// We create our own builder so that non-command classes are able to
Expand All @@ -197,10 +198,15 @@ public static function configureContainer($container) {

$container->share('filesetManager', FilesetManager::class);

// Install our command cache into the command factory.
$commandCacheDir = $this->getConfig()->get('blt.command-cache-dir');
$commandCacheDataStore = new FileStore($commandCacheDir);
/** @var \Consolidation\AnnotatedCommand\AnnotatedCommandFactory $factory */
$factory = $container->get('commandFactory');
// Tell the command loader to only allow command functions that have a
// name/alias.
$factory = $container->get('commandFactory');
$factory->setIncludeAllPublicMethods(FALSE);
$factory->setDataStore($commandCacheDataStore);
}

/**
Expand Down
8 changes: 5 additions & 3 deletions src/Robo/Commands/Blt/UpdateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,18 @@ public function initialize() {
*/
public function createProject() {
$result = $this->cleanUpProjectTemplate();
$result = $this->updateRootProjectFiles();
$result = $this->reInstallComposerPackages();
$result = $this->setProjectName();
$result = $this->initAndCommitRepo();
$this->installBltAlias();
$this->displayArt();

$this->yell("Your new BLT-based project has been created in {$this->getConfigValue('repo.root')}.");
$this->say("Please continue by following the \"Creating a new project with BLT\" instructions:");
$this->say("<comment>http://blt.readthedocs.io/en/8.x/readme/creating-new-project/</comment>");

return $result;
return $result->getExitCode();
}

/**
Expand Down Expand Up @@ -163,7 +165,8 @@ public function initAndCommitRepo() {
->exec("git init")
->exec('git add -A')
->exec("git commit -m 'Initial commit.'")
->detectInteractive()
->interactive(FALSE)
->printOutput(FALSE)
->run();

return $result;
Expand Down Expand Up @@ -200,7 +203,6 @@ protected function cleanUpProjectTemplate() {
* @return \Robo\Result
*/
protected function reInstallComposerPackages() {
$this->updateRootProjectFiles();
$this->say("Installing new Composer dependencies provided by BLT. This make take a while...");
$result = $this->taskFilesystemStack()
->remove([
Expand Down
4 changes: 2 additions & 2 deletions src/Robo/Config/DefaultConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,12 @@ public function populateHelperConfig() {
*/
protected function getSiteDirs() {
$sites_dir = $this->get('docroot') . '/sites';
$sites = [];

// If BLT's template has not yet been rsynced into the project root, it is
// possible that docroot/sites does not exist.
if (!file_exists($sites_dir)) {
return [];
return $sites;
}

$finder = new Finder();
Expand All @@ -101,7 +102,6 @@ protected function getSiteDirs() {
->directories()
->depth('< 1')
->exclude(['g']);
$sites = [];
foreach ($dirs->getIterator() as $dir) {
$sites[] = $dir->getRelativePathname();
}
Expand Down
55 changes: 55 additions & 0 deletions src/Robo/Datastore/DataStoreInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Acquia\Blt\Robo\Datastore;

/**
* Interface DataStoreInterface.
*/
interface DataStoreInterface {

/**
* Reads retrieves data from the store.
*
* @param string $key
* A key.
*
* @return mixed The value fpr the given key or null.
*/
public function get($key);

/**
* Saves a value with the given key.
*
* @param string $key
* A key.
* @param mixed $data
* Data to save to the store.
*/
public function set($key, $data);

/**
* Checks if a key is in the store.
*
* @param string $key
* A key.
*
* @return bool Whether a value exists with the given key
*/
public function has($key);

/**
* Remove value from the store.
*
* @param string $key
* A key.
*/
public function remove($key);

/**
* Return a list of all keys in the store.
*
* @return array A list of keys
*/
public function keys();

}
158 changes: 158 additions & 0 deletions src/Robo/Datastore/FileStore.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php

namespace Acquia\Blt\Robo\Datastore;

/**
* Class FileStore.
*/
class FileStore implements DataStoreInterface {
/**
* @var stringThedirectorytostorethedatafilesin
*/
protected $directory;

/**
*
*/
public function __construct($directory) {
$this->directory = $directory;
}

/**
* Reads retrieves data from the store.
*
* @param string $key
* A key.
*
* @return mixed The value fpr the given key or null.
*/
public function get($key) {
$out = NULL;
// Read the json encoded value from disk if it exists.
$path = $this->getFileName($key);
if (file_exists($path)) {
$out = file_get_contents($path);
$out = json_decode($out, TRUE);
}
return $out;
}

/**
* Saves a value with the given key.
*
* @param string $key
* A key.
* @param mixed $data
* Data to save to the store.
*/
public function set($key, $data) {
$path = $this->getFileName($key, TRUE);
file_put_contents($path, json_encode($data));
}

/**
* Checks if a key is in the store.
*
* @param string $key
* A key.
*
* @return bool Whether a value exists with the given key.
*/
public function has($key) {
$path = $this->getFileName($key);
return file_exists($path);
}

/**
* Remove value from the store.
*
* @param string $key
* A key.
*/
public function remove($key) {
$path = $this->getFileName($key, TRUE);
if (file_exists($path)) {
unlink($path);
}
}

/**
* Remove all values from the store.
*/
public function removeAll() {
foreach ($this->keys() as $key) {
$this->remove($key);
}
}

/**
* Return a list of all keys in the store.
*
* @return array A list of keys
*/
public function keys() {
$root = $this->directory;
if (file_exists($root) && is_readable($root)) {
return array_diff(scandir($root), array('..', '.'));
}
return [];
}

/**
* Get a valid file name for the given key.
*
* @param string $key
* The data key to be written or read.
*
* @return string A file path
*
* @throws \Exception
*/
protected function getFileName($key, $writable = FALSE) {
$key = $this->cleanKey($key);

if ($writable) {
$this->ensureDirectoryWritable();
}

if (!$key) {
throw new \Exception('Could not save data to a file because it is missing an ID');
}
return $this->directory . '/' . $key;
}

/**
* Make the file path safe by whitelisting characters.
*
* This is a very naive approach to hashing but in practice this doesn't
* matter since this is only used for a few already safe keys.
*
* @param $key
*
* @return mixed
*/
protected function cleanKey($key) {
return preg_replace('/[^a-zA-Z0-9\-\_\@\.]/', '-', $key);
}

/**
* Check that the directory is writable and create it if we can.
*/
protected function ensureDirectoryWritable() {
// Reality check to prevent stomping on the local filesystem if there is
// something wrong with the config.
if (!$this->directory) {
throw new \Exception('Could not save data to a file because the path setting is mis-configured.');
}

$writable = is_dir($this->directory) || (!file_exists($this->directory) && @mkdir($this->directory, 0777, TRUE));
$writable = $writable && is_writable($this->directory);
if (!$writable) {
throw new \Exception(
'Could not save data to a file because the path {path} cannot be written to.',
['path' => $this->directory]
);
}
}

}
2 changes: 1 addition & 1 deletion src/Robo/Tasks/LoadTasks.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
trait LoadTasks {

/**
* @return DrushTask
* @return \Acquia\Blt\Robo\Tasks\DrushTask
*/
protected function taskDrush() {
return $this->task(DrushTask::class);
Expand Down