Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 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
 
16
import chalk from 'chalk';
17
import { isStandardComponent, isCommunityComponent, rewritePlugintypeAsSubsystem } from './components.mjs';
18
import { isValidNoteName } from './noteTypes.mjs';
19
import logger from './logger.mjs';
20
import { readFile } from 'fs/promises';
21
 
22
/**
23
 * Validate an issue number input
24
 *
25
 * @param {string} input
26
 * @returns {string|boolean}
27
 */
28
export const validateIssueNumber = (input) => {
29
    if (!input) {
30
        return 'You must provide a tracker issue number';
31
    }
32
 
33
    if (input.match(/^[a-zA-Z]*-\d+$/)) {
34
        return true;
35
    }
36
 
37
    if (input.match(/^\d+$/)) {
38
        return true;
39
    }
40
 
41
    return 'The issue number was not recognised as a valid issue number';
42
};
43
 
44
/**
45
 * Format an issue number input.
46
 *
47
 * @param {string} input
48
 * @returns {string}
49
 */
50
export const formatIssueNumber = (input) => {
51
    if (input.match(/^[a-zA-Z]*-\d+$/)) {
52
        return input;
53
    }
54
 
55
    if (input.match(/^\d+$/)) {
56
        return `MDL-${input}`;
57
    }
58
 
59
    return input;
60
};
61
 
62
/**
63
 * Validate a component.
64
 *
65
 * @param {string} input
66
 * @returns {string|boolean}
67
 */
68
export const validateComponent = (input) => {
69
    if (isStandardComponent(input)) {
70
        return true;
71
    }
72
 
73
    if (isCommunityComponent(input)) {
74
        return 'Currently only core plugins are supported.';
75
    }
76
 
77
    return 'The component was not recognised as a standard component';
78
};
79
 
80
export const formatComponent = (input) => {
81
    if (rewritePlugintypeAsSubsystem(input)) {
82
        return `core_${input}`;
83
    }
84
    return input;
85
}
86
 
87
/**
88
 * Get the initial values from the options.
89
 *
90
 * @param {object} options
91
 * @returns {object}
92
 */
93
export const getInitialValues = (options) => {
94
    const initialValues = {};
95
 
96
    const type = getInitialTypeValue(options);
97
    if (type) {
98
        initialValues.type = type;
99
    }
100
 
101
    const issueNumber = getInitialIssueValue(options);
102
    if (issueNumber) {
103
        initialValues.issueNumber = issueNumber;
104
    }
105
 
106
    const component = getInitialComponentValue(options);
107
    if (component) {
108
        initialValues.components = component;
109
    }
110
 
111
    const message = getInitialMessageValue(options);
112
    if (message) {
113
        initialValues.message = message
114
        initialValues.addAnother = false;
115
    }
116
 
117
    return initialValues;
118
};
119
 
120
/**
121
 * Get the initial type value.
122
 *
123
 * @param {Object} options
124
 * @returns {string|undefined}
125
 */
126
const getInitialTypeValue = (options) => {
127
    if (!options.type) {
128
        return;
129
    }
130
 
131
    options.type = options.type.trim().toLowerCase();
132
 
133
    if (isValidNoteName(options.type)) {
134
        return options.type;
135
    }
136
 
137
    logger.warn(`Note type "${chalk.underline(chalk.red(options.type))}" is not valid.`);
138
};
139
 
140
/**
141
 * Get the initial issue number value.
142
 *
143
 * @param {Object} options
144
 * @returns {string|undefined}
145
 */
146
 
147
const getInitialIssueValue = (options) => {
148
    if (!options.issue) {
149
        return;
150
    }
151
    options.issue = options.issue.trim().toUpperCase();
152
 
153
    const issueNumberValidated = validateIssueNumber(options.issue);
154
    if (issueNumberValidated === true) {
155
        const issueNumber = formatIssueNumber(options.issue);
156
        if (issueNumber !== options.issue) {
157
            logger.warn(
158
                `Issue number "${chalk.underline(chalk.red(options.issue))}" was updated to ` +
159
                `"${chalk.underline(chalk.green(issueNumber))}"`
160
            );
161
        }
162
 
163
        return issueNumber;
164
    } else {
165
        logger.warn(`Issue number "${chalk.underline(chalk.red(options.issue))}" is not valid: ${issueNumberValidated}`);
166
    }
167
};
168
 
169
/**
170
 * Get the initial component value.
171
 *
172
 * @param {Object} options
173
 * @returns {string|undefined}
174
 */
175
const getInitialComponentValue = (options) => {
176
    if (!options.component) {
177
        return;
178
    }
179
 
180
    options.component = options.component.trim().toLowerCase();
181
    const componentValidated = validateComponent(options.component);
182
    if (componentValidated === true) {
183
        const component = formatComponent(options.component);
184
        if (component !== options.component) {
185
            logger.warn(
186
                `Component "${chalk.underline(chalk.red(options.component))}" was updated to ` +
187
                `"${chalk.underline(chalk.green(component))}"`
188
            );
189
        }
190
 
191
        return component;
192
    } else {
193
        logger.warn(`Component "${chalk.underline(chalk.red(options.component))}" is not valid: ${componentValidated}`);
194
    }
195
};
196
 
197
/**
198
 * Get the initial message value.
199
 *
200
 * @param {Object} options
201
 * @returns {string|undefined}
202
 */
203
 
204
const getInitialMessageValue = (options) => {
205
    if (!options.message) {
206
        return;
207
    }
208
 
209
    return options.message.trim();
210
};
211
 
212
/**
213
 * Get the current version from the project /version.php file.
214
 *
215
 * @returns {Promise<string>}
216
 */
217
export const getCurrentVersion = async () => {
218
    const versionRegex = new RegExp(/^ *\$release *= *['\"](?<release>[^ \+]+\+?) *\(Build:.*/m);
219
    try {
220
        const versionFile = await readFile('version.php', 'utf8');
221
        const match = versionFile.match(versionRegex);
222
        if (match) {
223
            return match.groups.release;
224
        }
225
    } catch(error) {
226
        logger.error('Unable to read the version file');
227
    }
228
 
229
    return "Unreleased";
230
}