UNPKG

9.56 kBJavaScriptView Raw
1Object.defineProperty(exports, "__esModule", { value: true });
2exports.getStatusProviderFromConfig = exports.getArtifactProviderFromConfig = exports.getGitTagPrefix = exports.getGlobalGithubConfig = exports.checkMinimalConfigVersion = exports.getConfiguration = exports.validateConfiguration = exports.getProjectConfigSchema = exports.getConfigFileDir = exports.getConfigFilePath = exports.findConfigFile = exports.DEFAULT_RELEASE_BRANCH_NAME = exports.CONFIG_FILE_NAME = void 0;
3const fs_1 = require("fs");
4const path_1 = require("path");
5const Ajv = require("ajv");
6const js_yaml_1 = require("js-yaml");
7const logger_1 = require("./logger");
8const errors_1 = require("./utils/errors");
9const version_1 = require("./utils/version");
10const github_1 = require("./artifact_providers/github");
11const zeus_1 = require("./artifact_providers/zeus");
12const none_1 = require("./artifact_providers/none");
13const gcs_1 = require("./artifact_providers/gcs");
14const zeus_2 = require("./status_providers/zeus");
15const github_2 = require("./status_providers/github");
16// TODO support multiple configuration files (one per configuration)
17exports.CONFIG_FILE_NAME = '.craft.yml';
18/**
19 * The default prefix for the release branch.
20 */
21exports.DEFAULT_RELEASE_BRANCH_NAME = 'release';
22/**
23 * Cached path to the configuration file
24 */
25let _configPathCache;
26/**
27 * Cached configuration
28 */
29let _configCache;
30/**
31 * Searches the current and parent directories for the configuration file
32 *
33 * Returns "undefined" if no file was found.
34 */
35function findConfigFile() {
36 if (_configPathCache) {
37 return _configPathCache;
38 }
39 const cwd = process.cwd();
40 const MAX_DEPTH = 1024;
41 let depth = 0;
42 let currentDir = cwd;
43 while (depth <= MAX_DEPTH) {
44 const probePath = path_1.join(currentDir, exports.CONFIG_FILE_NAME);
45 if (fs_1.existsSync(probePath) && fs_1.lstatSync(probePath).isFile()) {
46 _configPathCache = probePath;
47 return _configPathCache;
48 }
49 const parentDir = path_1.dirname(currentDir);
50 if (currentDir === parentDir) {
51 // Reached root directory
52 return undefined;
53 }
54 currentDir = parentDir;
55 depth += 1;
56 }
57 logger_1.logger.warn('findConfigFile: Reached maximum allowed directory depth');
58 return undefined;
59}
60exports.findConfigFile = findConfigFile;
61/**
62 * Returns project configuration (.craft.yml) file path
63 *
64 * Throws an error if the file cannot be found.
65 */
66function getConfigFilePath() {
67 const configFilePath = findConfigFile();
68 if (!configFilePath) {
69 throw new errors_1.ConfigurationError(`Cannot find Craft configuration file. Have you added "${exports.CONFIG_FILE_NAME}" to your project?`);
70 }
71 return configFilePath;
72}
73exports.getConfigFilePath = getConfigFilePath;
74/**
75 * Returns the path to the directory that contains the configuration file
76 *
77 * Returns "undefined" if no configuration file can be found.
78 */
79function getConfigFileDir() {
80 const configFilePath = findConfigFile();
81 if (!configFilePath) {
82 return undefined;
83 }
84 return path_1.dirname(configFilePath);
85}
86exports.getConfigFileDir = getConfigFileDir;
87/**
88 * Reads JSON schema for project configuration
89 */
90function getProjectConfigSchema() {
91 return require('./schemas/projectConfig.schema');
92}
93exports.getProjectConfigSchema = getProjectConfigSchema;
94/**
95 * Parses and validate passed configuration object
96 *
97 * Throw an error is the object cannot be properly parsed as configuration.
98 *
99 * @param rawConfig Raw project configuration object
100 */
101function validateConfiguration(rawConfig) {
102 logger_1.logger.debug('Parsing and validating the configuration file...');
103 const schemaName = 'projectConfig';
104 const projectConfigSchema = getProjectConfigSchema();
105 const ajvValidator = new Ajv().addSchema(projectConfigSchema, schemaName);
106 const valid = ajvValidator.validate(schemaName, rawConfig);
107 if (valid) {
108 return rawConfig;
109 }
110 else {
111 throw new errors_1.ConfigurationError(`Cannot parse configuration file:\n${ajvValidator.errorsText()}`);
112 }
113}
114exports.validateConfiguration = validateConfiguration;
115/**
116 * Returns the parsed configuration file contents
117 */
118function getConfiguration() {
119 if (_configCache) {
120 return _configCache;
121 }
122 const configPath = getConfigFilePath();
123 logger_1.logger.debug('Configuration file found: ', configPath);
124 const rawConfig = js_yaml_1.safeLoad(fs_1.readFileSync(configPath, 'utf-8'));
125 _configCache = validateConfiguration(rawConfig);
126 return _configCache;
127}
128exports.getConfiguration = getConfiguration;
129/**
130 * Checks that the current "craft" version is compatible with the configuration
131 *
132 * "minVersion" configuration parameter specifies the minimal version of "craft"
133 * that can work with the given configuration.
134 */
135function checkMinimalConfigVersion() {
136 const config = getConfiguration();
137 const minVersionRaw = config.minVersion;
138 if (!minVersionRaw) {
139 logger_1.logger.debug('No minimal version specified in the configuration, skpipping the check');
140 return;
141 }
142 const currentVersionRaw = version_1.getPackageVersion();
143 if (!currentVersionRaw) {
144 throw new Error('Cannot get the current craft version');
145 }
146 const minVersion = version_1.parseVersion(minVersionRaw);
147 if (!minVersion) {
148 throw new Error(`Cannot parse the minimal version: "${minVersionRaw}"`);
149 }
150 const currentVersion = version_1.parseVersion(currentVersionRaw);
151 if (!currentVersion) {
152 throw new Error(`Cannot parse the current version: "${currentVersionRaw}"`);
153 }
154 if (version_1.versionGreaterOrEqualThan(currentVersion, minVersion)) {
155 logger_1.logger.info(`"craft" version is compatible with the minimal version from the configuration file.`);
156 }
157 else {
158 throw new errors_1.ConfigurationError(`Incompatible "craft" versions. Current version: ${currentVersionRaw}, minimal version: ${minVersionRaw} (taken from .craft.yml).`);
159 }
160}
161exports.checkMinimalConfigVersion = checkMinimalConfigVersion;
162/**
163 * Return the parsed global Github configuration
164 */
165function getGlobalGithubConfig() {
166 // We extract global Github configuration (owner/repo) from top-level
167 // configuration
168 const repoGithubConfig = getConfiguration().github || {};
169 if (!repoGithubConfig) {
170 throw new errors_1.ConfigurationError('GitHub configuration not found in the config file');
171 }
172 if (!repoGithubConfig.owner) {
173 throw new errors_1.ConfigurationError('GitHub target: owner not found');
174 }
175 if (!repoGithubConfig.repo) {
176 throw new errors_1.ConfigurationError('GitHub target: repo not found');
177 }
178 return repoGithubConfig;
179}
180exports.getGlobalGithubConfig = getGlobalGithubConfig;
181/**
182 * Gets git tag prefix from configuration
183 */
184function getGitTagPrefix() {
185 const targets = getConfiguration().targets || [];
186 const githubTarget = targets.find(target => target.name === 'github') || {};
187 return githubTarget.tagPrefix || '';
188}
189exports.getGitTagPrefix = getGitTagPrefix;
190/**
191 * Create an artifact provider instance from the spec in the configuration file
192 *
193 * @returns An instance of artifact provider (which may be the dummy
194 * NoneArtifactProvider if artifact storage is disabled).
195 */
196function getArtifactProviderFromConfig() {
197 var _a, _b;
198 const projectConfig = getConfiguration();
199 const artifactProviderName = (_a = projectConfig.artifactProvider) === null || _a === void 0 ? void 0 : _a.name;
200 const artifactProviderConfig = Object.assign(Object.assign({}, (_b = projectConfig.artifactProvider) === null || _b === void 0 ? void 0 : _b.config), { repoName: projectConfig.github.repo, repoOwner: projectConfig.github.owner });
201 switch (artifactProviderName) {
202 case undefined: // Zeus is the default at the moment
203 case "zeus" /* Zeus */:
204 return new zeus_1.ZeusArtifactProvider(artifactProviderConfig);
205 case "none" /* None */:
206 return new none_1.NoneArtifactProvider();
207 case "gcs" /* GCS */:
208 return new gcs_1.GCSArtifactProvider(artifactProviderConfig);
209 case "github" /* Github */:
210 return new github_1.GithubArtifactProvider(artifactProviderConfig);
211 default: {
212 throw new errors_1.ConfigurationError('Invalid artifact provider');
213 }
214 }
215}
216exports.getArtifactProviderFromConfig = getArtifactProviderFromConfig;
217/**
218 * Create a status provider instance from the spec in the configuration file
219 *
220 * @returns An instance of status provider
221 */
222function getStatusProviderFromConfig() {
223 const config = getConfiguration() || {};
224 const githubConfig = config.github;
225 const rawStatusProvider = config.statusProvider || {
226 config: undefined,
227 name: undefined,
228 };
229 const { config: statusProviderConfig, name: statusProviderName, } = rawStatusProvider;
230 switch (statusProviderName) {
231 case undefined:
232 case "zeus" /* Zeus */:
233 return new zeus_2.ZeusStatusProvider(githubConfig.owner, githubConfig.repo, statusProviderConfig);
234 case "github" /* Github */:
235 return new github_2.GithubStatusProvider(githubConfig.owner, githubConfig.repo, statusProviderConfig);
236 default: {
237 throw new errors_1.ConfigurationError('Invalid status provider');
238 }
239 }
240}
241exports.getStatusProviderFromConfig = getStatusProviderFromConfig;
242//# sourceMappingURL=config.js.map
\No newline at end of file