@jbrowse/cli 2.8.0 → 2.10.0

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 CHANGED
@@ -54,6 +54,7 @@ It is likely preferable in most cases to install the tools globally with
54
54
  - [`jbrowse admin-server`](#jbrowse-admin-server)
55
55
  - [`jbrowse create LOCALPATH`](#jbrowse-create-localpath)
56
56
  - [`jbrowse help [COMMANDS]`](#jbrowse-help-commands)
57
+ - [`jbrowse make-pif FILE`](#jbrowse-make-pif-file)
57
58
  - [`jbrowse remove-track TRACK`](#jbrowse-remove-track-track)
58
59
  - [`jbrowse set-default-session`](#jbrowse-set-default-session)
59
60
  - [`jbrowse sort-gff FILE`](#jbrowse-sort-gff-file)
@@ -204,7 +205,7 @@ EXAMPLES
204
205
  ```
205
206
 
206
207
  _See code:
207
- [src/commands/add-assembly.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/add-assembly.ts)_
208
+ [src/commands/add-assembly.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/add-assembly.ts)_
208
209
 
209
210
  ## `jbrowse add-connection CONNECTIONURLORPATH`
210
211
 
@@ -229,13 +230,13 @@ FLAGS
229
230
  -h, --help Show CLI help.
230
231
  -n, --name=<value> Name of the connection. Defaults to connectionId if not provided
231
232
  -t, --type=<value> type of connection, ex. JBrowse1Connection, UCSCTrackHubConnection, custom
232
- --connectionId=<value> Id for the connection that must be unique to JBrowse. Defaults to
233
+ --connectionId=<value> Id for the connection that must be unique to JBrowse. Defaults to
233
234
  'connectionType-assemblyName-currentTime'
234
- --out=<value> synonym for target
235
- --overwrite Overwrites any existing connections if same connection id
236
- --skipCheck Don't check whether or not the data directory URL exists or if you are in a JBrowse
235
+ --out=<value> synonym for target
236
+ --overwrite Overwrites any existing connections if same connection id
237
+ --skipCheck Don't check whether or not the data directory URL exists or if you are in a JBrowse
237
238
  directory
238
- --target=<value> path to config file in JB2 installation directory to write out to.
239
+ --target=<value> path to config file in JB2 installation directory to write out to.
239
240
 
240
241
  DESCRIPTION
241
242
  Add a connection to a JBrowse 2 configuration
@@ -255,7 +256,7 @@ EXAMPLES
255
256
  ```
256
257
 
257
258
  _See code:
258
- [src/commands/add-connection.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/add-connection.ts)_
259
+ [src/commands/add-connection.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/add-connection.ts)_
259
260
 
260
261
  ## `jbrowse add-track TRACK`
261
262
 
@@ -282,18 +283,18 @@ FLAGS
282
283
  <options: copy|symlink|move|inPlace>
283
284
  -n, --name=<value> Name of the track. Will be defaulted to the trackId if none specified
284
285
  -t, --trackType=<value> Type of track, by default inferred from track file
285
- --bed1=<value> Used only for mcscan anchors/simpleAnchors types
286
- --bed2=<value> Used only for mcscan anchors/simpleAnchors types
287
- --category=<value> Optional Comma separated string of categories to group tracks
288
- --config=<value> Any extra config settings to add to a track. i.e '{"defaultRendering": "density"}'
289
- --indexFile=<value> Optional index file for the track
290
- --out=<value> synonym for target
291
- --overwrite Overwrites existing track if it shares the same trackId
292
- --protocol=<value> [default: uri] Force protocol to a specific value
293
- --skipCheck Skip check for whether or not the file or URL exists or if you are in a JBrowse directory
294
- --subDir=<value> when using --load a file, output to a subdirectory of the target dir
295
- --target=<value> path to config file in JB2 installation to write out to.
296
- --trackId=<value> trackId for the track, by default inferred from filename, must be unique throughout
286
+ --bed1=<value> Used only for mcscan anchors/simpleAnchors types
287
+ --bed2=<value> Used only for mcscan anchors/simpleAnchors types
288
+ --category=<value> Optional Comma separated string of categories to group tracks
289
+ --config=<value> Any extra config settings to add to a track. i.e '{"defaultRendering": "density"}'
290
+ --indexFile=<value> Optional index file for the track
291
+ --out=<value> synonym for target
292
+ --overwrite Overwrites existing track if it shares the same trackId
293
+ --protocol=<value> [default: uri] Force protocol to a specific value
294
+ --skipCheck Skip check for whether or not the file or URL exists or if you are in a JBrowse directory
295
+ --subDir=<value> when using --load a file, output to a subdirectory of the target dir
296
+ --target=<value> path to config file in JB2 installation to write out to.
297
+ --trackId=<value> trackId for the track, by default inferred from filename, must be unique throughout
297
298
  config
298
299
 
299
300
  DESCRIPTION
@@ -336,7 +337,7 @@ EXAMPLES
336
337
  ```
337
338
 
338
339
  _See code:
339
- [src/commands/add-track.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/add-track.ts)_
340
+ [src/commands/add-track.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/add-track.ts)_
340
341
 
341
342
  ## `jbrowse add-track-json TRACK`
342
343
 
@@ -351,10 +352,10 @@ ARGUMENTS
351
352
  TRACK track JSON file or command line arg blob
352
353
 
353
354
  FLAGS
354
- -u, --update update the contents of an existing track, matched based on trackId
355
- --out=<value> synonym for target
356
- --target=<value> path to config file in JB2 installation directory to write out to.
357
- Creates ./config.json if nonexistent
355
+ -u, --update update the contents of an existing track, matched based on trackId
356
+ --out=<value> synonym for target
357
+ --target=<value> path to config file in JB2 installation directory to write out to.
358
+ Creates ./config.json if nonexistent
358
359
 
359
360
  DESCRIPTION
360
361
  Add a track configuration directly from a JSON hunk to the JBrowse 2 configuration
@@ -366,7 +367,7 @@ EXAMPLES
366
367
  ```
367
368
 
368
369
  _See code:
369
- [src/commands/add-track-json.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/add-track-json.ts)_
370
+ [src/commands/add-track-json.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/add-track-json.ts)_
370
371
 
371
372
  ## `jbrowse admin-server`
372
373
 
@@ -377,15 +378,16 @@ USAGE
377
378
  $ jbrowse admin-server [-p <value>] [--root <value>] [--bodySizeLimit <value>] [-h]
378
379
 
379
380
  FLAGS
380
- -h, --help Show CLI help.
381
- -p, --port=<value> Specifified port to start the server on;
382
- Default is 9090.
383
- --bodySizeLimit=<value> [default: 25mb] Size limit of the update message; may need to increase if config is large.
384
- Argument is passed to bytes library for parsing: https://www.npmjs.com/package/bytes.
385
- --root=<value> path to the root of the JB2 installation.
386
- Creates ./config.json if nonexistent. note that you can navigate to
387
- ?config=path/to/subconfig.json in the web browser and it will write to
388
- rootDir/path/to/subconfig.json
381
+ -h, --help Show CLI help.
382
+ -p, --port=<value> Specifified port to start the server on;
383
+ Default is 9090.
384
+ --bodySizeLimit=<value> [default: 25mb] Size limit of the update message; may need to increase if config is
385
+ large.
386
+ Argument is passed to bytes library for parsing: https://www.npmjs.com/package/bytes.
387
+ --root=<value> path to the root of the JB2 installation.
388
+ Creates ./config.json if nonexistent. note that you can navigate to
389
+ ?config=path/to/subconfig.json in the web browser and it will write to
390
+ rootDir/path/to/subconfig.json
389
391
 
390
392
  DESCRIPTION
391
393
  Start up a small admin server for JBrowse configuration
@@ -397,7 +399,7 @@ EXAMPLES
397
399
  ```
398
400
 
399
401
  _See code:
400
- [src/commands/admin-server.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/admin-server.ts)_
402
+ [src/commands/admin-server.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/admin-server.ts)_
401
403
 
402
404
  ## `jbrowse create LOCALPATH`
403
405
 
@@ -411,14 +413,14 @@ ARGUMENTS
411
413
  LOCALPATH Location where JBrowse 2 will be installed
412
414
 
413
415
  FLAGS
414
- -f, --force Overwrites existing JBrowse 2 installation if present in path
415
- -h, --help Show CLI help.
416
- -l, --listVersions Lists out all versions of JBrowse 2
417
- -t, --tag=<value> Version of JBrowse 2 to install. Format is v1.0.0.
418
- Defaults to latest
419
- -u, --url=<value> A direct URL to a JBrowse 2 release
420
- --branch=<value> Download a development build from a named git branch
421
- --nightly Download the latest development build from the main branch
416
+ -f, --force Overwrites existing JBrowse 2 installation if present in path
417
+ -h, --help Show CLI help.
418
+ -l, --listVersions Lists out all versions of JBrowse 2
419
+ -t, --tag=<value> Version of JBrowse 2 to install. Format is v1.0.0.
420
+ Defaults to latest
421
+ -u, --url=<value> A direct URL to a JBrowse 2 release
422
+ --branch=<value> Download a development build from a named git branch
423
+ --nightly Download the latest development build from the main branch
422
424
 
423
425
  DESCRIPTION
424
426
  Downloads and installs the latest JBrowse 2 release
@@ -454,7 +456,7 @@ EXAMPLES
454
456
  ```
455
457
 
456
458
  _See code:
457
- [src/commands/create.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/create.ts)_
459
+ [src/commands/create.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/create.ts)_
458
460
 
459
461
  ## `jbrowse help [COMMANDS]`
460
462
 
@@ -477,6 +479,36 @@ DESCRIPTION
477
479
  _See code:
478
480
  [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.2.20/src/commands/help.ts)_
479
481
 
482
+ ## `jbrowse make-pif FILE`
483
+
484
+ creates pairwise indexed PAF (PIF), with bgzip and tabix
485
+
486
+ ```
487
+ USAGE
488
+ $ jbrowse make-pif FILE [--out <value>] [--csi] [-h]
489
+
490
+ ARGUMENTS
491
+ FILE PAF file as input
492
+
493
+ FLAGS
494
+ -h, --help Show CLI help.
495
+ --csi Create a CSI index for the PIF file instead of TBI
496
+ --out=<value> Where to write the output file. will write ${file}.pif.gz and ${file}.pif.gz.tbi
497
+
498
+ DESCRIPTION
499
+ creates pairwise indexed PAF (PIF), with bgzip and tabix
500
+
501
+ EXAMPLES
502
+ $ jbrowse pif input.paf # creates input.pif.gz in same directory
503
+
504
+
505
+
506
+ $ jbrowse pif input.paf --out output.pif.gz # specify output file, creates output.pif.gz.tbi also
507
+ ```
508
+
509
+ _See code:
510
+ [src/commands/make-pif.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/make-pif.ts)_
511
+
480
512
  ## `jbrowse remove-track TRACK`
481
513
 
482
514
  Remove a track configuration from a JBrowse 2 configuration. Be aware that this
@@ -503,7 +535,7 @@ EXAMPLES
503
535
  ```
504
536
 
505
537
  _See code:
506
- [src/commands/remove-track.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/remove-track.ts)_
538
+ [src/commands/remove-track.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/remove-track.ts)_
507
539
 
508
540
  ## `jbrowse set-default-session`
509
541
 
@@ -523,10 +555,10 @@ FLAGS
523
555
  -v, --view=<value> View type in config to be added as default session, i.e LinearGenomeView, CircularView,
524
556
  DotplotView.
525
557
  Must be provided if no default session file provided
526
- --delete Delete any existing default session.
527
- --out=<value> synonym for target
528
- --target=<value> path to config file in JB2 installation directory to write out to
529
- --viewId=<value> Identifier for the view. Will be generated on default
558
+ --delete Delete any existing default session.
559
+ --out=<value> synonym for target
560
+ --target=<value> path to config file in JB2 installation directory to write out to
561
+ --viewId=<value> Identifier for the view. Will be generated on default
530
562
 
531
563
  DESCRIPTION
532
564
  Set a default session with views and tracks
@@ -542,7 +574,7 @@ EXAMPLES
542
574
  ```
543
575
 
544
576
  _See code:
545
- [src/commands/set-default-session.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/set-default-session.ts)_
577
+ [src/commands/set-default-session.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/set-default-session.ts)_
546
578
 
547
579
  ## `jbrowse sort-gff FILE`
548
580
 
@@ -552,11 +584,14 @@ sort and grep
552
584
 
553
585
  ```
554
586
  USAGE
555
- $ jbrowse sort-gff FILE
587
+ $ jbrowse sort-gff FILE [-h]
556
588
 
557
589
  ARGUMENTS
558
590
  FILE GFF file
559
591
 
592
+ FLAGS
593
+ -h, --help Show CLI help.
594
+
560
595
  DESCRIPTION
561
596
  Helper utility to sort GFF files for tabix. Moves all lines starting with # to the top of the file, and sort by
562
597
  refname and start position using unix utilities sort and grep
@@ -570,7 +605,7 @@ EXAMPLES
570
605
  ```
571
606
 
572
607
  _See code:
573
- [src/commands/sort-gff.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/sort-gff.ts)_
608
+ [src/commands/sort-gff.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/sort-gff.ts)_
574
609
 
575
610
  ## `jbrowse text-index`
576
611
 
@@ -587,20 +622,20 @@ FLAGS
587
622
  assembly in the config
588
623
  -h, --help Show CLI help.
589
624
  -q, --quiet Hide the progress bars
590
- --attributes=<value> [default: Name,ID] Comma separated list of attributes to index
591
- --dryrun Just print out tracks that will be indexed by the process, without doing any indexing
592
- --exclude=<value> [default: CDS,exon] Adds gene type to list of excluded types
593
- --file=<value>... File or files to index (can be used to create trix indexes for embedded component use cases
625
+ --attributes=<value> [default: Name,ID] Comma separated list of attributes to index
626
+ --dryrun Just print out tracks that will be indexed by the process, without doing any indexing
627
+ --exclude=<value> [default: CDS,exon] Adds gene type to list of excluded types
628
+ --file=<value>... File or files to index (can be used to create trix indexes for embedded component use cases
594
629
  not using a config.json for example)
595
- --fileId=<value>... Set the trackId used for the indexes generated with the --file argument
596
- --force Overwrite previously existing indexes
597
- --out=<value> Synonym for target
598
- --perTrack If set, creates an index per track
599
- --prefixSize=<value> Specify the prefix size for the ixx index. We attempt to automatically calculate this, but
630
+ --fileId=<value>... Set the trackId used for the indexes generated with the --file argument
631
+ --force Overwrite previously existing indexes
632
+ --out=<value> Synonym for target
633
+ --perTrack If set, creates an index per track
634
+ --prefixSize=<value> Specify the prefix size for the ixx index. We attempt to automatically calculate this, but
600
635
  you can manually specify this too. If many genes have similar gene IDs e.g. Z000000001,
601
636
  Z000000002 the prefix size should be larger so that they get split into different bins
602
- --target=<value> Path to config file in JB2 installation directory to read from.
603
- --tracks=<value> Specific tracks to index, formatted as comma separated trackIds. If unspecified, indexes all
637
+ --target=<value> Path to config file in JB2 installation directory to read from.
638
+ --tracks=<value> Specific tracks to index, formatted as comma separated trackIds. If unspecified, indexes all
604
639
  available tracks
605
640
 
606
641
  DESCRIPTION
@@ -637,7 +672,7 @@ EXAMPLES
637
672
  ```
638
673
 
639
674
  _See code:
640
- [src/commands/text-index.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/text-index.ts)_
675
+ [src/commands/text-index.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/text-index.ts)_
641
676
 
642
677
  ## `jbrowse upgrade [LOCALPATH]`
643
678
 
@@ -651,14 +686,14 @@ ARGUMENTS
651
686
  LOCALPATH [default: .] Location where JBrowse 2 is installed
652
687
 
653
688
  FLAGS
654
- -h, --help Show CLI help.
655
- -l, --listVersions Lists out all versions of JBrowse 2
656
- -t, --tag=<value> Version of JBrowse 2 to install. Format is v1.0.0.
657
- Defaults to latest
658
- -u, --url=<value> A direct URL to a JBrowse 2 release
659
- --branch=<value> Download a development build from a named git branch
660
- --clean Removes old js,map,and LICENSE files in the installation
661
- --nightly Download the latest development build from the main branch
689
+ -h, --help Show CLI help.
690
+ -l, --listVersions Lists out all versions of JBrowse 2
691
+ -t, --tag=<value> Version of JBrowse 2 to install. Format is v1.0.0.
692
+ Defaults to latest
693
+ -u, --url=<value> A direct URL to a JBrowse 2 release
694
+ --branch=<value> Download a development build from a named git branch
695
+ --clean Removes old js,map,and LICENSE files in the installation
696
+ --nightly Download the latest development build from the main branch
662
697
 
663
698
  DESCRIPTION
664
699
  Upgrades JBrowse 2 to latest version
@@ -700,7 +735,7 @@ EXAMPLES
700
735
  ```
701
736
 
702
737
  _See code:
703
- [src/commands/upgrade.ts](https://github.com/GMOD/jbrowse-components/blob/v2.8.0/products/jbrowse-cli/src/commands/upgrade.ts)_
738
+ [src/commands/upgrade.ts](https://github.com/GMOD/jbrowse-components/blob/v2.10.0/products/jbrowse-cli/src/commands/upgrade.ts)_
704
739
 
705
740
  <!-- commandsstop -->
706
741
 
@@ -27,6 +27,34 @@ function makeLocationProtocol(protocol) {
27
27
  throw new Error(`invalid protocol ${protocol}`);
28
28
  };
29
29
  }
30
+ function fileOperation({ srcFilename, destFilename, mode, }) {
31
+ if (mode === 'copy') {
32
+ return copyFile(srcFilename, destFilename, COPYFILE_EXCL);
33
+ }
34
+ else if (mode === 'move') {
35
+ return rename(srcFilename, destFilename);
36
+ }
37
+ else if (mode === 'symlink') {
38
+ return symlink(path_1.default.resolve(srcFilename), destFilename);
39
+ }
40
+ return undefined;
41
+ }
42
+ // get path of destination, and remove file at that path if it exists and force
43
+ // is set
44
+ function destinationFn({ destinationDir, srcFilename, subDir, force, }) {
45
+ const dest = path_1.default.resolve(path_1.default.join(destinationDir, subDir, path_1.default.basename(srcFilename)));
46
+ if (force) {
47
+ try {
48
+ fs_1.default.unlinkSync(dest);
49
+ }
50
+ catch (e) {
51
+ /* unconditionally unlinkSync, due to
52
+ * https://github.com/nodejs/node/issues/14025#issuecomment-754021370
53
+ * and https://github.com/GMOD/jbrowse-components/issues/2768 */
54
+ }
55
+ }
56
+ return dest;
57
+ }
30
58
  const isUrl = (loc) => loc?.match(/^https?:\/\//);
31
59
  class AddTrack extends base_1.default {
32
60
  async run() {
@@ -37,12 +65,12 @@ class AddTrack extends base_1.default {
37
65
  const isDir = fs_1.default.lstatSync(output).isDirectory();
38
66
  this.target = isDir ? `${output}/config.json` : output;
39
67
  let { trackType, trackId, name, assemblyNames } = runFlags;
40
- const configDirectory = path_1.default.dirname(this.target);
68
+ const configDir = path_1.default.dirname(this.target);
41
69
  if (!argsTrack) {
42
70
  this.error('No track provided. Example usage: jbrowse add-track yourfile.bam', { exit: 120 });
43
71
  }
44
72
  if (subDir) {
45
- const dir = path_1.default.join(configDirectory, subDir);
73
+ const dir = path_1.default.join(configDir, subDir);
46
74
  if (!fs_1.default.existsSync(dir)) {
47
75
  fs_1.default.mkdirSync(dir);
48
76
  }
@@ -62,6 +90,7 @@ class AddTrack extends base_1.default {
62
90
  });
63
91
  if ([
64
92
  'PAFAdapter',
93
+ 'PairwiseIndexedPAFAdapter',
65
94
  'DeltaAdapter',
66
95
  'ChainAdapter',
67
96
  'MashMapAdapter',
@@ -69,6 +98,7 @@ class AddTrack extends base_1.default {
69
98
  'MCScanSimpleAnchorsAdapter',
70
99
  ].includes(adapter.type)) {
71
100
  // @ts-expect-error
101
+ // this is for the adapter's assembly names
72
102
  adapter.assemblyNames = assemblyNames.split(',').map(a => a.trim());
73
103
  }
74
104
  if (isUrl(location) && load) {
@@ -124,7 +154,7 @@ class AddTrack extends base_1.default {
124
154
  if (!configContents.tracks) {
125
155
  configContents.tracks = [];
126
156
  }
127
- const idx = configContents.tracks.findIndex(configTrack => configTrack.trackId === trackId);
157
+ const idx = configContents.tracks.findIndex(c => c.trackId === trackId);
128
158
  if (idx !== -1) {
129
159
  this.debug(`Found existing trackId ${trackId} in configuration`);
130
160
  if (force || overwrite) {
@@ -138,34 +168,20 @@ class AddTrack extends base_1.default {
138
168
  else {
139
169
  configContents.tracks.push(trackConfig);
140
170
  }
141
- // get path of destination, and remove file at that path if it exists and
142
- // force is set
143
- const destinationFn = (dir, file) => {
144
- const dest = path_1.default.resolve(path_1.default.join(dir, subDir, path_1.default.basename(file)));
145
- if (force) {
146
- try {
147
- fs_1.default.unlinkSync(dest);
148
- }
149
- catch (e) {
150
- /* unconditionally unlinkSync, due to
151
- * https://github.com/nodejs/node/issues/14025#issuecomment-754021370
152
- * and https://github.com/GMOD/jbrowse-components/issues/2768 */
153
- }
154
- }
155
- return dest;
156
- };
157
- const loadType = load || 'inPlace';
158
- const callbacks = {
159
- copy: (src, dest) => copyFile(src, dest, COPYFILE_EXCL),
160
- move: (src, dest) => rename(src, dest),
161
- symlink: (src, dest) => symlink(path_1.default.resolve(src), dest),
162
- inPlace: () => {
163
- /* do nothing */
164
- },
165
- };
166
- await Promise.all(Object.values(this.guessFileNames({ location, index, bed1, bed2 }))
167
- .filter(f => !!f)
168
- .map(src => callbacks[loadType](src, destinationFn(configDirectory, src))));
171
+ if (load && load !== 'inPlace') {
172
+ await Promise.all(Object.values(this.guessFileNames({ location, index, bed1, bed2 }))
173
+ .filter(f => !!f)
174
+ .map(srcFilename => fileOperation({
175
+ mode: load,
176
+ srcFilename,
177
+ destFilename: destinationFn({
178
+ destinationDir: configDir,
179
+ srcFilename,
180
+ force,
181
+ subDir,
182
+ }),
183
+ })));
184
+ }
169
185
  this.debug(`Writing configuration to file ${this.target}`);
170
186
  await this.writeJsonFile(this.target, configContents);
171
187
  this.log(`${idx !== -1 ? 'Overwrote' : 'Added'} track with name "${name}" and trackId "${trackId}" ${idx !== -1 ? 'in' : 'to'} ${this.target}`);
@@ -192,7 +208,8 @@ class AddTrack extends base_1.default {
192
208
  }
193
209
  else if (/\.gff3?\.b?gz$/i.test(location) ||
194
210
  /\.vcf\.b?gz$/i.test(location) ||
195
- /\.bed\.b?gz$/i.test(location)) {
211
+ /\.bed\.b?gz$/i.test(location) ||
212
+ /\.pif\.b?gz$/i.test(location)) {
196
213
  return {
197
214
  file: location,
198
215
  index: index || `${location}.tbi`,
@@ -306,6 +323,16 @@ class AddTrack extends base_1.default {
306
323
  bedLocation: makeLocation(location),
307
324
  };
308
325
  }
326
+ else if (/\.pif\.b?gz$/i.test(location)) {
327
+ return {
328
+ type: 'PairwiseIndexedPAFAdapter',
329
+ pifGzLocation: makeLocation(location),
330
+ index: {
331
+ location: makeLocation(index || `${location}.tbi`),
332
+ indexType: index?.toUpperCase().endsWith('CSI') ? 'CSI' : 'TBI',
333
+ },
334
+ };
335
+ }
309
336
  else if (/\.bed\.b?gz$/i.test(location)) {
310
337
  return {
311
338
  type: 'BedTabixAdapter',
@@ -433,6 +460,7 @@ class AddTrack extends base_1.default {
433
460
  DeltaAdapter: 'SyntenyTrack',
434
461
  ChainAdapter: 'SyntenyTrack',
435
462
  MashMapAdapter: 'SyntenyTrack',
463
+ PairwiseIndexedPAFAdapter: 'SyntenyTrack',
436
464
  MCScanAnchorsAdapter: 'SyntenyTrack',
437
465
  MCScanSimpleAnchorsAdapter: 'SyntenyTrack',
438
466
  };
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createPIF = exports.swapIndelCigar = exports.flipCigar = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const readline_1 = __importDefault(require("readline"));
9
+ const zlib_1 = require("zlib");
10
+ const core_1 = require("@oclif/core");
11
+ const command_exists_1 = require("command-exists");
12
+ const child_process_1 = require("child_process");
13
+ const path_1 = __importDefault(require("path"));
14
+ const base_1 = __importDefault(require("../base"));
15
+ const cigarRegex = new RegExp(/([MIDNSHPX=])/);
16
+ function getReadline(filename) {
17
+ const stream = fs_1.default.createReadStream(filename);
18
+ return readline_1.default.createInterface({
19
+ input: filename.match(/.b?gz$/) ? stream.pipe((0, zlib_1.createGunzip)()) : stream,
20
+ });
21
+ }
22
+ function getStdReadline() {
23
+ return readline_1.default.createInterface({
24
+ input: process.stdin,
25
+ });
26
+ }
27
+ function parseCigar(cigar = '') {
28
+ return cigar.split(cigarRegex).slice(0, -1);
29
+ }
30
+ function flipCigar(cigar) {
31
+ const arr = [];
32
+ for (let i = cigar.length - 2; i >= 0; i -= 2) {
33
+ arr.push(cigar[i]);
34
+ const op = cigar[i + 1];
35
+ if (op === 'D') {
36
+ arr.push('I');
37
+ }
38
+ else if (op === 'I') {
39
+ arr.push('D');
40
+ }
41
+ else {
42
+ arr.push(op);
43
+ }
44
+ }
45
+ return arr;
46
+ }
47
+ exports.flipCigar = flipCigar;
48
+ function swapIndelCigar(cigar) {
49
+ return cigar.replaceAll('D', 'K').replaceAll('I', 'D').replaceAll('K', 'I');
50
+ }
51
+ exports.swapIndelCigar = swapIndelCigar;
52
+ async function createPIF(filename, stream) {
53
+ const rl1 = filename ? getReadline(filename) : getStdReadline();
54
+ for await (const line of rl1) {
55
+ const [c1, l1, s1, e1, strand, c2, l2, s2, e2, ...rest] = line.split('\t');
56
+ stream.write([`t${c2}`, l2, s2, e2, strand, c1, l1, s1, e1, ...rest].join('\t') + '\n');
57
+ const cigarIdx = rest.findIndex(f => f.startsWith('cg:Z'));
58
+ const CIGAR = rest[cigarIdx];
59
+ if (CIGAR) {
60
+ rest[cigarIdx] = `cg:Z:${strand === '-'
61
+ ? flipCigar(parseCigar(CIGAR.slice(5))).join('')
62
+ : swapIndelCigar(CIGAR.slice(5))}`;
63
+ }
64
+ stream.write([`q${c1}`, l1, s1, e1, strand, c2, l2, s2, e2, ...rest].join('\t') + '\n');
65
+ }
66
+ rl1.close();
67
+ }
68
+ exports.createPIF = createPIF;
69
+ class MakePIF extends base_1.default {
70
+ async run() {
71
+ const { args: { file }, flags: { out, csi }, } = await this.parse(MakePIF);
72
+ if ((0, command_exists_1.sync)('sh') &&
73
+ (0, command_exists_1.sync)('sort') &&
74
+ (0, command_exists_1.sync)('grep') &&
75
+ (0, command_exists_1.sync)('tabix') &&
76
+ (0, command_exists_1.sync)('bgzip')) {
77
+ const fn = out || `${path_1.default.basename(file || 'output', '.paf')}.pif.gz`;
78
+ const child = (0, child_process_1.spawn)('sh', [
79
+ '-c',
80
+ `sort -t"\`printf '\t'\`" -k1,1 -k3,3n | bgzip > ${fn}; tabix ${csi ? '-C ' : ''}-s1 -b3 -e4 -0 ${fn}`,
81
+ ], {
82
+ env: { ...process.env, LC_ALL: 'C' },
83
+ stdio: ['pipe', process.stdout, process.stderr],
84
+ });
85
+ await createPIF(file, child.stdin);
86
+ child.stdin.end();
87
+ await new Promise(resolve => {
88
+ child.on('close', resolve);
89
+ });
90
+ }
91
+ else {
92
+ throw new Error('Unable to sort, requires unix type environment with sort, grep, bgzip, tabix');
93
+ }
94
+ }
95
+ }
96
+ MakePIF.description = 'creates pairwise indexed PAF (PIF), with bgzip and tabix';
97
+ MakePIF.examples = [
98
+ '$ jbrowse pif input.paf # creates input.pif.gz in same directory',
99
+ '',
100
+ '$ jbrowse pif input.paf --out output.pif.gz # specify output file, creates output.pif.gz.tbi also',
101
+ ];
102
+ MakePIF.flags = {
103
+ out: core_1.Flags.string({
104
+ description: 'Where to write the output file. will write ${file}.pif.gz and ${file}.pif.gz.tbi',
105
+ }),
106
+ csi: core_1.Flags.boolean({
107
+ description: 'Create a CSI index for the PIF file instead of TBI',
108
+ }),
109
+ help: core_1.Flags.help({ char: 'h' }),
110
+ };
111
+ MakePIF.args = {
112
+ file: core_1.Args.string({
113
+ required: true,
114
+ description: `PAF file as input`,
115
+ }),
116
+ };
117
+ exports.default = MakePIF;
@@ -39,4 +39,7 @@ SortGff.args = {
39
39
  description: `GFF file`,
40
40
  }),
41
41
  };
42
+ SortGff.flags = {
43
+ help: core_1.Flags.help({ char: 'h' }),
44
+ };
42
45
  exports.default = SortGff;
@@ -684,6 +684,57 @@
684
684
  "create.js"
685
685
  ]
686
686
  },
687
+ "make-pif": {
688
+ "aliases": [],
689
+ "args": {
690
+ "file": {
691
+ "description": "PAF file as input",
692
+ "name": "file",
693
+ "required": true
694
+ }
695
+ },
696
+ "description": "creates pairwise indexed PAF (PIF), with bgzip and tabix",
697
+ "examples": [
698
+ "$ jbrowse pif input.paf # creates input.pif.gz in same directory",
699
+ "",
700
+ "$ jbrowse pif input.paf --out output.pif.gz # specify output file, creates output.pif.gz.tbi also"
701
+ ],
702
+ "flags": {
703
+ "out": {
704
+ "description": "Where to write the output file. will write ${file}.pif.gz and ${file}.pif.gz.tbi",
705
+ "name": "out",
706
+ "hasDynamicHelp": false,
707
+ "multiple": false,
708
+ "type": "option"
709
+ },
710
+ "csi": {
711
+ "description": "Create a CSI index for the PIF file instead of TBI",
712
+ "name": "csi",
713
+ "allowNo": false,
714
+ "type": "boolean"
715
+ },
716
+ "help": {
717
+ "char": "h",
718
+ "description": "Show CLI help.",
719
+ "name": "help",
720
+ "allowNo": false,
721
+ "type": "boolean"
722
+ }
723
+ },
724
+ "hasDynamicHelp": false,
725
+ "hiddenAliases": [],
726
+ "id": "make-pif",
727
+ "pluginAlias": "@jbrowse/cli",
728
+ "pluginName": "@jbrowse/cli",
729
+ "pluginType": "core",
730
+ "strict": true,
731
+ "isESM": false,
732
+ "relativePath": [
733
+ "lib",
734
+ "commands",
735
+ "make-pif.js"
736
+ ]
737
+ },
687
738
  "remove-track": {
688
739
  "aliases": [],
689
740
  "args": {
@@ -842,7 +893,15 @@
842
893
  "$ jbrowse sort-gff input.gff | bgzip > sorted.gff.gz",
843
894
  "$ tabix sorted.gff.gz"
844
895
  ],
845
- "flags": {},
896
+ "flags": {
897
+ "help": {
898
+ "char": "h",
899
+ "description": "Show CLI help.",
900
+ "name": "help",
901
+ "allowNo": false,
902
+ "type": "boolean"
903
+ }
904
+ },
846
905
  "hasDynamicHelp": false,
847
906
  "hiddenAliases": [],
848
907
  "id": "sort-gff",
@@ -1087,5 +1146,5 @@
1087
1146
  ]
1088
1147
  }
1089
1148
  },
1090
- "version": "2.8.0"
1149
+ "version": "2.10.0"
1091
1150
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/cli",
3
- "version": "2.8.0",
3
+ "version": "2.10.0",
4
4
  "description": "A command line tool for working with JBrowse 2",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -75,5 +75,5 @@
75
75
  "publishConfig": {
76
76
  "access": "public"
77
77
  },
78
- "gitHead": "ee8c2bdc8bd4f1a70b1eefda984f04a2830d9ca0"
78
+ "gitHead": "223d8bfb68fd1bacaf22852639ad5920f1b7f43b"
79
79
  }