Skip to content
Snippets Groups Projects
Commit 3530751a authored by totten's avatar totten
Browse files

GenCode - Add an optional caching mode.

If CIVICRM_GENCODE_DIGEST is set, then GenCode will write out a digest of
all its inputs & templates. If someone tries to rerun with the same inputs,
then GenCode will do nothing.
parent 40c85a44
No related branches found
No related tags found
No related merge requests found
......@@ -11,11 +11,24 @@ class CRM_Core_CodeGen_Main {
var $tplCodePath;
var $schemaPath; // ex: schema/Schema.xml
function __construct($CoreDAOCodePath, $sqlCodePath, $phpCodePath, $tplCodePath, $smartyPluginDirs, $argCms, $argVersion, $schemaPath) {
/**
* @var string|NULL path in which to store a marker that indicates the last execution of
* GenCode. If a matching marker already exists, GenCode doesn't run.
*/
var $digestPath;
/**
* @var string|NULL a digest of the inputs to the code-generator (eg the properties and source files)
*/
var $digest;
function __construct($CoreDAOCodePath, $sqlCodePath, $phpCodePath, $tplCodePath, $smartyPluginDirs, $argCms, $argVersion, $schemaPath, $digestPath) {
$this->CoreDAOCodePath = $CoreDAOCodePath;
$this->sqlCodePath = $sqlCodePath;
$this->phpCodePath = $phpCodePath;
$this->tplCodePath = $tplCodePath;
$this->digestPath = $digestPath;
$this->digest = NULL;
// default cms is 'drupal', if not specified
$this->cms = isset($argCms) ? strtolower($argCms) : 'drupal';
......@@ -39,6 +52,16 @@ class CRM_Core_CodeGen_Main {
*
*/
function main() {
if (!empty($this->digestPath) && file_exists($this->digestPath)) {
if ($this->getDigest() === file_get_contents($this->digestPath)) {
echo "GenCode has previously executed. To force execution, please (a) omit CIVICRM_GENCODE_DIGEST\n";
echo "or (b) remove {$this->digestPath} or (c) call GenCode with new parameters.\n";
exit();
}
// Once we start GenCode, the old build is invalid
unlink($this->digestPath);
}
echo "\ncivicrm_domain.version := ". $this->db_version . "\n\n";
if ($this->buildVersion < 1.1) {
echo "The Database is not compatible for this version";
......@@ -62,18 +85,15 @@ Alternatively you can get a version of CiviCRM that matches your PHP version
$this->tables = $specification->tables;
$this->runAllTasks();
if (!empty($this->digestPath)) {
file_put_contents($this->digestPath, $this->getDigest());
}
}
function runAllTasks() {
// TODO: This configuration can be manipulated dynamically.
$components = array(
'CRM_Core_CodeGen_Config',
'CRM_Core_CodeGen_Reflection',
'CRM_Core_CodeGen_Schema',
'CRM_Core_CodeGen_DAO',
'CRM_Core_CodeGen_Test',
'CRM_Core_CodeGen_I18n',
);
$components = $this->getTasks();
foreach ($components as $component) {
$task = new $component($this);
......@@ -86,4 +106,53 @@ Alternatively you can get a version of CiviCRM that matches your PHP version
}
}
}
/**
* @return array of class names; each class implements CRM_Core_CodeGen_ITask
*/
public function getTasks() {
$components = array(
'CRM_Core_CodeGen_Config',
'CRM_Core_CodeGen_Reflection',
'CRM_Core_CodeGen_Schema',
'CRM_Core_CodeGen_DAO',
'CRM_Core_CodeGen_Test',
'CRM_Core_CodeGen_I18n',
);
return $components;
}
/**
* Compute a digest based on the inputs to the code-generator (ie the properties
* of the codegen and the source files loaded by the codegen).
*
* @return string
*/
function getDigest() {
if ($this->digest === NULL) {
$srcDir = CRM_Core_CodeGen_Util_File::findCoreSourceDir();
$files = CRM_Core_CodeGen_Util_File::findManyFiles(array(
array("$srcDir/CRM/Core/CodeGen", '*.php'),
array("$srcDir/xml", "*.php"),
array("$srcDir/xml", "*.tpl"),
array("$srcDir/xml", "*.xml"),
));
$properties = var_export(array(
CRM_Core_CodeGen_Util_File::digestAll($files),
$this->buildVersion,
$this->db_version,
$this->cms,
$this->CoreDAOCodePath,
$this->sqlCodePath,
$this->phpCodePath,
$this->tplCodePath,
$this->schemaPath,
$this->getTasks(),
), TRUE);
$this->digest = md5($properties);
}
return $this->digest;
}
}
......@@ -31,4 +31,50 @@ class CRM_Core_CodeGen_Util_File {
return $newTempDir;
}
/**
* Calculate a cumulative digest based on a collection of files
*
* @param array $files list of file names (strings)
* @param callable $digest a one-way hash function (string => string)
* @return string
*/
static function digestAll($files, $digest = 'md5') {
$buffer = '';
foreach ($files as $file) {
$buffer .= $digest(file_get_contents($file));
}
return $digest($buffer);
}
/**
* Find the paths to all key files involved in the gen-code process
*
* @return array
* @throws RuntimeException
*/
static function findCoreSourceDir() {
$path = str_replace(DIRECTORY_SEPARATOR, '/', __DIR__);
if (!preg_match(':(.*)/CRM/Core/CodeGen/Util:', $path, $matches)) {
throw new RuntimeException("Failed to determine path of code-gen");
}
return $matches[1];
}
/**
* Find files in several directories using several filename patterns
*
*
* @param array $pairs each item is an array(0 => $searchBaseDir, 1 => $filePattern)
* @return array of file paths
*/
static function findManyFiles($pairs) {
$files = array();
foreach ($pairs as $pair) {
list ($dir, $pattern) = $pair;
$files = array_merge($files, CRM_Utils_File::findFiles($dir, $pattern));
}
return $files;
}
}
......@@ -29,6 +29,7 @@ $genCode = new CRM_Core_CodeGen_Main(
array('../packages/Smarty/plugins', '../CRM/Core/Smarty/plugins'), // smarty plugin dirs
@$argv[3], // cms
empty($argv[2]) ? NULL : $argv[2], // db version
empty($argv[1]) ? 'schema/Schema.xml' : $argv[1] // schem afile
empty($argv[1]) ? 'schema/Schema.xml' : $argv[1], // schem afile
getenv('CIVICRM_GENCODE_DIGEST') ? getenv('CIVICRM_GENCODE_DIGEST') : NULL
);
$genCode->main();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment