Skip to content

Commit cadd534

Browse files
andrewnicolsjunpataleta
authored andcommitted
Merge branch 'MDL-76802-master' of https://github.com/sarjona/moodle
2 parents b711e80 + f0a20c0 commit cadd534

File tree

7 files changed

+216
-0
lines changed

7 files changed

+216
-0
lines changed

.grunt/components.js

+150
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,155 @@ const getOwningComponentDirectory = checkPath => {
232232
return null;
233233
};
234234

235+
/**
236+
* Get the latest tag in a remote GitHub repository.
237+
*
238+
* @param {string} url The remote repository.
239+
* @returns {Array}
240+
*/
241+
const getRepositoryTags = async(url) => {
242+
const gtr = require('git-tags-remote');
243+
try {
244+
const tags = await gtr.get(url);
245+
if (tags !== undefined) {
246+
return tags;
247+
}
248+
} catch (error) {
249+
return [];
250+
}
251+
return [];
252+
};
253+
254+
/**
255+
* Get the list of thirdparty libraries that could be upgraded.
256+
*
257+
* @returns {Array}
258+
*/
259+
const getThirdPartyLibsUpgradable = async() => {
260+
const libraries = getThirdPartyLibsData().filter((library) => !!library.repository);
261+
const upgradableLibraries = [];
262+
const versionCompare = (a, b) => {
263+
if (a === b) {
264+
return 0;
265+
}
266+
267+
const aParts = a.split('.');
268+
const bParts = b.split('.');
269+
270+
for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) {
271+
const aPart = parseInt(aParts[i], 10);
272+
const bPart = parseInt(bParts[i], 10);
273+
if (aPart > bPart) {
274+
// 1.1.0 > 1.0.9
275+
return 1;
276+
} else if (aPart < bPart) {
277+
// 1.0.9 < 1.1.0
278+
return -1;
279+
} else {
280+
// Same version.
281+
continue;
282+
}
283+
}
284+
285+
if (aParts.length > bParts.length) {
286+
// 1.0.1 > 1.0
287+
return 1;
288+
}
289+
290+
// 1.0 < 1.0.1
291+
return -1;
292+
};
293+
294+
for (let library of libraries) {
295+
upgradableLibraries.push(
296+
getRepositoryTags(library.repository).then((tagMap) => {
297+
library.version = library.version.replace(/^v/, '');
298+
const currentVersion = library.version.replace(/moodle-/, '');
299+
const currentMajorVersion = library.version.split('.')[0];
300+
const tags = [...tagMap]
301+
.map((tagData) => tagData[0])
302+
.filter((tag) => !tag.match(/(alpha|beta|rc)/))
303+
.map((tag) => tag.replace(/^v/, ''))
304+
.sort((a, b) => versionCompare(b, a));
305+
if (!tags.length) {
306+
library.warning = "Unable to find any comparable tags.";
307+
return library;
308+
}
309+
310+
library.latestVersion = tags[0];
311+
tags.some((tag) => {
312+
if (!tag) {
313+
return false;
314+
}
315+
316+
// See if the version part matches.
317+
const majorVersion = tag.split('.')[0];
318+
if (majorVersion === currentMajorVersion) {
319+
library.latestSameMajorVersion = tag;
320+
return true;
321+
}
322+
return false;
323+
});
324+
325+
326+
if (versionCompare(currentVersion, library.latestVersion) > 0) {
327+
// Moodle somehow has a newer version than the latest version.
328+
library.warning = `Newer version found: ${currentVersion} > ${library.latestVersion} for ${library.name}`;
329+
return library;
330+
}
331+
332+
333+
if (library.version !== library.latestVersion) {
334+
// Delete version and add it again at the end of the array. That way, current and new will stay closer.
335+
delete library.version;
336+
library.version = currentVersion;
337+
return library;
338+
}
339+
return null;
340+
})
341+
);
342+
}
343+
344+
return (await Promise.all(upgradableLibraries)).filter((library) => !!library);
345+
};
346+
347+
/**
348+
* Get the list of thirdparty libraries.
349+
*
350+
* @returns {Array}
351+
*/
352+
const getThirdPartyLibsData = () => {
353+
const DOMParser = require('xmldom').DOMParser;
354+
const fs = require('fs');
355+
const xpath = require('xpath');
356+
const path = require('path');
357+
358+
const libraryList = [];
359+
const libraryFields = [
360+
'location',
361+
'name',
362+
'version',
363+
'repository',
364+
];
365+
366+
const thirdpartyfiles = getThirdPartyLibsList(fs.realpathSync('./'));
367+
thirdpartyfiles.forEach(function(libraryPath) {
368+
const xmlContent = fs.readFileSync(libraryPath, 'utf8');
369+
const doc = new DOMParser().parseFromString(xmlContent);
370+
const libraries = xpath.select("/libraries/library", doc);
371+
for (const library of libraries) {
372+
const libraryData = [];
373+
for (const field of libraryFields) {
374+
libraryData[field] = xpath.select(`${field}/text()`, library)?.toString();
375+
}
376+
libraryData.location = path.join(path.dirname(libraryPath), libraryData.location);
377+
libraryList.push(libraryData);
378+
}
379+
});
380+
381+
return libraryList.sort((a, b) => a.location.localeCompare(b.location));
382+
};
383+
235384
module.exports = {
236385
fetchComponentData,
237386
getAmdSrcGlobList,
@@ -241,4 +390,5 @@ module.exports = {
241390
getYuiSrcGlobList,
242391
getThirdPartyLibsList,
243392
getThirdPartyPaths,
393+
getThirdPartyLibsUpgradable,
244394
};

.grunt/tasks/upgradablelibs.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// This file is part of Moodle - http://moodle.org/
2+
//
3+
// Moodle is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// Moodle is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU General Public License
14+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
15+
/* jshint node: true, browser: false */
16+
/* eslint-env node */
17+
18+
/**
19+
* @copyright 2023 Sara Arjona <[email protected]>
20+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
21+
*/
22+
23+
module.exports = grunt => {
24+
/**
25+
* Generate upgradable third-party libraries (utilising thirdpartylibs.xml data)
26+
*/
27+
grunt.registerTask('upgradablelibs', 'Generate upgradable third-party libraries', async function() {
28+
const done = this.async();
29+
30+
const path = require('path');
31+
const ComponentList = require(path.join(process.cwd(), '.grunt', 'components.js'));
32+
33+
// An array of third party libraries that have a newer version in their repositories.
34+
const thirdPartyLibs = await ComponentList.getThirdPartyLibsUpgradable({progress: true});
35+
for (let library of thirdPartyLibs) {
36+
grunt.log.ok(JSON.stringify(Object.assign({}, library), null, 4));
37+
}
38+
39+
done();
40+
});
41+
42+
};

Gruntfile.js

+2
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ module.exports = function(grunt) {
260260
addTask('watch', grunt);
261261
addTask('startup', grunt);
262262

263+
addTask('upgradablelibs', grunt);
264+
263265
// Register the default task.
264266
grunt.registerTask('default', ['startup']);
265267
};

lib/editor/tiny/thirdpartylibs.xml

+1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
<name>Tiny</name>
66
<license>MIT</license>
77
<version>6.3.2</version>
8+
<repository>https://github.com/tinymce/tinymce</repository>
89
</library>
910
</libraries>

lib/upgrade.txt

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ information provided here is intended especially for developers.
7979
Course formats using components will be allowed to use one level indentation only.
8080
* The method `flexible_table::set_columnsattributes` now can be used with 'class' key to add custom classes to the DOM.
8181
* The editor_tinymce plugin has been removed from core.
82+
* A new grunt task, upgradablelibs, has been added to get the list of libraries that have a newer version in their repositories.
8283

8384
=== 4.1 ===
8485

npm-shrinkwrap.json

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"eslint-plugin-promise": "6.0.0",
2424
"fb-watchman": "2.0.1",
2525
"gherkin-lint": "^4.2.2",
26+
"git-tags-remote": "^1.0.5",
2627
"glob": "7.2.0",
2728
"grunt": "^1.4.1",
2829
"grunt-contrib-uglify": "5.0.1",

0 commit comments

Comments
 (0)