Example #1
0
/**
 * This is a helper function that just contains a block of code that needs to be
 * executed from two different places in this script. Consider it more as C macro
 * than a real function.
 */
function amos_parse_core_commit()
{
    global $DB;
    global $stage, $realmodified, $timemodified, $commitmsg, $committer, $committeremail, $commithash, $version, $fullcommitmsg, $startatlock, $affected;
    // if there is nothing to do, just store the last hash processed and return
    // this is typical for git commits that do not touch any lang file
    if (!$stage->has_component()) {
        file_put_contents($startatlock, $commithash);
        return;
    }
    if (empty($commithash)) {
        throw new coding_exception('When storing strings from a git commit, the hash must be provided');
    }
    // this is a hacky check to make sure that the git commit has not been processed already
    // this helps to prevent situations when a commit is reverted and AMOS is adding
    // and removing strings in sort of loop
    if ($DB->record_exists('amos_commits', array('source' => 'git', 'commithash' => $commithash))) {
        $stage->clear();
        fputs(STDOUT, "SKIP {$commithash} has already been processed before\n");
        file_put_contents($startatlock, $commithash);
        return;
    }
    // rebase the stage so that it contains just real modifications of strings
    $stage->rebase($timemodified, true, $timemodified);
    // make sure that the strings to be removed are really affected by the commit
    foreach ($stage->get_iterator() as $component) {
        foreach ($component->get_iterator() as $string) {
            if (!isset($affected[$component->name][$string->id])) {
                $component->unlink_string($string->id);
            }
        }
    }
    // rebase again to get rid of eventually empty components that were
    // left after removing unaffected strings
    $stage->rebase($timemodified, false);
    // if there is nothing to do now, just store the last has processed and return.
    // this is typical for git commits that touch some lang file but they do not actually
    // modify any string. Note that we do not execute AMOScript in this situation.
    if (!$stage->has_component()) {
        fputs(STDOUT, "NOOP {$commithash} does not introduce any string change\n");
        file_put_contents($startatlock, $commithash);
        return;
    }
    // ok so it seems we finally have something to do here! let's spam the world first
    amos_core_commit_notify($stage, $commitmsg, $committer, $committeremail, $commithash, $fullcommitmsg);
    // actually commit the changes
    $stage->commit($commitmsg, array('source' => 'git', 'userinfo' => $committer . ' <' . $committeremail . '>', 'commithash' => $commithash), true, $timemodified);
    // execute AMOS script if the commit message contains some
    if ($version->code >= mlang_version::MOODLE_20) {
        $instructions = mlang_tools::extract_script_from_text($fullcommitmsg);
        if (!empty($instructions)) {
            foreach ($instructions as $instruction) {
                fputs(STDOUT, "EXEC {$instruction}\n");
                $changes = mlang_tools::execute($instruction, $version, $timemodified);
                if ($changes instanceof mlang_stage) {
                    $changes->rebase($timemodified);
                    $changes->commit($commitmsg, array('source' => 'commitscript', 'userinfo' => $committer . ' <' . $committeremail . '>', 'commithash' => $commithash), true, $timemodified);
                } elseif ($changes < 0) {
                    fputs(STDERR, "EXEC STATUS {$changes}\n");
                }
                unset($changes);
            }
        }
    }
    // remember the processed commithash
    file_put_contents($startatlock, $commithash);
}
Example #2
0
require_once dirname(__FILE__) . '/locallib.php';
require_once dirname(__FILE__) . '/mlanglib.php';
require_once dirname(__FILE__) . '/execute_form.php';
require_login(SITEID, false);
require_capability('local/amos:execute', get_system_context());
require_capability('local/amos:stage', get_system_context());
$PAGE->set_pagelayout('standard');
$PAGE->set_url('/local/amos/execute.php');
navigation_node::override_active_url(new moodle_url('/local/amos/stage.php'));
$PAGE->set_title('AMOS ' . get_string('scriptexecute', 'local_amos'));
$PAGE->set_heading('AMOS ' . get_string('scriptexecute', 'local_amos'));
$executeform = new local_amos_execute_form(null, local_amos_execute_options());
if ($data = $executeform->get_data()) {
    $version = mlang_version::by_code($data->version);
    $stage = mlang_persistent_stage::instance_for_user($USER->id, sesskey());
    $instructions = mlang_tools::extract_script_from_text($data->script);
    if (!empty($instructions)) {
        foreach ($instructions as $instruction) {
            $changes = mlang_tools::execute($instruction, $version);
            if ($changes instanceof mlang_stage) {
                foreach ($changes->get_iterator() as $component) {
                    $stage->add($component, true);
                }
                $changes->clear();
            } elseif ($changes < 0) {
                throw new moodle_exception('error_during_amoscript_execution', 'local_amos', '', null, $changes);
            }
            unset($changes);
        }
    }
    $stage->rebase();
Example #3
0
    public function test_execution_strings_move()
    {
        $stage = new mlang_stage();
        $version = mlang_version::by_branch('MOODLE_20_STABLE');
        $now = time();
        // this block emulates parse-core.php
        $component = new mlang_component('admin', 'en', $version);
        $component->add_string(new mlang_string('configsitepolicy', 'OLD', $now - 2));
        $stage->add($component);
        $stage->rebase($now - 2, true, $now - 2);
        $stage->commit('Committed initial English string', array('source' => 'unittest'), true, $now - 2);
        $component->clear();
        unset($component);
        // this block emulates parse-lang.php
        $component = new mlang_component('admin', 'cs', $version);
        $component->add_string(new mlang_string('configsitepolicy', 'OLD in cs', $now - 1));
        $stage->add($component);
        $stage->rebase();
        $stage->commit('Committed initial Czech translation', array('source' => 'unittest'), true, $now - 1);
        $component->clear();
        unset($component);
        // this block emulates parse-core.php again later
        // now the string is moved in the English pack by the developer who provides AMOS script in commit message
        // this happened in b593d49d593ee778f525b4074f5ee7978c5e2960
        $component = new mlang_component('admin', 'en', $version);
        $component->add_string(new mlang_string('sitepolicy_help', 'NEW', $now));
        $component->add_string(new mlang_string('configsitepolicy', 'OLD', $now, true));
        $commitmsg = 'MDL-24570 multiple sitepolicy fixes + adding new separate guest user policy
AMOS BEGIN
 MOV [configsitepolicy,core_admin],[sitepolicy_help,core_admin]
AMOS END';
        $stage->add($component);
        $stage->rebase($now, true, $now);
        $stage->commit($commitmsg, array('source' => 'unittest'), true, $now);
        $component->clear();
        unset($component);
        // execute AMOS script if the commit message contains some
        if ($version->code >= mlang_version::MOODLE_20) {
            $instructions = mlang_tools::extract_script_from_text($commitmsg);
            if (!empty($instructions)) {
                foreach ($instructions as $instruction) {
                    $changes = mlang_tools::execute($instruction, $version, $now);
                    $changes->rebase($now);
                    $changes->commit($commitmsg, array('source' => 'commitscript'), true, $now);
                    unset($changes);
                }
            }
        }
        // check the results
        $component = mlang_component::from_snapshot('admin', 'cs', $version, $now);
        $this->assertTrue($component->has_string('sitepolicy_help'));
        $this->assertEqual('OLD in cs', $component->get_string('sitepolicy_help')->text);
        $this->assertEqual(1, $component->get_number_of_strings());
    }