Skip to content
Snippets Groups Projects
Select Git revision
  • c5fa30ff2c9a4e5a0988422f894941c295268bca
  • main default protected
  • next
  • revert-31645-feat/rename-gradle-wrapper-validation-action
  • renovate/main-redis-5.x
  • fix/36615b-branch-reuse-no-cache
  • chore/punycode
  • fix/36615-branch-reuse-bug
  • refactor/pin-new-value
  • feat/36219--git-x509-signing
  • feat/structured-logger
  • hotfix/39.264.1
  • feat/skip-dangling
  • gh-readonly-queue/next/pr-36034-7a061c4ca1024a19e2c295d773d9642625d1c2be
  • hotfix/39.238.3
  • refactor/gitlab-auto-approve
  • feat/template-strings
  • gh-readonly-queue/next/pr-35654-137d934242c784e0c45d4b957362214f0eade1d7
  • fix/32307-global-extends-merging
  • fix/32307-global-extends-repositories
  • gh-readonly-queue/next/pr-35009-046ebf7cb84ab859f7fefceb5fa53a54ce9736f8
  • 41.34.1
  • 41.34.0
  • 41.33.0
  • 41.32.3
  • 41.32.2
  • 41.32.1
  • 41.32.0
  • 41.31.1
  • 41.31.0
  • 41.30.5
  • 41.30.4
  • 41.30.3
  • 41.30.2
  • 41.30.1
  • 41.30.0
  • 41.29.1
  • 41.29.0
  • 41.28.2
  • 41.28.1
  • 41.28.0
41 results

schedule.spec.js

Blame
  • validation.js 4.50 KiB
    const semver = require('semver');
    const options = require('./definitions').getOptions();
    const {
      hasValidSchedule,
      hasValidTimezone,
    } = require('../workers/branch/schedule');
    
    let optionTypes;
    
    module.exports = {
      validateConfig,
    };
    
    function validateConfig(config) {
      if (!optionTypes) {
        optionTypes = {};
        options.forEach(option => {
          optionTypes[option.name] = option.type;
        });
      }
      let errors = [];
      let warnings = [];
    
      function isIgnored(key) {
        const ignoredNodes = [
          'prBanner',
          'depType',
          'npmToken',
          'packageFile',
          'forkToken',
          'repository',
        ];
        return ignoredNodes.indexOf(key) !== -1;
      }
    
      function isAFunction(value) {
        const getType = {};
        return value && getType.toString.call(value) === '[object Function]';
      }
    
      function isObject(obj) {
        return Object.prototype.toString.call(obj) === '[object Object]';
      }
    
      function isString(val) {
        return typeof val === 'string' || val instanceof String;
      }
    
      for (const [key, val] of Object.entries(config)) {
        if (
          !isIgnored(key) && // We need to ignore some reserved keys
          !isAFunction(val) // Ignore all functions
        ) {
          if (!optionTypes[key]) {
            errors.push({
              depName: 'Configuration Error',
              message: `Invalid configuration option: \`${key}\``,
            });
          } else if (key === 'schedule') {
            const [validSchedule, errorMessage] = hasValidSchedule(val);
            if (!validSchedule) {
              errors.push({
                depName: 'Configuration Error',
                message: `Invalid schedule: \`${errorMessage}\``,
              });
            }
          } else if (key === 'timezone' && val !== null) {
            const [validTimezone, errorMessage] = hasValidTimezone(val);
            if (!validTimezone) {
              errors.push({
                depName: 'Configuration Error',
                message: errorMessage,
              });
            }
          } else if (key === 'allowedVersions' && val !== null) {
            if (!semver.validRange(val)) {
              errors.push({
                depName: 'Configuration Error',
                message: `Invalid semver range for allowedVersions: \`${val}\``,
              });
            }
          } else if (val != null) {
            const type = optionTypes[key];
            if (type === 'boolean') {
              if (val !== true && val !== false) {
                errors.push({
                  depName: 'Configuration Error',
                  message: `Configuration option \`${key}\` should be boolean. Found: ${JSON.stringify(
                    val
                  )} (${typeof val})`,
                });
              }
            } else if (type === 'list') {
              if (!Array.isArray(val)) {
                errors.push({
                  depName: 'Configuration Error',
                  message: `Configuration option \`${key}\` should be a list (Array)`,
                });
              } else if (key === 'extends') {
                for (const subval of val) {
                  if (isString(subval) && subval.match(/^:timezone(.+)$/)) {
                    const [, timezone] = subval.match(/^:timezone\((.+)\)$/);
                    const [validTimezone, errorMessage] = hasValidTimezone(
                      timezone
                    );
                    if (!validTimezone) {
                      errors.push({
                        depName: 'Configuration Error',
                        message: errorMessage,
                      });
                    }
                  }
                }
              } else {
                // eslint-disable-next-line no-loop-func
                val.forEach(subval => {
                  if (isObject(subval)) {
                    const subValidation = module.exports.validateConfig(subval);
                    warnings = warnings.concat(subValidation.warnings);
                    errors = errors.concat(subValidation.errors);
                  }
                });
              }
            } else if (type === 'string') {
              if (!isString(val)) {
                errors.push({
                  depName: 'Configuration Error',
                  message: `Configuration option \`${key}\` should be a string`,
                });
              }
            } else if (type === 'json') {
              if (isObject(val)) {
                const subValidation = module.exports.validateConfig(val);
                warnings = warnings.concat(subValidation.warnings);
                errors = errors.concat(subValidation.errors);
              } else {
                errors.push({
                  depName: 'Configuration Error',
                  message: `Configuration option \`${key}\` should be a json object`,
                });
              }
            }
          }
        }
      }
      return { errors, warnings };
    }