modules/frontend/app/services/Version.service.js (110 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import {BehaviorSubject} from 'rxjs'; import _ from 'lodash'; /** * Utility service for version parsing and comparing */ const VERSION_MATCHER = /(\d+)\.(\d+)\.(\d+)([-.]([^0123456789][^-]+)(-SNAPSHOT)?)?(-(\d+))?(-([\da-f]+))?/i; const numberComparator = (a, b) => a > b ? 1 : a < b ? -1 : 0; export default class IgniteVersion { constructor() { this.webConsole = '2.8.0'; this.supportedVersions = [ { label: 'Ignite 2.8', ignite: '2.8.0' }, { label: 'Ignite 2.7', ignite: '2.7.0' }, { label: 'Ignite 2.6', ignite: '2.6.0' }, { label: 'Ignite 2.5', ignite: '2.5.0' }, { label: 'Ignite 2.4', ignite: '2.4.0' }, { label: 'Ignite 2.3', ignite: '2.3.0' }, { label: 'Ignite 2.1', ignite: '2.2.0' }, { label: 'Ignite 2.0', ignite: '2.0.0' }, { label: 'Ignite 1.x', ignite: '1.9.0' } ]; /** Current product version. */ let current = _.head(this.supportedVersions); try { const ignite = localStorage.configurationVersion; const restored = _.find(this.supportedVersions, {ignite}); if (restored) current = restored; } catch (ignored) { // No-op. } this.currentSbj = new BehaviorSubject(current); this.currentSbj.subscribe({ next: (ver) => { try { localStorage.setItem('configurationVersion', ver.ignite); } catch (ignored) { // No-op. } } }); } /** * @return {String} Current Ignite version. */ get current() { return this.currentSbj.getValue().ignite; } /** * Check if version in range. * * @param {String} target Target version. * @param {String | Array.<String>} ranges Version ranges to compare with. * @returns {Boolean} `True` if version is equal or greater than specified range. */ since(target, ...ranges) { const targetVer = this.parse(target); return !!_.find(ranges, (range) => { if (_.isArray(range)) { const [after, before] = range; return this.compare(targetVer, this.parse(after)) >= 0 && (_.isNil(before) || this.compare(targetVer, this.parse(before)) < 0); } return this.compare(targetVer, this.parse(range)) >= 0; }); } /** * Check whether version before than specified version. * * @param {String} target Target version. * @param {String} ranges Version ranges to compare with. * @return {Boolean} `True` if version before than specified version. */ before(target, ...ranges) { return !this.since(target, ...ranges); } /** * Check if current version in specified range. * * @param {String|Array.<String>} ranges Version ranges to compare with. * @returns {Boolean} `True` if configuration version is equal or greater than specified range. */ available(...ranges) { return this.since(this.current, ...ranges); } /** * Tries to parse product version from it's string representation. * * @param {String} ver - String representation of version. * @returns {{major: Number, minor: Number, maintenance: Number, stage: String, revTs: Number, revHash: String}} - Object that contains product version fields. */ parse(ver) { // Development or built from source ZIP. ver = ver.replace(/(-DEV|-n\/a)$/i, ''); const [, major, minor, maintenance, stage, ...chunks] = ver.match(VERSION_MATCHER); return { major: parseInt(major, 10), minor: parseInt(minor, 10), maintenance: parseInt(maintenance, 10), stage: (stage || '').substring(1), revTs: chunks[2] ? parseInt(chunks[3], 10) : 0, revHash: chunks[4] ? chunks[5] : null }; } /** * Compare to version. * * @param {Object} a first compared version. * @param {Object} b second compared version. * @returns {Number} 1 if a > b, 0 if versions equals, -1 if a < b */ compare(a, b) { let res = numberComparator(a.major, b.major); if (res !== 0) return res; res = numberComparator(a.minor, b.minor); if (res !== 0) return res; res = numberComparator(a.maintenance, b.maintenance); if (res !== 0) return res; return numberComparator(a.stage, b.stage); } }