@@ -4,7 +4,7 @@ import spec = require('jsii-spec');
4
4
import log4js = require( 'log4js' ) ;
5
5
import yargs = require( 'yargs' ) ;
6
6
import { compareAssemblies } from '../lib' ;
7
- import { downloadNpmPackage } from '../lib/util' ;
7
+ import { DownloadFailure , downloadNpmPackage , showDownloadFailure } from '../lib/util' ;
8
8
import { VERSION } from '../lib/version' ;
9
9
10
10
const LOG = log4js . getLogger ( 'jsii-diff' ) ;
@@ -33,13 +33,24 @@ async function main(): Promise<number> {
33
33
configureLog4js ( argv . verbose ) ;
34
34
35
35
LOG . debug ( `Loading original assembly from ${ ( argv as any ) . original } ` ) ;
36
- const original = await loadAssembly ( ( argv as any ) . original ) ;
36
+ const loadOriginal = await loadAssembly ( ( argv as any ) . original ) ;
37
+ if ( ! loadOriginal . success ) {
38
+ process . stderr . write ( `Could not load '${ loadOriginal . resolved } ': ${ showDownloadFailure ( loadOriginal . reason ) } . Skipping analysis\n` ) ;
39
+ return 0 ;
40
+ }
37
41
38
42
LOG . debug ( `Loading updated assembly from ${ ( argv as any ) . updated } ` ) ;
39
- const updated = await loadAssembly ( ( argv as any ) . updated ) ;
43
+ const loadUpdated = await loadAssembly ( ( argv as any ) . updated ) ;
44
+ if ( ! loadUpdated . success ) {
45
+ process . stderr . write ( `Could not load '${ loadUpdated . resolved } ': ${ showDownloadFailure ( loadUpdated . reason ) } . Skipping analysis\n` ) ;
46
+ return 0 ;
47
+ }
48
+
49
+ const original = loadOriginal . assembly ;
50
+ const updated = loadUpdated . assembly ;
40
51
41
52
if ( original . name !== updated . name ) {
42
- process . stderr . write ( `Look like different assemblies: '${ original . name } ' vs '${ updated . name } '. Comparing is probably pointless...` ) ;
53
+ process . stderr . write ( `Look like different assemblies: '${ original . name } ' vs '${ updated . name } '. Comparing is probably pointless...\n ` ) ;
43
54
}
44
55
45
56
LOG . info ( `Starting analysis` ) ;
@@ -66,27 +77,37 @@ async function main(): Promise<number> {
66
77
// Allow both npm:<package> (legacy) and npm://<package> (looks better)
67
78
const NPM_REGEX = / ^ n p m : ( \/ \/ ) ? / ;
68
79
69
- async function loadAssembly ( name : string ) {
80
+ /**
81
+ * Load the indicated assembly from the given name
82
+ *
83
+ * Supports downloading from NPM as well as from file or directory.
84
+ */
85
+ async function loadAssembly ( requested : string ) : Promise < LoadAssemblyResult > {
86
+ let resolved = requested ;
70
87
try {
71
- if ( name . match ( NPM_REGEX ) ) {
72
- let pkg = name . replace ( NPM_REGEX , '' ) ;
88
+ if ( requested . match ( NPM_REGEX ) ) {
89
+ let pkg = requested . replace ( NPM_REGEX , '' ) ;
73
90
if ( ! pkg ) { pkg = await loadPackageNameFromAssembly ( ) ; }
74
91
75
- // Put 'pkg' back into 'name' so any errors loading the assembly get a good source description
76
- name = `npm://${ pkg } ` ;
77
- if ( pkg . indexOf ( '@' , 1 ) === - 1 ) { name += '@latest' ; }
92
+ resolved = `npm://${ pkg } ` ;
93
+ if ( pkg . indexOf ( '@' , 1 ) === - 1 ) { resolved += '@latest' ; }
78
94
79
- return await downloadNpmPackage ( pkg , loadFromFilesystem ) ;
95
+ const download = await downloadNpmPackage ( pkg , loadFromFilesystem ) ;
96
+ if ( download . success ) {
97
+ return { requested, resolved, success : true , assembly : download . result } ;
98
+ }
99
+ return { requested, resolved, success : false , reason : download . reason } ;
80
100
} else {
81
- return await loadFromFilesystem ( name ) ;
101
+ // We don't accept failure loading from the filesystem
102
+ return { requested, resolved, success : true , assembly : await loadFromFilesystem ( requested ) } ;
82
103
}
83
104
} catch ( e ) {
84
105
// Prepend information about which assembly we've failed to load
85
106
//
86
107
// Look at the type of error. If it has a lot of lines (like validation errors
87
108
// tend to do) log everything to the debug log and only show a couple
88
109
const maxLines = 3 ;
89
- const messageWithContext = `Error loading assembly '${ name } ': ${ e . message } ` ;
110
+ const messageWithContext = `Error loading assembly '${ resolved } ': ${ e . message } ` ;
90
111
const errorLines = messageWithContext . split ( '\n' ) ;
91
112
if ( errorLines . length < maxLines ) { throw new Error ( messageWithContext ) ; }
92
113
for ( const line of errorLines ) {
@@ -96,6 +117,9 @@ async function loadAssembly(name: string) {
96
117
}
97
118
}
98
119
120
+ type LoadAssemblyResult = { requested : string ; resolved : string }
121
+ & ( { success : true ; assembly : reflect . Assembly } | { success : false ; reason : DownloadFailure } ) ;
122
+
99
123
async function loadPackageNameFromAssembly ( ) : Promise < string > {
100
124
const JSII_ASSEMBLY_FILE = '.jsii' ;
101
125
if ( ! await fs . pathExists ( JSII_ASSEMBLY_FILE ) ) {
0 commit comments