mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 08:56:36 +02:00
Merge branch 'MDL-81125-main-alt' of https://github.com/andrewnicols/moodle
This commit is contained in:
commit
bd9631bda5
154 changed files with 3231 additions and 137 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -56,3 +56,4 @@ moodle-plugin-ci.phar
|
||||||
.hugo_build.lock
|
.hugo_build.lock
|
||||||
phpcs.xml
|
phpcs.xml
|
||||||
jsconfig.json
|
jsconfig.json
|
||||||
|
UPGRADING-CURRENT.md
|
||||||
|
|
|
@ -40,9 +40,20 @@ const fetchComponentData = () => {
|
||||||
if (!Object.entries(componentData).length) {
|
if (!Object.entries(componentData).length) {
|
||||||
componentData.subsystems = {};
|
componentData.subsystems = {};
|
||||||
componentData.pathList = [];
|
componentData.pathList = [];
|
||||||
|
componentData.components = {};
|
||||||
|
componentData.standardComponents = {};
|
||||||
|
|
||||||
// Fetch the component definiitions from the distributed JSON file.
|
// Fetch the component definiitions from the distributed JSON file.
|
||||||
const components = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/components.json`));
|
const components = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/components.json`));
|
||||||
|
const pluginData = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/plugins.json`));
|
||||||
|
|
||||||
|
componentData.pluginTypes = components.plugintypes;
|
||||||
|
|
||||||
|
const standardPlugins = Object.entries(pluginData.standard).map(
|
||||||
|
([pluginType, pluginNames]) => {
|
||||||
|
return pluginNames.map(pluginName => `${pluginType}_${pluginName}`);
|
||||||
|
}
|
||||||
|
).reduce((acc, val) => acc.concat(val), []);
|
||||||
|
|
||||||
// Build the list of moodle subsystems.
|
// Build the list of moodle subsystems.
|
||||||
componentData.subsystems.lib = 'core';
|
componentData.subsystems.lib = 'core';
|
||||||
|
@ -55,8 +66,8 @@ const fetchComponentData = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The list of components incldues the list of subsystems.
|
// The list of components includes the list of subsystems.
|
||||||
componentData.components = componentData.subsystems;
|
componentData.components = {...componentData.subsystems};
|
||||||
|
|
||||||
// Go through each of the plugintypes.
|
// Go through each of the plugintypes.
|
||||||
Object.entries(components.plugintypes).forEach(([pluginType, pluginTypePath]) => {
|
Object.entries(components.plugintypes).forEach(([pluginType, pluginTypePath]) => {
|
||||||
|
@ -87,6 +98,20 @@ const fetchComponentData = () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Create a list of the standard subsystem and plugins.
|
||||||
|
componentData.standardComponents = Object.fromEntries(
|
||||||
|
Object.entries(componentData.components).filter(([, name]) => {
|
||||||
|
if (name === 'core' || name.startsWith('core_')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return standardPlugins.indexOf(name) !== -1;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
componentData.componentMapping = Object.fromEntries(
|
||||||
|
Object.entries(componentData.components).map(([path, name]) => [name, path])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return componentData;
|
return componentData;
|
||||||
|
|
110
.grunt/notes/src/components.mjs
Normal file
110
.grunt/notes/src/components.mjs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import * as Components from '../../components.js';
|
||||||
|
|
||||||
|
const componentData = Components.fetchComponentData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The standard components shipped with core Moodle.
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
export const standardComponents = componentData.standardComponents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All components of the current Moodle instance.
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
export const allComponents = componentData.components;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all components of the current Moodle instance.
|
||||||
|
*
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
export const getAllComponents = () => {
|
||||||
|
let components = new Map(Object.entries(componentData.pluginTypes).map(([value, path]) => ([path,{
|
||||||
|
path,
|
||||||
|
value,
|
||||||
|
name: `${value} (plugin type)`,
|
||||||
|
}])));
|
||||||
|
|
||||||
|
Object
|
||||||
|
.entries(componentData.components)
|
||||||
|
.filter(([path, value]) => Object.values(componentData.standardComponents).includes(value))
|
||||||
|
.forEach(([path, value]) => {
|
||||||
|
const entry = {
|
||||||
|
path,
|
||||||
|
value,
|
||||||
|
name: value,
|
||||||
|
};
|
||||||
|
if (Object.values(componentData.subsystems).includes(value)) {
|
||||||
|
if (components.has(path)) {
|
||||||
|
entry.name = `${value} (subsystem / plugintype)`;
|
||||||
|
} else {
|
||||||
|
entry.name = `${value} (subsystem)`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
components.set(path, entry);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Array.from(components.values());
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the specified component is a standard component shipped with core Moodle.
|
||||||
|
*
|
||||||
|
* @param {string} componentName
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export const isStandardComponent = (componentName) => {
|
||||||
|
if (Object.values(componentData.standardComponents).includes(componentName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(componentData.pluginTypes).includes(componentName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const rewritePlugintypeAsSubsystem = (componentName) => {
|
||||||
|
if (Object.keys(componentData.pluginTypes).includes(componentName)) {
|
||||||
|
const pluginTypePath = componentData.pluginTypes[componentName];
|
||||||
|
if (Object.keys(componentData.subsystems).includes(pluginTypePath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the specified component is a community component.
|
||||||
|
*
|
||||||
|
* @param {string} componentName
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export const isCommunityComponent = (componentName) => {
|
||||||
|
if (isStandardComponent(componentName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.values(componentData.components).indexOf(componentName) !== -1;
|
||||||
|
}
|
85
.grunt/notes/src/create.mjs
Normal file
85
.grunt/notes/src/create.mjs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import inquirer from 'inquirer';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
|
||||||
|
import { createNote } from './note.mjs';
|
||||||
|
import { getInitialValues } from './helpers.mjs';
|
||||||
|
import * as Prompts from './prompts.mjs';
|
||||||
|
import logger from './logger.mjs';
|
||||||
|
|
||||||
|
export default async (options) => {
|
||||||
|
// Processs the initial values.
|
||||||
|
const initialValues = getInitialValues(options);
|
||||||
|
|
||||||
|
// Fetch information.
|
||||||
|
const messages = [];
|
||||||
|
const { issueNumber } = await inquirer.prompt([
|
||||||
|
Prompts.getIssuePrompt(),
|
||||||
|
], initialValues);
|
||||||
|
|
||||||
|
let selection = {};
|
||||||
|
let notePath;
|
||||||
|
do {
|
||||||
|
selection = {};
|
||||||
|
selection = await inquirer.prompt([
|
||||||
|
Prompts.getComponentsPrompt(),
|
||||||
|
Prompts.getTypePrompt(),
|
||||||
|
Prompts.getMessagePromptInput(),
|
||||||
|
], initialValues);
|
||||||
|
if (selection.message === '') {
|
||||||
|
selection = Object.assign(
|
||||||
|
selection,
|
||||||
|
await inquirer.prompt([
|
||||||
|
Prompts.getMessagePromptEditor(),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`
|
||||||
|
Creating upgrade note with the following options:
|
||||||
|
|
||||||
|
- Issue: ${chalk.bold(issueNumber)}
|
||||||
|
- Component: ${chalk.bold(selection.components)}
|
||||||
|
- Type: ${chalk.bold(selection.type)}
|
||||||
|
- Message:
|
||||||
|
${chalk.bold(selection.message)}
|
||||||
|
`);
|
||||||
|
|
||||||
|
messages.push({
|
||||||
|
components: [selection.components],
|
||||||
|
type: selection.type,
|
||||||
|
message: selection.message,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save the note so far.
|
||||||
|
if (notePath) {
|
||||||
|
await createNote(issueNumber, messages, notePath);
|
||||||
|
logger.info(`Updated note at: ${chalk.underline(chalk.bold(notePath))}`);
|
||||||
|
} else {
|
||||||
|
notePath = await createNote(issueNumber, messages);
|
||||||
|
logger.info(`Note created at: ${chalk.underline(chalk.bold(notePath))}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
selection = Object.assign(
|
||||||
|
selection,
|
||||||
|
await inquirer.prompt([
|
||||||
|
Prompts.getAddAnotherPrompt(),
|
||||||
|
], initialValues),
|
||||||
|
);
|
||||||
|
} while (selection.addAnother);
|
||||||
|
};
|
318
.grunt/notes/src/generate.mjs
Normal file
318
.grunt/notes/src/generate.mjs
Normal file
|
@ -0,0 +1,318 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import { getAllComponents } from './components.mjs';
|
||||||
|
import { getCombinedNotesByComponent, deleteAllNotes } from './note.mjs';
|
||||||
|
import { getNoteName } from './noteTypes.mjs';
|
||||||
|
import { writeFile, readFile, unlink } from 'fs/promises';
|
||||||
|
import { join as joinPath } from 'path';
|
||||||
|
import logger from './logger.mjs';
|
||||||
|
import { getCurrentVersion } from './helpers.mjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to fetch the current notes from a file.
|
||||||
|
*
|
||||||
|
* @param {string} file
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
const getCurrentNotes = async (file) => {
|
||||||
|
try {
|
||||||
|
return await readFile(file, 'utf8');
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the UPGRADING.md file.
|
||||||
|
*
|
||||||
|
* @param {string} upgradeNotes
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {boolean} options.deleteNotes
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
const updateUpgradeNotes = async (upgradeNotes, options) => {
|
||||||
|
const fileName = 'UPGRADING.md';
|
||||||
|
// Write the notes to a file.
|
||||||
|
logger.info(`Writing notes to ${chalk.underline(chalk.bold(fileName))}`);
|
||||||
|
// Prepend to the existing file.
|
||||||
|
const existingContent = await getCurrentNotes(fileName);
|
||||||
|
if (existingContent) {
|
||||||
|
await writeFile(fileName, getUpdatedNotes(existingContent, upgradeNotes));
|
||||||
|
} else {
|
||||||
|
// This should not normally happen.
|
||||||
|
await writeFile(fileName, upgradeNotes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.deleteNotes) {
|
||||||
|
logger.warn(`>>> Deleting all notes <<<`)
|
||||||
|
// Delete the notes.
|
||||||
|
deleteAllNotes();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the current summary notes.
|
||||||
|
*
|
||||||
|
* @param {string} upgradeNotes
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
const createCurrentSummary = async (upgradeNotes) => {
|
||||||
|
const fileName = 'UPGRADING-CURRENT.md';
|
||||||
|
const notes = `# Moodle upgrade notes\n\n${upgradeNotes}`;
|
||||||
|
await writeFile(fileName, notes);
|
||||||
|
|
||||||
|
logger.info(`Running upgrade notes written to ${chalk.underline(chalk.bold(fileName))}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the indexes of the lines that contain the version headings.
|
||||||
|
*
|
||||||
|
* @param {array<string>} lines
|
||||||
|
* @returns {array<object>}
|
||||||
|
*/
|
||||||
|
const getVersionLineIndexes = (lines) => {
|
||||||
|
const h2Indexes = [];
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
const matches = line.match(/^##\s(?<version>.*)$/);
|
||||||
|
if (matches) {
|
||||||
|
h2Indexes.push({
|
||||||
|
index,
|
||||||
|
line,
|
||||||
|
version: matches.groups.version,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return h2Indexes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the index of the Unreleased heading.
|
||||||
|
*
|
||||||
|
* @param {array<object>} versionHeadings
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
const findUnreleasedHeadingIndex = (versionHeadings) => versionHeadings.findIndex((heading) => {
|
||||||
|
if (heading.version === 'Unreleased') {
|
||||||
|
// Used if version cannot be guessed.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (heading.version.endsWith('+')) {
|
||||||
|
// Weekly release for a stable branch.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (heading.version.match(/beta|rc\d/)) {
|
||||||
|
// Beta and RC rolls are treated as weeklies.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (heading.version.endsWith('dev')) {
|
||||||
|
// Development version.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the before and after content, to facilitate replacing any existing Unreleased notes.
|
||||||
|
*
|
||||||
|
* @param {array<string>} lines
|
||||||
|
* @returns {Object} {beforeContent: string, afterContent: string}
|
||||||
|
*/
|
||||||
|
const getBeforeAndAfterContent = (lines) => {
|
||||||
|
const existingLines = lines.split('\n');
|
||||||
|
const versionHeadings = getVersionLineIndexes(existingLines);
|
||||||
|
|
||||||
|
if (versionHeadings.length > 0) {
|
||||||
|
const unreleasedHeadingIndex = findUnreleasedHeadingIndex(versionHeadings);
|
||||||
|
if (unreleasedHeadingIndex !== -1) {
|
||||||
|
const beforeContent = existingLines.slice(0, versionHeadings[unreleasedHeadingIndex].index).join('\n');
|
||||||
|
if (versionHeadings.length > unreleasedHeadingIndex + 1) {
|
||||||
|
const afterContent = existingLines.slice(versionHeadings[unreleasedHeadingIndex + 1].index).join('\n');
|
||||||
|
return {
|
||||||
|
beforeContent,
|
||||||
|
afterContent,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
beforeContent,
|
||||||
|
afterContent: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
beforeContent: existingLines.slice(0, versionHeadings[0].index).join('\n'),
|
||||||
|
afterContent: existingLines.slice(versionHeadings[0].index).join('\n'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
beforeContent: existingLines.join('\n'),
|
||||||
|
afterContent: '',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the notes for the component.
|
||||||
|
*
|
||||||
|
* @param {string} type
|
||||||
|
* @param {Number} headingLevel
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
const getNotesForComponent = (types, headingLevel) => {
|
||||||
|
let upgradeNotes = '';
|
||||||
|
Object.entries(types).forEach(([type, notes]) => {
|
||||||
|
upgradeNotes += '#'.repeat(headingLevel);
|
||||||
|
upgradeNotes += ` ${getNoteName(type)}\n\n`;
|
||||||
|
notes.forEach(({ message, issueNumber }) => {
|
||||||
|
// Split the message into lines, removing empty lines.
|
||||||
|
const messageLines = message
|
||||||
|
.split('\n')
|
||||||
|
.filter((line) => line.trim().length > 0);
|
||||||
|
|
||||||
|
const firstLine = messageLines.shift().trim();
|
||||||
|
upgradeNotes += `- ${firstLine}\n`;
|
||||||
|
|
||||||
|
messageLines
|
||||||
|
.forEach((line) => {
|
||||||
|
upgradeNotes += ` ${line.trimEnd()}\n`;
|
||||||
|
});
|
||||||
|
upgradeNotes += `\n For more information see [${issueNumber}](https://tracker.moodle.org/browse/${issueNumber})\n`;
|
||||||
|
});
|
||||||
|
upgradeNotes += '\n';
|
||||||
|
});
|
||||||
|
|
||||||
|
return upgradeNotes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the updated notes mixed with existing content.
|
||||||
|
*
|
||||||
|
* @param {string} existingContent
|
||||||
|
* @param {string} upgradeNotes
|
||||||
|
*/
|
||||||
|
const getUpdatedNotes = (existingContent, upgradeNotes) => {
|
||||||
|
const { beforeContent, afterContent } = getBeforeAndAfterContent(existingContent);
|
||||||
|
const newContent = `${beforeContent}\n${upgradeNotes}\n${afterContent}`
|
||||||
|
.split('\n')
|
||||||
|
.filter((line, index, lines) => {
|
||||||
|
if (line === '' && lines[index - 1] === '') {
|
||||||
|
// Remove multiple consecutive empty lines.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
|
return newContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the notes for each component.
|
||||||
|
*/
|
||||||
|
const updateComponentNotes = (
|
||||||
|
notes,
|
||||||
|
version,
|
||||||
|
notesFileName = 'UPGRADING.md',
|
||||||
|
removeEmpty = false,
|
||||||
|
) => {
|
||||||
|
return getAllComponents().map(async (component) => {
|
||||||
|
logger.verbose(`Updating notes for ${component.name} into ${component.path}`);
|
||||||
|
const fileName = joinPath(component.path, notesFileName);
|
||||||
|
|
||||||
|
const existingContent = await getCurrentNotes(fileName);
|
||||||
|
|
||||||
|
if (!existingContent) {
|
||||||
|
if (!notes[component.value]) {
|
||||||
|
// No existing notes, and no new notes to add.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!notes[component.value]) {
|
||||||
|
// There is existing content, but nothing to add.
|
||||||
|
if (removeEmpty) {
|
||||||
|
logger.verbose(`Removing empty notes file ${fileName}`);
|
||||||
|
await unlink(fileName);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const componentNotes = notes[component.value];
|
||||||
|
let upgradeNotes = `## ${version}\n\n`;
|
||||||
|
upgradeNotes += getNotesForComponent(componentNotes, 3);
|
||||||
|
|
||||||
|
if (existingContent) {
|
||||||
|
await writeFile(fileName, getUpdatedNotes(existingContent, upgradeNotes));
|
||||||
|
} else {
|
||||||
|
await writeFile(
|
||||||
|
fileName,
|
||||||
|
`# ${component.name} Upgrade notes\n\n${upgradeNotes}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the upgrade notes for a new release.
|
||||||
|
*
|
||||||
|
* @param {string|undefined} version
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {boolean} options.generateUpgradeNotes
|
||||||
|
* @param {boolean} options.deleteNotes
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
export default async (version, options = {}) => {
|
||||||
|
const notes = await getCombinedNotesByComponent();
|
||||||
|
|
||||||
|
if (Object.keys(notes).length === 0) {
|
||||||
|
logger.warn('No notes to generate');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!version) {
|
||||||
|
version = await getCurrentVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the upgrade notes for this release.
|
||||||
|
// We have
|
||||||
|
// - a title with the release name
|
||||||
|
// - the change types
|
||||||
|
// - which contain the components
|
||||||
|
// - which document each changev
|
||||||
|
let upgradeNotes = `## ${version}\n\n`;
|
||||||
|
|
||||||
|
Object.entries(notes).forEach(([component, types]) => {
|
||||||
|
upgradeNotes += `### ${component}\n\n`;
|
||||||
|
upgradeNotes += getNotesForComponent(types, 4);
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
createCurrentSummary(upgradeNotes),
|
||||||
|
...updateComponentNotes(notes, version, 'UPGRADING-CURRENT.md', true),
|
||||||
|
]);
|
||||||
|
if (options.generateUpgradeNotes) {
|
||||||
|
await Promise.all(updateComponentNotes(notes, version));
|
||||||
|
await updateUpgradeNotes(upgradeNotes, options);
|
||||||
|
}
|
||||||
|
};
|
230
.grunt/notes/src/helpers.mjs
Normal file
230
.grunt/notes/src/helpers.mjs
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import { isStandardComponent, isCommunityComponent, rewritePlugintypeAsSubsystem } from './components.mjs';
|
||||||
|
import { isValidNoteName } from './noteTypes.mjs';
|
||||||
|
import logger from './logger.mjs';
|
||||||
|
import { readFile } from 'fs/promises';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate an issue number input
|
||||||
|
*
|
||||||
|
* @param {string} input
|
||||||
|
* @returns {string|boolean}
|
||||||
|
*/
|
||||||
|
export const validateIssueNumber = (input) => {
|
||||||
|
if (!input) {
|
||||||
|
return 'You must provide a tracker issue number';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.match(/^[a-zA-Z]*-\d+$/)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.match(/^\d+$/)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'The issue number was not recognised as a valid issue number';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format an issue number input.
|
||||||
|
*
|
||||||
|
* @param {string} input
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const formatIssueNumber = (input) => {
|
||||||
|
if (input.match(/^[a-zA-Z]*-\d+$/)) {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.match(/^\d+$/)) {
|
||||||
|
return `MDL-${input}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a component.
|
||||||
|
*
|
||||||
|
* @param {string} input
|
||||||
|
* @returns {string|boolean}
|
||||||
|
*/
|
||||||
|
export const validateComponent = (input) => {
|
||||||
|
if (isStandardComponent(input)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCommunityComponent(input)) {
|
||||||
|
return 'Currently only core plugins are supported.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'The component was not recognised as a standard component';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const formatComponent = (input) => {
|
||||||
|
if (rewritePlugintypeAsSubsystem(input)) {
|
||||||
|
return `core_${input}`;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the initial values from the options.
|
||||||
|
*
|
||||||
|
* @param {object} options
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
export const getInitialValues = (options) => {
|
||||||
|
const initialValues = {};
|
||||||
|
|
||||||
|
const type = getInitialTypeValue(options);
|
||||||
|
if (type) {
|
||||||
|
initialValues.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueNumber = getInitialIssueValue(options);
|
||||||
|
if (issueNumber) {
|
||||||
|
initialValues.issueNumber = issueNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
const component = getInitialComponentValue(options);
|
||||||
|
if (component) {
|
||||||
|
initialValues.components = component;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = getInitialMessageValue(options);
|
||||||
|
if (message) {
|
||||||
|
initialValues.message = message
|
||||||
|
initialValues.addAnother = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the initial type value.
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @returns {string|undefined}
|
||||||
|
*/
|
||||||
|
const getInitialTypeValue = (options) => {
|
||||||
|
if (!options.type) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
options.type = options.type.trim().toLowerCase();
|
||||||
|
|
||||||
|
if (isValidNoteName(options.type)) {
|
||||||
|
return options.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warn(`Note type "${chalk.underline(chalk.red(options.type))}" is not valid.`);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the initial issue number value.
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @returns {string|undefined}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const getInitialIssueValue = (options) => {
|
||||||
|
if (!options.issue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
options.issue = options.issue.trim().toUpperCase();
|
||||||
|
|
||||||
|
const issueNumberValidated = validateIssueNumber(options.issue);
|
||||||
|
if (issueNumberValidated === true) {
|
||||||
|
const issueNumber = formatIssueNumber(options.issue);
|
||||||
|
if (issueNumber !== options.issue) {
|
||||||
|
logger.warn(
|
||||||
|
`Issue number "${chalk.underline(chalk.red(options.issue))}" was updated to ` +
|
||||||
|
`"${chalk.underline(chalk.green(issueNumber))}"`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return issueNumber;
|
||||||
|
} else {
|
||||||
|
logger.warn(`Issue number "${chalk.underline(chalk.red(options.issue))}" is not valid: ${issueNumberValidated}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the initial component value.
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @returns {string|undefined}
|
||||||
|
*/
|
||||||
|
const getInitialComponentValue = (options) => {
|
||||||
|
if (!options.component) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
options.component = options.component.trim().toLowerCase();
|
||||||
|
const componentValidated = validateComponent(options.component);
|
||||||
|
if (componentValidated === true) {
|
||||||
|
const component = formatComponent(options.component);
|
||||||
|
if (component !== options.component) {
|
||||||
|
logger.warn(
|
||||||
|
`Component "${chalk.underline(chalk.red(options.component))}" was updated to ` +
|
||||||
|
`"${chalk.underline(chalk.green(component))}"`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return component;
|
||||||
|
} else {
|
||||||
|
logger.warn(`Component "${chalk.underline(chalk.red(options.component))}" is not valid: ${componentValidated}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the initial message value.
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @returns {string|undefined}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const getInitialMessageValue = (options) => {
|
||||||
|
if (!options.message) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return options.message.trim();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current version from the project /version.php file.
|
||||||
|
*
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
export const getCurrentVersion = async () => {
|
||||||
|
const versionRegex = new RegExp(/^ *\$release *= *['\"](?<release>[^ \+]+\+?) *\(Build:.*/m);
|
||||||
|
try {
|
||||||
|
const versionFile = await readFile('version.php', 'utf8');
|
||||||
|
const match = versionFile.match(versionRegex);
|
||||||
|
if (match) {
|
||||||
|
return match.groups.release;
|
||||||
|
}
|
||||||
|
} catch(error) {
|
||||||
|
logger.error('Unable to read the version file');
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unreleased";
|
||||||
|
}
|
30
.grunt/notes/src/logger.mjs
Normal file
30
.grunt/notes/src/logger.mjs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import winston from 'winston';
|
||||||
|
|
||||||
|
const logger = winston.createLogger({
|
||||||
|
level: 'info',
|
||||||
|
format: winston.format.combine(
|
||||||
|
winston.format.colorize(),
|
||||||
|
winston.format.simple()
|
||||||
|
),
|
||||||
|
transports: [
|
||||||
|
new winston.transports.Console(),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
export default logger;
|
183
.grunt/notes/src/note.mjs
Normal file
183
.grunt/notes/src/note.mjs
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import yaml from 'js-yaml';
|
||||||
|
import path from 'path';
|
||||||
|
import { writeFile, mkdir, readdir, readFile, unlink } from 'fs/promises';
|
||||||
|
import { isValidNoteName } from './noteTypes.mjs';
|
||||||
|
|
||||||
|
const unreleasedPath = path.resolve('.upgradenotes');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the filename for the note.
|
||||||
|
*
|
||||||
|
* @param {string} issueNumnber The issue number
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
const getFilename = (issueNumber) => {
|
||||||
|
const dateTimeFormat = new Intl.DateTimeFormat(undefined, {
|
||||||
|
year: 'numeric',
|
||||||
|
month: '2-digit',
|
||||||
|
day: '2-digit',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
fractionalSecondDigits: 2,
|
||||||
|
timeZone: 'UTC',
|
||||||
|
});
|
||||||
|
|
||||||
|
const date = Object.fromEntries(
|
||||||
|
dateTimeFormat.formatToParts(new Date())
|
||||||
|
.filter((p) => p.type !== 'literal')
|
||||||
|
.map((p) => ([p.type, p.value]))
|
||||||
|
);
|
||||||
|
|
||||||
|
const dateString = [
|
||||||
|
date.year,
|
||||||
|
date.month,
|
||||||
|
date.day,
|
||||||
|
date.hour,
|
||||||
|
date.minute,
|
||||||
|
date.second,
|
||||||
|
date.fractionalSecond,
|
||||||
|
].join('');
|
||||||
|
|
||||||
|
return `${issueNumber}-${dateString}.yml`;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new note.
|
||||||
|
*
|
||||||
|
* @param {string} issueNumber
|
||||||
|
* @param {[type: string]: {message: string}} messages
|
||||||
|
* @returns {string} The path to the note on disk
|
||||||
|
*/
|
||||||
|
export const createNote = async (
|
||||||
|
issueNumber,
|
||||||
|
messages,
|
||||||
|
notePath,
|
||||||
|
) => {
|
||||||
|
const note = {
|
||||||
|
issueNumber,
|
||||||
|
notes: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
messages.forEach(({components, type, message}) => {
|
||||||
|
note.notes[components] = note.notes[components] || [];
|
||||||
|
note.notes[components].push({message, type});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!notePath) {
|
||||||
|
notePath = path.resolve(unreleasedPath, getFilename(issueNumber));
|
||||||
|
}
|
||||||
|
const noteContent = yaml.dump(note);
|
||||||
|
|
||||||
|
await mkdir(unreleasedPath, {recursive: true});
|
||||||
|
await writeFile(notePath, noteContent);
|
||||||
|
|
||||||
|
return notePath;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all unreleased notes.
|
||||||
|
*
|
||||||
|
* @returns {Promise<{issueNumber: string, components: string[], types: {[type: string]: {message: string}[]}}[]>
|
||||||
|
*/
|
||||||
|
export const getAllNotes = async () => {
|
||||||
|
const files = await readdir(unreleasedPath);
|
||||||
|
const notes = files
|
||||||
|
.filter((file) => file.endsWith('.yml'))
|
||||||
|
.map(async (file) => {
|
||||||
|
const filePath = path.resolve(unreleasedPath, file);
|
||||||
|
const fileContent = await readFile(filePath, 'utf8');
|
||||||
|
|
||||||
|
return {
|
||||||
|
...yaml.load(fileContent),
|
||||||
|
filePath,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return Promise.all(notes);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of notes, grouped by note type, then component.
|
||||||
|
*
|
||||||
|
* @returns {Promise<{[type: string]: {[components: string]: {message: string, issueNumber: string}[]}}>}
|
||||||
|
*/
|
||||||
|
export const getCombinedNotes = async () => {
|
||||||
|
const notes = await getAllNotes();
|
||||||
|
const combinedNotes = {};
|
||||||
|
|
||||||
|
notes.forEach((note) => {
|
||||||
|
Object.entries(note.notes).forEach(([components, data]) => {
|
||||||
|
data.forEach((entry) => {
|
||||||
|
if (!isValidNoteName(entry.type)) {
|
||||||
|
throw new Error(`Invalid note type: "${entry.type}" in file ${note.filePath}`);
|
||||||
|
}
|
||||||
|
combinedNotes[entry.type] = combinedNotes[entry.type] || {};
|
||||||
|
combinedNotes[entry.type][components] = combinedNotes[entry.type][components] || [];
|
||||||
|
combinedNotes[entry.type][components].push({message: entry.message, issueNumber: note.issueNumber});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return combinedNotes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of notes, grouped by component, then by note type.
|
||||||
|
*
|
||||||
|
* @returns {Promise<{[component: string]: {[type: string]: {message: string, issueNumber: string}[]}}>}
|
||||||
|
*/
|
||||||
|
export const getCombinedNotesByComponent = async () => {
|
||||||
|
const notes = await getAllNotes();
|
||||||
|
const combinedNotes = {};
|
||||||
|
|
||||||
|
notes.forEach((note) => {
|
||||||
|
Object.entries(note.notes).forEach(([component, data]) => {
|
||||||
|
combinedNotes[component] = combinedNotes[component] || {};
|
||||||
|
data.forEach((entry) => {
|
||||||
|
if (!isValidNoteName(entry.type)) {
|
||||||
|
throw new Error(`Invalid note type: "${entry.type}" in file ${note.filePath}`);
|
||||||
|
}
|
||||||
|
combinedNotes[component][entry.type] = combinedNotes[component][entry.type] || [];
|
||||||
|
combinedNotes[component][entry.type].push({
|
||||||
|
component,
|
||||||
|
message: entry.message,
|
||||||
|
issueNumber: note.issueNumber,
|
||||||
|
type: entry.type,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return combinedNotes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all unreleased notes.
|
||||||
|
*
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
export const deleteAllNotes = async () => {
|
||||||
|
const files = await readdir(unreleasedPath);
|
||||||
|
return Promise.all(
|
||||||
|
files
|
||||||
|
.filter((item, index) => files.indexOf(item) === index)
|
||||||
|
.filter((file) => file.endsWith('.yml'))
|
||||||
|
.map((file) => unlink(`${unreleasedPath}/${file}`))
|
||||||
|
);
|
||||||
|
};
|
45
.grunt/notes/src/noteTypes.mjs
Normal file
45
.grunt/notes/src/noteTypes.mjs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
const noteTypes = {
|
||||||
|
'improved': 'Added',
|
||||||
|
'removed': 'Removed',
|
||||||
|
'changed': 'Changed',
|
||||||
|
'deprecated': 'Deprecated',
|
||||||
|
'fixed': 'Fixed',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the note names.
|
||||||
|
*
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
export const getNoteNames = () => Object.keys(noteTypes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the human-readable note name.
|
||||||
|
*
|
||||||
|
* @param {string} type
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const getNoteName = (type) => noteTypes[type];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the note name is valid.
|
||||||
|
*
|
||||||
|
* @param {string} type
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export const isValidNoteName = (type) => noteTypes[type] !== undefined;
|
153
.grunt/notes/src/prompts.mjs
Normal file
153
.grunt/notes/src/prompts.mjs
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import inquirer from 'inquirer';
|
||||||
|
import SearchList from 'inquirer-search-list';
|
||||||
|
|
||||||
|
import { getNoteNames } from './noteTypes.mjs';
|
||||||
|
import { getAllComponents } from './components.mjs';
|
||||||
|
import {
|
||||||
|
formatComponent,
|
||||||
|
formatIssueNumber,
|
||||||
|
validateComponent,
|
||||||
|
validateIssueNumber,
|
||||||
|
} from './helpers.mjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Search List which accepts an initial value.
|
||||||
|
*/
|
||||||
|
class SearchListWithInitialValue extends SearchList {
|
||||||
|
constructor(options, ...args) {
|
||||||
|
super(options, ...args);
|
||||||
|
|
||||||
|
if (options.default) {
|
||||||
|
const pointer = this.filterList.findIndex((item) => {
|
||||||
|
return item.value === options.default;
|
||||||
|
});
|
||||||
|
if (pointer > -1) {
|
||||||
|
this.pointer = pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inquirer.registerPrompt('search-list', SearchListWithInitialValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the issue type prompt.
|
||||||
|
*
|
||||||
|
* @param {string} defaultData The initially selected value
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
export const getTypePrompt = (defaultData) => ({
|
||||||
|
default: defaultData,
|
||||||
|
type: 'search-list',
|
||||||
|
message: 'Type of change',
|
||||||
|
name: 'type',
|
||||||
|
choices: getNoteNames(),
|
||||||
|
validate: (selection) => {
|
||||||
|
if (selection.length < 1) {
|
||||||
|
return 'You must select at least one type of change';
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the component prompt.
|
||||||
|
*
|
||||||
|
* @param {string} [defaultValue='core'] The initally selected value.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getComponentsPrompt = (defaultValue) => {
|
||||||
|
if (!defaultValue ) {
|
||||||
|
defaultValue = 'core';
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
choices: getAllComponents(),
|
||||||
|
default: defaultValue,
|
||||||
|
type: 'search-list',
|
||||||
|
message: 'Component',
|
||||||
|
name: 'components',
|
||||||
|
validate: validateComponent,
|
||||||
|
filter: formatComponent,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the issue number prompt as an inline input.
|
||||||
|
*
|
||||||
|
* @param {string} defaultData
|
||||||
|
* @returns {object}
|
||||||
|
*/
|
||||||
|
export const getIssuePrompt = (defaultData) => ({
|
||||||
|
default: defaultData,
|
||||||
|
type: 'input',
|
||||||
|
message: 'Tracker issue number',
|
||||||
|
name: 'issueNumber',
|
||||||
|
validate: validateIssueNumber,
|
||||||
|
filter: formatIssueNumber,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a message prompt.
|
||||||
|
*
|
||||||
|
* @param {string} defaultData
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getMessagePromptEditor = (defaultData) => ({
|
||||||
|
default: defaultData,
|
||||||
|
type: process.stdin.isTTY ? 'editor' : 'input',
|
||||||
|
postfix: '.md',
|
||||||
|
message: 'Message',
|
||||||
|
name: 'message',
|
||||||
|
waitUserInput: false,
|
||||||
|
validate: (input) => {
|
||||||
|
if (!input) {
|
||||||
|
return 'You must provide a message';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
// Remove any trailing whitespace.
|
||||||
|
filter: (input) => input.split('\n').map((line) => line.trimEnd()).join('\n'),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a message prompt.
|
||||||
|
*
|
||||||
|
* @param {string} defaultData
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getMessagePromptInput = (defaultData) => ({
|
||||||
|
default: defaultData,
|
||||||
|
type: 'input',
|
||||||
|
message: 'Message (leave empty to use editor)',
|
||||||
|
name: 'message',
|
||||||
|
filter: (input) => input.trim(),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a prompt to ask the user if they wish to add another entry.
|
||||||
|
*
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
export const getAddAnotherPrompt = () => ({
|
||||||
|
type: 'confirm',
|
||||||
|
message: 'Do you want to add another note?',
|
||||||
|
default: false,
|
||||||
|
name: 'addAnother',
|
||||||
|
});
|
103
.grunt/upgradenotes.mjs
Executable file
103
.grunt/upgradenotes.mjs
Executable file
|
@ -0,0 +1,103 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
// This file is part of Moodle - http://moodle.org/
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { Argument, Option, program } from 'commander';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
|
||||||
|
import { getNoteNames } from './notes/src/noteTypes.mjs';
|
||||||
|
import createAction from './notes/src/create.mjs';
|
||||||
|
import generateAction from './notes/src/generate.mjs';
|
||||||
|
import logger from './notes/src/logger.mjs';
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
${chalk.bold(chalk.underline(chalk.green('Moodle Upgrade Notes Generator')))}
|
||||||
|
|
||||||
|
This tool is used to generate the upgrade notes for changes you make in Moodle.
|
||||||
|
|
||||||
|
Please remember that the intended audience of these changes is
|
||||||
|
${chalk.italic('plugin developers')} who need to know how to update their plugins
|
||||||
|
for a new Moodle version.
|
||||||
|
|
||||||
|
Upgrade notes should not be used to document changes for site administrators, or
|
||||||
|
for internal API changes which are not expected to be used outside of the
|
||||||
|
relevant component.
|
||||||
|
`)
|
||||||
|
|
||||||
|
program.configureHelp({
|
||||||
|
helpWidth: 100,
|
||||||
|
});
|
||||||
|
|
||||||
|
program.on('option:verbose', () => {
|
||||||
|
logger.level = 'verbose';
|
||||||
|
});
|
||||||
|
|
||||||
|
program.addOption(
|
||||||
|
new Option(
|
||||||
|
'-v, --verbose',
|
||||||
|
'Output more information during the generation process',
|
||||||
|
)
|
||||||
|
.default(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Define the command line options.
|
||||||
|
program
|
||||||
|
.command('create')
|
||||||
|
.summary('Generate a new upgrade note')
|
||||||
|
.addOption(
|
||||||
|
new Option('-t, --type <type>', `The type of change to document. Valid types are: ${getNoteNames().join(', ')}`)
|
||||||
|
)
|
||||||
|
.addOption(new Option('-i, --issue <issue>', 'The tracker issue number'))
|
||||||
|
.addOption(new Option('-c, --component <component>', 'The component to write a note for'))
|
||||||
|
.addOption(new Option(
|
||||||
|
'-m, --message <message>',
|
||||||
|
'The message to use for the upgrade note',
|
||||||
|
))
|
||||||
|
.action((options) => createAction(options));
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('summary')
|
||||||
|
.summary('Generate a local copy of the upgrade notes summary')
|
||||||
|
.addArgument(
|
||||||
|
new Argument('[version]', 'The Moodle version to create the summary notes for')
|
||||||
|
)
|
||||||
|
.action((version) => generateAction(version));
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('release')
|
||||||
|
.summary('Generate the markdown copies of the upgrade notes for a Moodle release')
|
||||||
|
.addArgument(
|
||||||
|
new Argument('[version]', 'The Moodle version to create the release notes for')
|
||||||
|
)
|
||||||
|
.addOption(
|
||||||
|
new Option(
|
||||||
|
'--generate-upgrade-notes',
|
||||||
|
'Generate the UPGRADING.md notes for the release. ' +
|
||||||
|
'Note: This option is intended for use by the release manager when generating the upgrade notes.',
|
||||||
|
)
|
||||||
|
.default(true)
|
||||||
|
)
|
||||||
|
.addOption(
|
||||||
|
new Option(
|
||||||
|
'-d, --delete-notes',
|
||||||
|
'Delete the notes after generating the UPGRADING.md notes for the release. ' +
|
||||||
|
'Note: This option is intended for use by the release manager when generating the upgrade notes.' +
|
||||||
|
'This option has no effect unless --generate-upgrade-notes is also set.'
|
||||||
|
)
|
||||||
|
.default(false)
|
||||||
|
)
|
||||||
|
.action((version, options) => generateAction(version, options));
|
||||||
|
|
||||||
|
program.parse();
|
0
.upgradenotes/.gitkeep
Normal file
0
.upgradenotes/.gitkeep
Normal file
6
.upgradenotes/MDL-48940-2024052002223792.yml
Normal file
6
.upgradenotes/MDL-48940-2024052002223792.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
issueNumber: MDL-48940
|
||||||
|
notes:
|
||||||
|
core:
|
||||||
|
- message: >
|
||||||
|
The previously deprecated function `search_generate_text_SQL` has been removed and can no longer be used.
|
||||||
|
type: removed
|
6
.upgradenotes/MDL-71748-2024052002223792.yml
Normal file
6
.upgradenotes/MDL-71748-2024052002223792.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
issueNumber: MDL-71748
|
||||||
|
notes:
|
||||||
|
core:
|
||||||
|
- message: >
|
||||||
|
The previously deprecated function `core_text::reset_caches()` has been removed and can no longer be used.
|
||||||
|
type: removed
|
6
.upgradenotes/MDL-72353-2024052002223792.yml
Normal file
6
.upgradenotes/MDL-72353-2024052002223792.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
issueNumber: MDL-72353
|
||||||
|
notes:
|
||||||
|
report:
|
||||||
|
- message: >-
|
||||||
|
The previously deprecated `report_helper::save_selected_report` method has been removed and can no longer be used
|
||||||
|
type: removed
|
7
.upgradenotes/MDL-73165-2024052002223792.yml
Normal file
7
.upgradenotes/MDL-73165-2024052002223792.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
issueNumber: MDL-73165
|
||||||
|
notes:
|
||||||
|
core:
|
||||||
|
- message: >
|
||||||
|
The following previously deprecated methods have been removed and can no longer be used:
|
||||||
|
- `renderer_base::should_display_main_logo`
|
||||||
|
type: removed
|
5
.upgradenotes/MDL-74484-2024052002223792.yml
Normal file
5
.upgradenotes/MDL-74484-2024052002223792.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
issueNumber: MDL-74484
|
||||||
|
notes:
|
||||||
|
core:
|
||||||
|
- message: Final deprecation of print_error(). Use moodle_exception instead.
|
||||||
|
type: removed
|
8
.upgradenotes/MDL-76690-2024052002223792.yml
Normal file
8
.upgradenotes/MDL-76690-2024052002223792.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
issueNumber: MDL-76690
|
||||||
|
notes:
|
||||||
|
core_reportbuilder:
|
||||||
|
- message: >
|
||||||
|
The following previously deprecated local helper methods have been removed and can no longer be used:
|
||||||
|
- `audience::get_all_audiences_menu_types`
|
||||||
|
- `report::get_available_columns`
|
||||||
|
type: removed
|
11
.upgradenotes/MDL-81168-2024052002223792.yml
Normal file
11
.upgradenotes/MDL-81168-2024052002223792.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
issueNumber: MDL-81168
|
||||||
|
notes:
|
||||||
|
core_reportbuilder:
|
||||||
|
- message: >
|
||||||
|
In order to better support float values in filter forms, the following
|
||||||
|
filter types now cast given SQL prior to comparison:
|
||||||
|
|
||||||
|
- `duration`
|
||||||
|
- `filesize`
|
||||||
|
- `number`
|
||||||
|
type: changed
|
6
.upgradenotes/MDL-81274-2024052002223792.yml
Normal file
6
.upgradenotes/MDL-81274-2024052002223792.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
issueNumber: MDL-81274
|
||||||
|
notes:
|
||||||
|
mod_data:
|
||||||
|
- message: >-
|
||||||
|
The `data_add_record` method accepts a new `$approved` parameter to set the corresponding state of the new record
|
||||||
|
type: improved
|
6
.upgradenotes/MDL-81330-2024052002223792.yml
Normal file
6
.upgradenotes/MDL-81330-2024052002223792.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
issueNumber: MDL-81330
|
||||||
|
notes:
|
||||||
|
core_reportbuilder:
|
||||||
|
- message: >
|
||||||
|
The base datasource `add_all_from_entities` method accepts a new optional parameter to specify which entities to add elements from
|
||||||
|
type: changed
|
8
.upgradenotes/MDL-81433-2024052002223792.yml
Normal file
8
.upgradenotes/MDL-81433-2024052002223792.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
issueNumber: MDL-81433
|
||||||
|
notes:
|
||||||
|
core_reportbuilder:
|
||||||
|
- message: >
|
||||||
|
The following external methods now return tags data relevant to each custom report:
|
||||||
|
- `core_reportbuilder_list_reports`
|
||||||
|
- `core_reportbuilder_retrieve_report`
|
||||||
|
type: improved
|
6
.upgradenotes/MDL-81434-2024052002223792.yml
Normal file
6
.upgradenotes/MDL-81434-2024052002223792.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
issueNumber: MDL-81434
|
||||||
|
notes:
|
||||||
|
core_reportbuilder:
|
||||||
|
- message: |2
|
||||||
|
Added a new database helper method `sql_replace_parameters` to help ensure uniqueness of parameters within a SQL expression
|
||||||
|
type: improved
|
8
.upgradenotes/MDL-81610-2024052002223792.yml
Normal file
8
.upgradenotes/MDL-81610-2024052002223792.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
issueNumber: MDL-81610
|
||||||
|
notes:
|
||||||
|
core_courseformat:
|
||||||
|
- message: >
|
||||||
|
The constructor of `core_courseformat\output\local\state\cm` has been updated to accept a new optional parameter, `$istrackeduser`.
|
||||||
|
|
||||||
|
If `istrackeduser` is pre-computed for the course module's course, it can be provided here to avoid an additional function call.
|
||||||
|
type: improved
|
7
UPGRADING.md
Normal file
7
UPGRADING.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# Moodle Upgrade notes
|
||||||
|
|
||||||
|
This file contains important information for developers on changes to the Moodle codebase.
|
||||||
|
|
||||||
|
More detailed information on key changes can be found in the [Developer update notes](https://moodledev.io/docs/devupdate) for your version of Moodle.
|
||||||
|
|
||||||
|
The format of this change log follows the advice given at [Keep a CHANGELOG](https://keepachangelog.com).
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the tool_behat code.
|
This files describes API changes in the tool_behat code.
|
||||||
|
|
||||||
=== 4.3 ===
|
=== 4.3 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /admin/tool/brickfield/*.
|
This files describes API changes in /admin/tool/brickfield/*.
|
||||||
|
|
||||||
=== 4.0 ===
|
=== 4.0 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in /admin/tool/dataprivacy/*
|
This file describes API changes in /admin/tool/dataprivacy/*
|
||||||
Information provided here is intended especially for developers.
|
Information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in core libraries and APIs,
|
This files describes API changes in core libraries and APIs,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the logstore_database code.
|
This files describes API changes in the logstore_database code.
|
||||||
|
|
||||||
=== 3.4 ===
|
=== 3.4 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /admin/tool/log - plugins,
|
This files describes API changes in /admin/tool/log - plugins,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes changes in /admin/tool/lp/* - plugins,
|
This files describes changes in /admin/tool/lp/* - plugins,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes for code that uses MFA.
|
This files describes API changes for code that uses MFA.
|
||||||
|
|
||||||
=== 4.4 ===
|
=== 4.4 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes changes in tool_mobile code.
|
This files describes changes in tool_mobile code.
|
||||||
Information provided here is intended especially for developers.
|
Information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the tool_phpunit code.
|
This files describes API changes in the tool_phpunit code.
|
||||||
|
|
||||||
=== 3.9 ===
|
=== 3.9 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /admin/tool/* - plugins,
|
This files describes API changes in /admin/tool/* - plugins,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the tool_usertours code.
|
This files describes API changes in the tool_usertours code.
|
||||||
|
|
||||||
=== 4.4 ===
|
=== 4.4 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /admin/*.
|
This files describes API changes in /admin/*.
|
||||||
|
|
||||||
=== 4.4 ===
|
=== 4.4 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in analytics sub system,
|
This files describes API changes in analytics sub system,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /auth/cas/*,
|
This files describes API changes in /auth/cas/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /auth/db/*,
|
This files describes API changes in /auth/db/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /auth/email/*,
|
This files describes API changes in /auth/email/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
=== 4.4 ===
|
=== 4.4 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the auth_ldap code.
|
This files describes API changes in the auth_ldap code.
|
||||||
|
|
||||||
=== 3.4 ===
|
=== 3.4 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /auth/manual/*,
|
This files describes API changes in /auth/manual/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in auth_mnet code.
|
This files describes API changes in auth_mnet code.
|
||||||
|
|
||||||
=== 3.3 ===
|
=== 3.3 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /auth/none/*,
|
This files describes API changes in /auth/none/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /auth/shibboleth/*,
|
This files describes API changes in /auth/shibboleth/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /auth/* - plugins,
|
This files describes API changes in /auth/* - plugins,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /availability/*.
|
This files describes API changes in /availability/*.
|
||||||
|
|
||||||
The information here is intended only for developers.
|
The information here is intended only for developers.
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /backup/*,
|
This files describes API changes in /backup/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /badges/*,
|
This files describes API changes in /badges/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
=== 4.4 ===
|
=== 4.4 ===
|
||||||
* The following previously deprecated methods have been removed and can no longer be used:
|
* The following previously deprecated methods have been removed and can no longer be used:
|
||||||
- block_calendar_upcoming::get_upcoming_content
|
- block_calendar_upcoming::get_upcoming_content
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in the lp block code.
|
This file describes API changes in the lp block code.
|
||||||
|
|
||||||
=== 3.7 ===
|
=== 3.7 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in the myoverview block code.
|
This file describes API changes in the myoverview block code.
|
||||||
|
|
||||||
=== 3.7 ===
|
=== 3.7 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in the recentlyaccessedcourses block code.
|
This file describes API changes in the recentlyaccessedcourses block code.
|
||||||
|
|
||||||
=== 3.8 ===
|
=== 3.8 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in the recentlyaccesseditems block code.
|
This file describes API changes in the recentlyaccesseditems block code.
|
||||||
|
|
||||||
=== 4.4 ===
|
=== 4.4 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in the section_links block code.
|
This file describes API changes in the section_links block code.
|
||||||
|
|
||||||
=== 3.11 ===
|
=== 3.11 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in the starredcourses block code.
|
This file describes API changes in the starredcourses block code.
|
||||||
|
|
||||||
=== 3.8 ===
|
=== 3.8 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the block tag_youtube code.
|
This files describes API changes in the block tag_youtube code.
|
||||||
|
|
||||||
=== 3.10.1 ===
|
=== 3.10.1 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in the timeline block code.
|
This file describes API changes in the timeline block code.
|
||||||
|
|
||||||
=== 4.0 ===
|
=== 4.0 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /blocks/* - activity modules,
|
This files describes API changes in /blocks/* - activity modules,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /blog/* ,
|
This files describes API changes in /blog/* ,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
5
cache/upgrade.txt
vendored
5
cache/upgrade.txt
vendored
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /cache/stores/* - cache store plugins.
|
This files describes API changes in /cache/stores/* - cache store plugins.
|
||||||
Information provided here is intended especially for developers.
|
Information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /calendar/* ,
|
This files describes API changes in /calendar/* ,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /cohort/ information provided here is intended
|
This files describes API changes in /cohort/ information provided here is intended
|
||||||
especially for developers.
|
especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /comment/* ,
|
This files describes API changes in /comment/* ,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,7 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in /communication/provider/*
|
This file describes API changes in /communication/provider/*
|
||||||
Information provided here is intended especially for developers.
|
Information provided here is intended especially for developers.
|
||||||
|
|
|
@ -1,2 +1,7 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in /communication/*
|
This file describes API changes in /communication/*
|
||||||
Information provided here is intended especially for developers.
|
Information provided here is intended especially for developers.
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /competency/*. The information provided
|
This files describes API changes in /competency/*. The information provided
|
||||||
here is intended especially for developers.
|
here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in /completion/* - completion,
|
This file describes API changes in /completion/* - completion,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in core libraries and APIs,
|
This files describes API changes in core libraries and APIs,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes for course formats
|
This files describes API changes for course formats
|
||||||
|
|
||||||
Overview of this plugin type at https://moodledev.io/docs/apis/plugintypes/format
|
Overview of this plugin type at https://moodledev.io/docs/apis/plugintypes/format
|
||||||
|
|
||||||
=== 4.5 ===
|
|
||||||
* The constructor of core_courseformat\output\local\state\cm has been updated to accept a new optional parameter called is_tracked_user.
|
|
||||||
If is_tracked_user is pre-computed for this CM's course, it can be provided here to avoid an additional function call.
|
|
||||||
|
|
||||||
=== 4.4 ===
|
=== 4.4 ===
|
||||||
* The core_courseformat\output\local\content\section::export_for_template() is not returning hiddenfromstudents and notavailable
|
* The core_courseformat\output\local\content\section::export_for_template() is not returning hiddenfromstudents and notavailable
|
||||||
directly in the data array anymore. Instead, it returns the visibility data in the 'visibility' key. It means that templates
|
directly in the data array anymore. Instead, it returns the visibility data in the 'visibility' key. It means that templates
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /course/*,
|
This files describes API changes in /course/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /customfield/field/* - customfield field types,
|
This files describes API changes in /customfield/field/* - customfield field types,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /customfield/*,
|
This files describes API changes in /customfield/*,
|
||||||
Information provided here is intended especially for developers.
|
Information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /dataformat/ download system,
|
This files describes API changes in /dataformat/ download system,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the enrol_database code.
|
This files describes API changes in the enrol_database code.
|
||||||
|
|
||||||
=== 3.11 ===
|
=== 3.11 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the enrol_ldap code.
|
This files describes API changes in the enrol_ldap code.
|
||||||
|
|
||||||
=== 3.8 ===
|
=== 3.8 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /enrol/* - plugins,
|
This files describes API changes in /enrol/* - plugins,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /files/*,
|
This files describes API changes in /files/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in core filter API and plugins,
|
This file describes API changes in core filter API and plugins,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /grade/export/* - plugins,
|
This files describes API changes in /grade/export/* - plugins,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /grade/grading/form/* - Advanced grading methods
|
This files describes API changes in /grade/grading/form/* - Advanced grading methods
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /grade/report/*,
|
This files describes API changes in /grade/report/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes in /grade/* ;
|
This file describes API changes in /grade/* ;
|
||||||
Information provided here is intended especially for developers.
|
Information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /group/*,
|
This files describes API changes in /group/*,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in core libraries and APIs,
|
This files describes API changes in core libraries and APIs,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the editor_atto code.
|
This files describes API changes in the editor_atto code.
|
||||||
|
|
||||||
=== 4.1 ===
|
=== 4.1 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in tiny_accessibilitychecker - TinyMCE Accessibility checker plugin,
|
This files describes API changes in tiny_accessibilitychecker - TinyMCE Accessibility checker plugin,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /lib/editor/tiny/* - TinyMCE editor,
|
This files describes API changes in /lib/editor/tiny/* - TinyMCE editor,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in core_form libraries and APIs,
|
This files describes API changes in core_form libraries and APIs,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the mlbackend_php code, the
|
This files describes API changes in the mlbackend_php code, the
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the mlbackend_python code, the
|
This files describes API changes in the mlbackend_python code, the
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
|
|
||||||
This files describes API changes in core libraries and APIs,
|
This files describes API changes in core libraries and APIs,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
=== 4.5 ===
|
|
||||||
|
|
||||||
* Final deprecation and removal of the function core_text::reset_caches().
|
|
||||||
* The previously deprecated function `search_generate_text_SQL` has been removed and can no longer be used.
|
|
||||||
* The following previously deprecated methods have been removed and can no longer be used:
|
|
||||||
- `renderer_base::should_display_main_logo`
|
|
||||||
* Final deprecation of print_error(). Use moodle_exception instead.
|
|
||||||
|
|
||||||
=== 4.4 ===
|
=== 4.4 ===
|
||||||
|
|
||||||
* New modinfo methods related to delegated sections (sections controlled by a component):
|
* New modinfo methods related to delegated sections (sections controlled by a component):
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in core_xapi libraries and APIs,
|
This files describes API changes in core_xapi libraries and APIs,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This file describes API changes for the plugins of the type 'local'.
|
This file describes API changes for the plugins of the type 'local'.
|
||||||
|
|
||||||
=== 3.1 ===
|
=== 3.1 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /media/ plugins,
|
This files describes API changes in /media/ plugins,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in /message/ messaging system,
|
This files describes API changes in /message/ messaging system,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the assign code.
|
This files describes API changes in the assign code.
|
||||||
|
|
||||||
=== 4.3 ===
|
=== 4.3 ===
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
=== 4.5 Onwards ===
|
||||||
|
|
||||||
|
This file has been replaced by UPGRADING.md. See MDL-81125 for further information.
|
||||||
|
|
||||||
|
===
|
||||||
This files describes API changes in the bigbluebuttonbn code.
|
This files describes API changes in the bigbluebuttonbn code.
|
||||||
=== 4.3 ===
|
=== 4.3 ===
|
||||||
* Make instance class constructor private and use the factory method to create instances.
|
* Make instance class constructor private and use the factory method to create instances.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue