@jbrowse/cli 4.3.0 → 5.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +451 -72
- package/dist/base.js +0 -3
- package/dist/bin.js +2 -1
- package/dist/cliFetch.js +3 -0
- package/dist/commands/add-assembly/index.js +46 -19
- package/dist/commands/add-assembly/utils.js +204 -290
- package/dist/commands/add-connection.js +73 -79
- package/dist/commands/add-track-json.js +24 -12
- package/dist/commands/add-track-utils/adapter-utils.js +189 -288
- package/dist/commands/add-track-utils/file-operations.js +27 -11
- package/dist/commands/add-track-utils/multiwig.js +47 -0
- package/dist/commands/add-track-utils/track-config.js +66 -25
- package/dist/commands/add-track-utils/validators.js +36 -20
- package/dist/commands/add-track.js +200 -62
- package/dist/commands/admin-server/index.js +39 -50
- package/dist/commands/admin-server/utils.js +238 -126
- package/dist/commands/create.js +18 -34
- package/dist/commands/make-density/density-generator.js +180 -0
- package/dist/commands/make-density/index.js +139 -0
- package/dist/commands/make-pif/index.js +133 -11
- package/dist/commands/make-pif/pif-generator.js +243 -43
- package/dist/commands/process-utils.js +13 -2
- package/dist/commands/remove-track.js +20 -13
- package/dist/commands/set-default-session.js +35 -31
- package/dist/commands/shared/config-operations.js +3 -10
- package/dist/commands/shared/density.js +12 -0
- package/dist/commands/shared/sort-utils.js +67 -10
- package/dist/commands/shared/validators.js +38 -3
- package/dist/commands/sort-bed.js +2 -33
- package/dist/commands/sort-gff.js +2 -33
- package/dist/commands/text-index/adapter-utils.js +19 -26
- package/dist/commands/text-index/aggregate.js +40 -34
- package/dist/commands/text-index/command.js +37 -7
- package/dist/commands/text-index/config-utils.js +62 -85
- package/dist/commands/text-index/file-list.js +32 -18
- package/dist/commands/text-index/index.js +4 -4
- package/dist/commands/text-index/indexing-utils.js +44 -96
- package/dist/commands/text-index/per-track.js +44 -31
- package/dist/commands/text-index/validators.js +1 -1
- package/dist/commands/upgrade.js +20 -32
- package/dist/commands/validate/configManifest.generated.js +7613 -0
- package/dist/commands/validate/configSchema.generated.js +20400 -0
- package/dist/commands/validate/displayDefaultKeys.js +28 -0
- package/dist/commands/validate/index.js +113 -0
- package/dist/commands/validate/liftConfig.js +34 -0
- package/dist/commands/validate/markRules/aggregateFieldName.js +9 -0
- package/dist/commands/validate/markRules/autoBin.js +27 -0
- package/dist/commands/validate/markRules/colorScale.js +244 -0
- package/dist/commands/validate/markRules/cssColorsLevel4.js +162 -0
- package/dist/commands/validate/markRules/jexlStrings.js +23 -0
- package/dist/commands/validate/markRules/markProblems.js +532 -0
- package/dist/commands/validate/markRules/markRuleFacts.js +6 -0
- package/dist/commands/validate/markRules/markSpecs.js +96 -0
- package/dist/commands/validate/markRules/markVocabulary.js +57 -0
- package/dist/commands/validate/markRules/shapeNameList.js +7 -0
- package/dist/commands/validate/markRules/stepChannels.js +55 -0
- package/dist/commands/validate/schemaValidate.js +425 -0
- package/dist/commands/validate/suggest.js +35 -0
- package/dist/commands/validate/types.js +6 -0
- package/dist/commands/validate/validateConfig.js +502 -0
- package/dist/index.js +104 -50
- package/dist/types/common.js +3 -27
- package/dist/utils.js +309 -128
- package/dist/version.js +1 -1
- package/package.json +8 -14
- package/bin/run +0 -4
- package/bundle/index.js +0 -3686
- package/dist/commands/make-pif/cigar-utils.js +0 -24
- package/dist/commands/make-pif/file-utils.js +0 -30
- package/dist/commands/track-utils.js +0 -74
- package/dist/util.js +0 -35
|
@@ -1,110 +1,58 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Readable } from 'stream';
|
|
3
|
-
import { generateMeta, guessAdapterFromFileName, indexGff3, indexVcf, } from '@jbrowse/text-indexing-core';
|
|
1
|
+
import { guessAdapterFromFileName, writeTrixIndex, } from '@jbrowse/text-indexing-core';
|
|
4
2
|
import { Presets, SingleBar } from 'cli-progress';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export async function runIxIxx({ readStream, outLocation, name, prefixSize, quiet, }) {
|
|
9
|
-
const progressBar = new SingleBar({ format: '{bar} Sorting and writing index...', etaBuffer: 2000 }, Presets.shades_classic);
|
|
10
|
-
if (!quiet) {
|
|
11
|
-
progressBar.start(1, 0);
|
|
12
|
-
}
|
|
13
|
-
const ixPath = path.join(outLocation, 'trix', `${name}.ix`);
|
|
14
|
-
const ixxPath = path.join(outLocation, 'trix', `${name}.ixx`);
|
|
15
|
-
await ixIxxStream(readStream, ixPath, ixxPath, prefixSize);
|
|
16
|
-
if (!quiet) {
|
|
17
|
-
progressBar.update(1);
|
|
18
|
-
progressBar.stop();
|
|
19
|
-
}
|
|
3
|
+
import { supported } from '../../types/common.js';
|
|
4
|
+
function bar(format) {
|
|
5
|
+
return new SingleBar({ format, etaBuffer: 2000 }, Presets.shades_classic);
|
|
20
6
|
}
|
|
21
|
-
export async function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const { indexingFeatureTypesToExclude = typesToExclude, indexingAttributes = attributes, } = textSearching || {};
|
|
26
|
-
const loc = getAdapterLocation(adapter);
|
|
27
|
-
if (!loc) {
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
const progressBar = new SingleBar({
|
|
31
|
-
format: `{bar} ${trackId} {percentage}% | ETA: {eta}s`,
|
|
32
|
-
etaBuffer: 2000,
|
|
33
|
-
}, Presets.shades_classic);
|
|
34
|
-
if (type === 'Gff3TabixAdapter' || type === 'Gff3Adapter') {
|
|
35
|
-
yield* indexGff3({
|
|
36
|
-
config,
|
|
37
|
-
attributesToIndex: indexingAttributes,
|
|
38
|
-
inLocation: getLoc(loc),
|
|
39
|
-
outDir: outLocation,
|
|
40
|
-
featureTypesToExclude: indexingFeatureTypesToExclude,
|
|
41
|
-
onStart: totalBytes => {
|
|
42
|
-
if (!quiet) {
|
|
43
|
-
progressBar.start(totalBytes, 0);
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
onUpdate: receivedBytes => {
|
|
47
|
-
if (!quiet) {
|
|
48
|
-
progressBar.update(receivedBytes);
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
else if (type === 'VcfTabixAdapter' || type === 'VcfAdapter') {
|
|
54
|
-
yield* indexVcf({
|
|
55
|
-
config,
|
|
56
|
-
attributesToIndex: indexingAttributes,
|
|
57
|
-
inLocation: getLoc(loc),
|
|
58
|
-
outDir: outLocation,
|
|
59
|
-
onStart: totalBytes => {
|
|
60
|
-
if (!quiet) {
|
|
61
|
-
progressBar.start(totalBytes, 0);
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
onUpdate: receivedBytes => {
|
|
65
|
-
if (!quiet) {
|
|
66
|
-
progressBar.update(receivedBytes);
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
if (!quiet) {
|
|
72
|
-
progressBar.stop();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
export async function indexDriver({ trackConfigs, attributes, outLocation, name, quiet, typesToExclude, assemblyNames, prefixSize, }) {
|
|
77
|
-
const readStream = Readable.from(indexFiles({
|
|
78
|
-
trackConfigs,
|
|
79
|
-
attributes,
|
|
80
|
-
outLocation,
|
|
81
|
-
quiet,
|
|
82
|
-
typesToExclude,
|
|
83
|
-
}));
|
|
84
|
-
await runIxIxx({
|
|
85
|
-
readStream,
|
|
86
|
-
outLocation,
|
|
87
|
-
name,
|
|
88
|
-
prefixSize,
|
|
89
|
-
quiet,
|
|
90
|
-
});
|
|
91
|
-
generateMeta({
|
|
92
|
-
configs: trackConfigs,
|
|
93
|
-
attributesToIndex: attributes,
|
|
7
|
+
export async function indexDriver({ trackConfigs, policy, outLocation, name, quiet, assemblyNames, prefixSize, }) {
|
|
8
|
+
let sortBar;
|
|
9
|
+
await writeTrixIndex({
|
|
10
|
+
tracks: trackConfigs,
|
|
94
11
|
outDir: outLocation,
|
|
95
12
|
name,
|
|
96
|
-
|
|
13
|
+
policy,
|
|
97
14
|
assemblyNames,
|
|
15
|
+
prefixSize,
|
|
16
|
+
onSort: quiet
|
|
17
|
+
? undefined
|
|
18
|
+
: () => {
|
|
19
|
+
sortBar = bar('{bar} Sorting and writing index...');
|
|
20
|
+
sortBar.start(1, 0);
|
|
21
|
+
},
|
|
22
|
+
makeProgress: quiet
|
|
23
|
+
? undefined
|
|
24
|
+
: trackId => {
|
|
25
|
+
const progressBar = bar(
|
|
26
|
+
// eslint-disable-next-line unicorn/no-incorrect-template-string-interpolation -- {bar}/{percentage}/{eta} are cli-progress format tokens, not JS interpolation
|
|
27
|
+
`{bar} ${trackId} {percentage}% | ETA: {eta}s`);
|
|
28
|
+
return {
|
|
29
|
+
onStart: totalBytes => {
|
|
30
|
+
progressBar.start(totalBytes, 0);
|
|
31
|
+
},
|
|
32
|
+
onUpdate: receivedBytes => {
|
|
33
|
+
progressBar.update(receivedBytes);
|
|
34
|
+
},
|
|
35
|
+
onDone: () => {
|
|
36
|
+
progressBar.stop();
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
},
|
|
98
40
|
});
|
|
41
|
+
sortBar?.update(1);
|
|
42
|
+
sortBar?.stop();
|
|
99
43
|
}
|
|
100
44
|
export function prepareFileTrackConfigs(files, fileIds) {
|
|
101
|
-
return files
|
|
102
|
-
.map((file, i) => {
|
|
45
|
+
return files.map((file, i) => {
|
|
103
46
|
const config = guessAdapterFromFileName(file);
|
|
104
47
|
if (fileIds?.[i]) {
|
|
105
48
|
config.trackId = fileIds[i];
|
|
106
49
|
}
|
|
50
|
+
// throw rather than silently filtering: a user who named the file with
|
|
51
|
+
// --file should be told it can't be indexed instead of getting a misleading
|
|
52
|
+
// "successfully created index" with no output
|
|
53
|
+
if (!supported(config.adapter?.type)) {
|
|
54
|
+
throw new Error(`Cannot text-index ${file}: adapter type ${config.adapter?.type} is not indexable (only GFF3, GTF and VCF are supported)`);
|
|
55
|
+
}
|
|
107
56
|
return config;
|
|
108
|
-
})
|
|
109
|
-
.filter(fileConfig => supported(fileConfig.adapter?.type));
|
|
57
|
+
});
|
|
110
58
|
}
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { parseCommaSeparatedString, writeJsonFile } from '../../utils.js';
|
|
2
|
+
import { createTrixAdapter } from './adapter-utils.js';
|
|
3
|
+
import { formatDryRun, getTrackConfigs, loadConfigForIndexing, prepareIndexDriverFlags, } from './config-utils.js';
|
|
4
|
+
import { indexDriver } from './indexing-utils.js';
|
|
5
|
+
import { validateAssembliesForPerTrack, validateTrackConfigs, } from './validators.js';
|
|
6
6
|
export async function perTrackIndex(flags) {
|
|
7
|
-
const { out, target, tracks, excludeTracks, assemblies, attributes, quiet, force, exclude, prefixSize, } = flags;
|
|
8
|
-
const { config, configPath, outLocation } = await loadConfigForIndexing(target, out, resolveConfigPath);
|
|
9
|
-
const configTracks = config.tracks || [];
|
|
7
|
+
const { out, target, tracks, excludeTracks, assemblies, attributes, quiet, force, exclude, include, prefixSize, dryrun, } = flags;
|
|
10
8
|
validateAssembliesForPerTrack(assemblies);
|
|
9
|
+
const { config, configPath, outLocation } = await loadConfigForIndexing(target, out);
|
|
10
|
+
const configTracks = config.tracks ?? [];
|
|
11
11
|
const confs = getTrackConfigs(config, parseCommaSeparatedString(tracks), undefined, parseCommaSeparatedString(excludeTracks));
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
validateTrackConfigs(confs);
|
|
13
|
+
if (dryrun) {
|
|
14
|
+
console.log(formatDryRun(confs));
|
|
15
|
+
return;
|
|
14
16
|
}
|
|
15
|
-
|
|
17
|
+
// sequential, not Promise.all: each track's indexer owns the progress bar and
|
|
18
|
+
// streams a whole file through ixIxx
|
|
19
|
+
const indexed = [];
|
|
16
20
|
for (const trackConfig of confs) {
|
|
17
21
|
const { textSearching, trackId, assemblyNames } = trackConfig;
|
|
18
22
|
if (textSearching?.textSearchAdapter && !force) {
|
|
@@ -25,27 +29,36 @@ export async function perTrackIndex(flags) {
|
|
|
25
29
|
outLocation,
|
|
26
30
|
name: trackId,
|
|
27
31
|
assemblyNames,
|
|
28
|
-
...prepareIndexDriverFlags({
|
|
32
|
+
...prepareIndexDriverFlags({
|
|
33
|
+
attributes,
|
|
34
|
+
exclude,
|
|
35
|
+
include,
|
|
36
|
+
quiet,
|
|
37
|
+
prefixSize,
|
|
38
|
+
}),
|
|
29
39
|
});
|
|
30
|
-
|
|
31
|
-
// modifies track with new text search adapter
|
|
32
|
-
const index = configTracks.findIndex(track => trackId === track.trackId);
|
|
33
|
-
if (index !== -1) {
|
|
34
|
-
configTracks[index] = {
|
|
35
|
-
...trackConfig,
|
|
36
|
-
textSearching: {
|
|
37
|
-
...textSearching,
|
|
38
|
-
textSearchAdapter: createTrixAdapter(trackId, assemblyNames),
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
hasChanges = true;
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
console.warn(`Warning: can't find trackId ${trackId}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
40
|
+
indexed.push(trackConfig);
|
|
47
41
|
}
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
// a track that already carried an adapter keeps it — re-indexing under --force
|
|
43
|
+
// refreshes the trix files the existing adapter already points at. The rest
|
|
44
|
+
// gain one naming the files just written. getTrackConfigs returns elements of
|
|
45
|
+
// config.tracks, so every indexed track is somewhere in configTracks.
|
|
46
|
+
const newAdapters = new Map(indexed
|
|
47
|
+
.filter(track => !track.textSearching?.textSearchAdapter)
|
|
48
|
+
.map(track => [
|
|
49
|
+
track.trackId,
|
|
50
|
+
createTrixAdapter(track.trackId, track.assemblyNames),
|
|
51
|
+
]));
|
|
52
|
+
const updatedTracks = configTracks.map(track => {
|
|
53
|
+
const textSearchAdapter = newAdapters.get(track.trackId);
|
|
54
|
+
return textSearchAdapter
|
|
55
|
+
? {
|
|
56
|
+
...track,
|
|
57
|
+
textSearching: { ...track.textSearching, textSearchAdapter },
|
|
58
|
+
}
|
|
59
|
+
: track;
|
|
60
|
+
});
|
|
61
|
+
if (updatedTracks.some((track, i) => track !== configTracks[i])) {
|
|
62
|
+
await writeJsonFile(configPath, { ...config, tracks: updatedTracks });
|
|
50
63
|
}
|
|
51
64
|
}
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { parseArgs } from 'util';
|
|
4
|
-
import
|
|
5
|
-
import fetch from "../cliFetch.js";
|
|
6
|
-
import { fetchGithubVersions, getBranch, getLatest, getTag, printHelp, } from "../utils.js";
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { parseArgs } from 'node:util';
|
|
4
|
+
import { downloadRelease, extractZip, printHelp, printVersions, } from '../utils.js';
|
|
7
5
|
const description = 'Upgrades JBrowse 2 to latest version';
|
|
8
6
|
const examples = [
|
|
9
7
|
'# Upgrades current directory to latest jbrowse release',
|
|
@@ -65,8 +63,6 @@ export async function run(args) {
|
|
|
65
63
|
args,
|
|
66
64
|
allowPositionals: true,
|
|
67
65
|
});
|
|
68
|
-
const argsPath = positionals[0];
|
|
69
|
-
const { clean, listVersions, tag, url, branch, nightly } = runFlags;
|
|
70
66
|
if (runFlags.help) {
|
|
71
67
|
printHelp({
|
|
72
68
|
options,
|
|
@@ -76,41 +72,33 @@ export async function run(args) {
|
|
|
76
72
|
});
|
|
77
73
|
return;
|
|
78
74
|
}
|
|
75
|
+
const { clean, listVersions, tag, url, branch, nightly } = runFlags;
|
|
79
76
|
if (listVersions) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
process.exit(0);
|
|
83
|
-
}
|
|
84
|
-
if (!argsPath) {
|
|
85
|
-
throw new Error('No directory supplied');
|
|
77
|
+
await printVersions();
|
|
78
|
+
return;
|
|
86
79
|
}
|
|
80
|
+
// localPath is optional: `jbrowse upgrade` upgrades the install in the
|
|
81
|
+
// current directory, as the examples and docs advertise
|
|
82
|
+
const argsPath = positionals[0] ?? '.';
|
|
87
83
|
if (!fs.existsSync(path.join(argsPath, 'manifest.json'))) {
|
|
88
84
|
throw new Error(`No manifest.json found in this directory, are you sure it is an
|
|
89
85
|
existing jbrowse 2 installation?`);
|
|
90
86
|
}
|
|
91
|
-
const locationUrl =
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (!response.ok) {
|
|
98
|
-
throw new Error(`HTTP ${response.status} fetching ${locationUrl}: ${response.statusText}`);
|
|
99
|
-
}
|
|
100
|
-
const type = response.headers.get('content-type');
|
|
101
|
-
if (url &&
|
|
102
|
-
type !== 'application/zip' &&
|
|
103
|
-
type !== 'application/octet-stream') {
|
|
104
|
-
throw new Error('The URL provided does not seem to be a JBrowse installation URL');
|
|
105
|
-
}
|
|
87
|
+
const { locationUrl, archive } = await downloadRelease({
|
|
88
|
+
url,
|
|
89
|
+
nightly,
|
|
90
|
+
branch,
|
|
91
|
+
tag,
|
|
92
|
+
});
|
|
106
93
|
if (clean) {
|
|
107
94
|
fs.rmSync(path.join(argsPath, 'static'), { recursive: true, force: true });
|
|
108
|
-
|
|
95
|
+
const workerFiles = fs
|
|
109
96
|
.readdirSync(argsPath)
|
|
110
|
-
.filter(f => f.includes('worker.js'))
|
|
97
|
+
.filter(f => f.includes('worker.js'));
|
|
98
|
+
for (const f of workerFiles) {
|
|
111
99
|
fs.unlinkSync(path.join(argsPath, f));
|
|
112
100
|
}
|
|
113
101
|
}
|
|
114
|
-
await
|
|
102
|
+
await extractZip(archive, argsPath);
|
|
115
103
|
console.log(`Unpacked ${locationUrl} at ${argsPath}`);
|
|
116
104
|
}
|