Skip to content
Snippets Groups Projects
Select Git revision
  • aab6b62dbb2196e4f9d95c2e5d7a30b8460b550a
  • main default protected
  • renovate/cloudflare-5.x
  • renovate/immich
  • renovate/oauth2-proxy-7.x
  • renovate/ghcr.io-tektoncd-pipeline-webhook-d4749e605405422fd87700164e31b2d1-1.x
  • renovate/ghcr.io-tektoncd-pipeline-resolvers-ff86b24f130c42b88983d3c13993056d-1.x
  • renovate/ghcr.io-tektoncd-pipeline-events-a9042f7efb0cbade2a868a1ee5ddd52c-1.x
  • renovate/ghcr.io-tektoncd-pipeline-controller-10a3e32792f33651396d02b6855a6e36-1.x
  • renovate/github.com-prometheus-client_golang-1.x
  • renovate/ghcr.io-siderolabs-talosctl-1.x
  • renovate/siderolabs-talos-1.10.x
  • renovate/docker.io-helmunittest-helm-unittest-3.x
  • renovate/hcloud-exporter-4.x
  • renovate/gitlab-runner-0.x
  • renovate/redis-21.x
  • renovate/mikefarah-yq-4.x
  • renovate/prometheus-json-exporter-0.x
  • renovate/prometheus-smartctl-exporter-0.x
  • renovate/gcr.io-projectsigstore-cosign-2.x
  • renovate/docker.io-bitnami-kubectl-1.x
  • v25.07
  • v25.06
  • v25.05
  • v25.04
  • v25.03
  • v25.02
  • v25.01
  • v24.12
  • v24.11
  • v24.10
  • v24.09
  • v24.08
  • v24.07
  • v24.06
  • v24.05
  • v24.04
  • v24.03
  • v24.02
  • v24.01
  • v23.12
41 results

validate.sh

Blame
  • version.ts 3.99 KiB
    import { eq, major, minor, patch, prerelease } from '@renovatebot/ruby-semver';
    import {
      SegmentElement,
      create,
    } from '@renovatebot/ruby-semver/dist/ruby/version.js';
    import { regEx } from '../../../util/regex';
    
    interface RubyVersion {
      major: number;
      minor: number;
      patch: number;
      prerelease: string[] | null;
    }
    
    function releaseSegments(version: string): SegmentElement[] {
      const v = create(version);
      if (v) {
        return v.release().getSegments();
      }
      /* istanbul ignore next */
      return [];
    }
    
    const parse = (version: string): RubyVersion => ({
      major: major(version),
      minor: minor(version),
      patch: patch(version),
      prerelease: prerelease(version),
    });
    
    const floor = (version: string): string => {
      const segments = releaseSegments(version);
      if (segments.length <= 1) {
        // '~> 2' is equivalent to '~> 2.0', thus no need to floor
        return segments.join('.');
      }
      return [...segments.slice(0, -1), 0].join('.');
    };
    
    const adapt = (left: string, right: string): string =>
      left.split('.').slice(0, right.split('.').length).join('.');
    
    const trimZeroes = (version: string): string => {
      const segments = version.split('.');
      while (segments.length > 0 && segments[segments.length - 1] === '0') {
        segments.pop();
      }
      return segments.join('.');
    };
    
    // Returns the upper bound of `~>` operator.
    const pgteUpperBound = (version: string): string => {
      const segments = releaseSegments(version);
      if (segments.length > 1) {
        segments.pop();
      }
      return incrementLastSegment(segments.join('.'));
    };
    
    // istanbul ignore next
    const incrementLastSegment = (version: string): string => {
      const segments = releaseSegments(version);
      const nextLast = parseInt(segments.pop() as string, 10) + 1;
    
      return [...segments, nextLast].join('.');
    };
    
    // istanbul ignore next
    const incrementMajor = (
      maj: number,
      min: number,
      ptch: number,
      pre: string[],
    ): number => (min === 0 || ptch === 0 || pre.length === 0 ? maj + 1 : maj);
    
    // istanbul ignore next
    const incrementMinor = (min: number, ptch: number, pre: string[]): number =>
      ptch === 0 || pre.length === 0 ? min + 1 : min;
    
    // istanbul ignore next
    const incrementPatch = (ptch: number, pre: string[]): number =>
      pre.length === 0 ? ptch + 1 : ptch;
    
    // istanbul ignore next
    const increment = (from: string, to: string): string => {
      const parsed = parse(from);
      const { major: maj, prerelease: pre } = parsed;
      let { minor: min, patch: ptch } = parsed;
      min = min || 0;
      ptch = ptch || 0;
    
      let nextVersion: string;
      const adapted = adapt(to, from);
      if (eq(from, adapted)) {
        return incrementLastSegment(from);
      }
    
      const isStable = (x: string): boolean => regEx(/^[0-9.-/]+$/).test(x);
      if (major(from) !== major(adapted)) {
        nextVersion = [incrementMajor(maj, min, ptch, pre ?? []), 0, 0].join('.');
      } else if (minor(from) !== minor(adapted)) {
        nextVersion = [maj, incrementMinor(min, ptch, pre ?? []), 0].join('.');
      } else if (patch(from) !== patch(adapted)) {
        nextVersion = [maj, min, incrementPatch(ptch, pre ?? [])].join('.');
      } else if (isStable(from) && isStable(adapted)) {
        nextVersion = [maj, min, incrementPatch(ptch, pre ?? [])].join('.');
      } else {
        nextVersion = [maj, min, ptch].join('.');
      }
    
      return increment(nextVersion, to);
    };
    
    // istanbul ignore next
    const decrement = (version: string): string => {
      const segments = releaseSegments(version);
      const nextSegments = segments
        .reverse()
        .reduce(
          (
            accumulator: number[],
            segment: SegmentElement,
            index: number,
          ): number[] => {
            if (index === 0) {
              return [(segment as number) - 1];
            }
    
            if (accumulator[index - 1] === -1) {
              return [
                ...accumulator.slice(0, index - 1),
                0,
                (segment as number) - 1,
              ];
            }
    
            return [...accumulator, segment as number];
          },
          [],
        );
    
      return nextSegments.reverse().join('.');
    };
    
    export {
      parse,
      adapt,
      floor,
      trimZeroes,
      pgteUpperBound,
      increment,
      decrement,
    };