[ENHANCEMENT] minimum versions or minimum version in relation to

Aperta
#649 12 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
35/100
Tipo di issue
Funzionalità
Chiarezza
Da chiarire
Stato di attività
Ferma
Stack tecnologico
javascript, node.js
Ambito
tooling

Direzione di ricerca

Start with the TODO in minimum-engines.mjs and compare the requested behavior with minVersion, minSatisfying, validRange, and satisfies. Resolve whether one or two functions, names, and options are intended, then define tests for the listed range and version cases. Done means the agreed API handles the node_modules engine aggregation case without producing 16.0.0 for 16.1.0.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Right now, we have the minVersion function:

minVersion('14.0.0 || 16.1.0 || 18.0.0') // => '14.0.0'

and the minSatisfying function:

minSatisfying([parse('16.1.0')],'14.0.0 || 16.1.0 || 18.0.0')
// SemVer {
//   options: {},
//   loose: false,
//   includePrerelease: false,
//   raw: '16.1.0',
//   major: 16,
//   minor: 1,
//   patch: 0,
//   prerelease: [],
//   build: [],
//   version: '16.1.0'
// }
minSatisfying([parse('16.0.0')],'14.0.0 || 16.1.0 || 18.0.0')
// null

I suggest the addition of one or two functions:

to_be_named(version, range, options)

to_be_named('13.0.0', '14.0.0 || 16.1.0 || 18.0.0') // => '14.0.0'
to_be_named('14.0.0', '14.0.0 || 16.1.0 || 18.0.0') // => '14.0.0'
to_be_named('14.0.1', '14.0.0 || 16.1.0 || 18.0.0') // => '14.0.1'
to_be_named('15.0.0', '14.0.0 || 16.1.0 || 18.0.0') // => '16.1.0'
to_be_named('16.0.0', '14.0.0 || 16.1.0 || 18.0.0') // => '16.1.0'
to_be_named('16.1.0', '14.0.0 || 16.1.0 || 18.0.0') // => '16.1.0'
to_be_named('16.1.1', '14.0.0 || 16.1.0 || 18.0.0') // => '16.1.1'
to_be_named('18.0.0', '14.0.0 || 16.1.0 || 18.0.0') // => '18.0.0'
to_be_named('18.0.1', '14.0.0 || 16.1.0 || 18.0.0') // => '18.0.1'
to_be_named('19.0.0', '14.0.0 || 16.1.0 || 18.0.0') // => '19.0.0'

or:

to_be_named2(range, options)

to_be_named2('a || b || c') // => [ minVersion(a), minVersion(b), minVersion(c) ]

to_be_named2('8.0.0', '10.0.1', '>12.0.0 || <14.0.0 || ~18.0.0' || ^20.0.0) 
// =>       ['8.0.0', '10.0.1', '12.0.1',   '0.0.0',   '18.0.0',   '20.0.0' ]

My use case is the following script:

minimum-engines.mjs

#!/usr/bin/env node

/*
 Copyright (c) 2023, Sebastian Davids

 Licensed 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.
 */

// Prerequisite:
//   npm i --save-dev semver

// Usage:
//   node minimum-engines.mjs node_modules

import { compare, minVersion, satisfies, validRange } from 'semver';
import { readFile, readdir } from 'node:fs/promises';
import { resolve } from 'node:path';

if (process.argv.length < 3) {
  console.error('You need to supply the path to the node_modules folder');
  process.exit(1);
}

const nodeModulesPath = process.argv[2];

const getPackageJsonFiles = async function* (path) {
  const dirEntries = await readdir(path, { withFileTypes: true });
  for (const entry of dirEntries) {
    const file = resolve(path, entry.name);
    if (entry.isDirectory()) {
      yield* getPackageJsonFiles(file);
    } else if (entry.name === 'package.json') {
      yield file;
    }
  }
};

const getEngines = async (path) => {
  const json = await readFile(path, 'utf8');
  try {
    const { engines = {} } = JSON.parse(json);
    return engines;
  } catch {
    return {};
  }
};

const mergeEngine = (engines, engine, value) => {
  const range = value.trim();
  if (range === '' || validRange(range) === null) {
    return;
  }
  const current = engines[engine] ?? '0.0.0';
  if (satisfies(current, range)) {
    return;
  }
  // TODO does not handle the following case:
  // range: 14.0.0 || 16.1.0 || 18.0.0
  // current: 16.0.0
  const version = minVersion(range).raw;
  const newCurrent = compare(version, current) === -1 ? current : version;
  // 16.0.0 instead of 16.1.0
  engines[engine] = newCurrent;
  //
};

const result = {};

try {
  for await (const file of getPackageJsonFiles(nodeModulesPath)) {
    const engines = await getEngines(file);
    for (const engine of Object.keys(engines)) {
      mergeEngine(result, engine, engines[engine]);
    }
  }
  console.log(JSON.stringify(result));
} catch (e) {
  console.error(e);
}

It will crawl the given node_modules folder and return an object one can use for the engines in your project.

Example output

{"node":"18.12.0","npm":"1.0.0","iojs":"1.0.0"}

See the TODO for the case the script cannot handle right now without one of the suggested function additions.

Lingua principale
JavaScript
Stelle
5.5k
Fork
624
Merge medio
6g 1h
PR unite (30g)
13

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di npm/node-semver

Tutte le issue di npm/node-semver

Issue simili

Altre issue su JavaScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.