1
1
/* eslint-disable no-console */
2
2
import { getLGConfig } from '@lg-tools/meta' ;
3
3
import chalk from 'chalk' ;
4
- import { spawn } from 'cross-spawn' ;
5
4
import fse from 'fs-extra' ;
6
- import { homedir } from 'os' ;
7
5
import path from 'path' ;
8
6
9
- import { formatLog } from './utils' ;
7
+ import { createLinkFrom } from './utils/createLinkFrom' ;
8
+ import { formatLog } from './utils/formatLog' ;
9
+ import { yarnInstall } from './utils/install' ;
10
+ import { linkPackageTo } from './utils/linkPackageTo' ;
11
+ import { PackageDetails } from './utils/types' ;
10
12
11
13
interface LinkOptions {
12
14
packages : Array < string > ;
13
15
scope : string ;
14
16
verbose : boolean ;
17
+ to ?: string ;
18
+ from ?: string ;
15
19
}
16
20
17
21
const ignorePackages = [ 'mongo-nav' ] ;
18
22
19
- export async function linkPackages ( destination : string , opts : LinkOptions ) {
20
- const { verbose, scope : scopeFlag , packages } = opts ;
23
+ export async function linkPackages (
24
+ dest : string | undefined ,
25
+ opts : LinkOptions ,
26
+ ) {
27
+ const { verbose, scope : scopeFlag , packages, to, from } = opts ;
28
+
21
29
const rootDir = process . cwd ( ) ;
22
- const relativeDestination = path . relative ( rootDir , destination ) ;
30
+
31
+ if ( ! to && ! dest && ! from ) {
32
+ console . error ( 'Error linking. Must provide either a destination or source' ) ;
33
+ }
34
+
35
+ const destination = path . resolve ( path . join ( rootDir , dest || to || '.' ) ) ;
36
+ const source = path . resolve ( from ? path . join ( rootDir , from ) : rootDir ) ;
23
37
24
38
// Check if the destination exists
25
39
if (
26
- ! ( fse . existsSync ( destination ) && fse . lstatSync ( destination ) . isDirectory ( ) )
40
+ ! (
41
+ destination &&
42
+ fse . existsSync ( destination ) &&
43
+ fse . lstatSync ( destination ) . isDirectory ( )
44
+ )
27
45
) {
28
46
throw new Error (
29
- `Can't find the directory ${ formatLog . path ( relativeDestination ) } .` ,
47
+ `Can't find the directory ${ formatLog . path ( destination ?? '' ) } .` ,
48
+ ) ;
49
+ }
50
+
51
+ if ( dest ?? to ) {
52
+ console . log (
53
+ chalk . green ( `Linking packages to ${ formatLog . path ( destination ) } ...` ) ,
30
54
) ;
31
55
}
32
56
33
- console . log (
34
- chalk . green (
35
- `Linking packages to ${ formatLog . path ( relativeDestination ) } ...` ,
36
- ) ,
37
- ) ;
57
+ if ( from ) {
58
+ console . log (
59
+ chalk . green ( `Linking packages from ${ formatLog . path ( source ) } ...` ) ,
60
+ ) ;
61
+ }
38
62
39
- const { scopes : availableScopes } = getLGConfig ( ) ;
63
+ const { scopes : availableScopes } = getLGConfig ( source ) ;
64
+
65
+ verbose &&
66
+ console . log ( {
67
+ availableScopes,
68
+ dest,
69
+ to,
70
+ from,
71
+ destination,
72
+ source,
73
+ rootDir,
74
+ } ) ;
40
75
41
76
const linkPromises : Array < Promise < void > > = [ ] ;
42
77
43
78
for ( const [ scopeName , scopePath ] of Object . entries ( availableScopes ) ) {
44
79
if ( ! scopeFlag || scopeFlag . includes ( scopeName ) ) {
45
80
linkPromises . push (
46
81
linkPackagesForScope (
47
- scopeName ,
48
- scopePath as string ,
82
+ { scopeName, scopePath } ,
83
+ source ,
49
84
destination ,
50
85
packages ,
51
86
verbose ,
@@ -60,8 +95,8 @@ export async function linkPackages(destination: string, opts: LinkOptions) {
60
95
}
61
96
62
97
async function linkPackagesForScope (
63
- scopeName : string ,
64
- scopePath : string ,
98
+ { scopeName, scopePath } : Pick < PackageDetails , 'scopeName' | 'scopePath' > ,
99
+ source : string ,
65
100
destination : string ,
66
101
packages ?: Array < string > ,
67
102
verbose ?: boolean ,
@@ -86,16 +121,23 @@ async function linkPackagesForScope(
86
121
packages . some ( pkgFlag => pkgFlag . includes ( installedPkg ) ) ) ,
87
122
) ;
88
123
124
+ /** Create links */
89
125
console . log (
90
126
chalk . gray (
91
127
` Creating links to ${ formatLog . scope ( scopeName ) } packages...` ,
92
128
) ,
93
129
) ;
94
130
await Promise . all (
95
131
packagesToLink . map ( pkg => {
96
- createYarnLinkForPackage ( scopeName , scopePath , pkg , verbose ) ;
132
+ createLinkFrom (
133
+ source ,
134
+ { scopeName, scopePath, packageName : pkg } ,
135
+ verbose ,
136
+ ) ;
97
137
} ) ,
98
138
) ;
139
+
140
+ /** Connect link */
99
141
console . log (
100
142
chalk . gray (
101
143
` Connecting links for ${ formatLog . scope (
@@ -105,7 +147,14 @@ async function linkPackagesForScope(
105
147
) ;
106
148
await Promise . all (
107
149
packagesToLink . map ( ( pkg : string ) =>
108
- linkPackageToDestination ( scopeName , pkg , destination , verbose ) ,
150
+ linkPackageTo (
151
+ destination ,
152
+ {
153
+ scopeName,
154
+ packageName : pkg ,
155
+ } ,
156
+ verbose ,
157
+ ) ,
109
158
) ,
110
159
) ;
111
160
} else {
@@ -124,102 +173,11 @@ async function linkPackagesForScope(
124
173
// TODO: Prompt user to install instead of just running it
125
174
await yarnInstall ( destination ) ;
126
175
await linkPackagesForScope (
127
- scopeName ,
128
- scopePath ,
176
+ { scopeName, scopePath } ,
129
177
destination ,
178
+ source ,
130
179
packages ,
131
180
verbose ,
132
181
) ;
133
182
}
134
183
}
135
-
136
- /**
137
- * Runs the yarn link command in a leafygreen-ui package directory
138
- * @returns Promise that resolves when the yarn link command has finished
139
- */
140
- function createYarnLinkForPackage (
141
- scopeName : string ,
142
- scopePath : string ,
143
- packageName : string ,
144
- verbose ?: boolean ,
145
- ) : Promise < void > {
146
- const scopeSrc = scopePath ;
147
- return new Promise < void > ( resolve => {
148
- const packagesDirectory = findDirectory ( process . cwd ( ) , scopeSrc ) ;
149
-
150
- if ( packagesDirectory ) {
151
- verbose &&
152
- console . log (
153
- 'Creating link for:' ,
154
- chalk . green ( `${ scopeName } /${ packageName } ` ) ,
155
- ) ;
156
- spawn ( 'yarn' , [ 'link' ] , {
157
- cwd : path . join ( packagesDirectory , packageName ) ,
158
- stdio : verbose ? 'inherit' : 'ignore' ,
159
- } )
160
- . on ( 'close' , resolve )
161
- . on ( 'error' , ( ) => {
162
- throw new Error ( `Couldn't create link for package: ${ packageName } ` ) ;
163
- } ) ;
164
- } else {
165
- throw new Error (
166
- `Can't find a ${ scopeSrc } directory in ${ process . cwd ( ) } or any of its parent directories.` ,
167
- ) ;
168
- }
169
- } ) ;
170
- }
171
-
172
- /**
173
- * Runs the yarn link <packageName> command in the destination directory
174
- * @returns Promise that resolves when the yarn link <packageName> command has finished
175
- */
176
- function linkPackageToDestination (
177
- scopeName : string ,
178
- packageName : string ,
179
- destination : string ,
180
- verbose ?: boolean ,
181
- ) : Promise < void > {
182
- const fullPackageName = `${ scopeName } /${ packageName } ` ;
183
- return new Promise < void > ( resolve => {
184
- verbose && console . log ( 'Linking package:' , chalk . blue ( fullPackageName ) ) ;
185
- spawn ( 'yarn' , [ 'link' , fullPackageName ] , {
186
- cwd : destination ,
187
- stdio : verbose ? 'inherit' : 'ignore' ,
188
- } )
189
- . on ( 'close' , resolve )
190
- . on ( 'error' , ( ) => {
191
- throw new Error ( `Couldn't link package: ${ fullPackageName } ` ) ;
192
- } ) ;
193
- } ) ;
194
- }
195
-
196
- function findDirectory (
197
- startDir : string ,
198
- targetDir : string ,
199
- ) : string | undefined {
200
- const testDir = path . join ( startDir , targetDir ) ;
201
-
202
- if ( fse . existsSync ( testDir ) && fse . lstatSync ( testDir ) . isDirectory ( ) ) {
203
- return testDir ;
204
- } else {
205
- const parentDir = path . join ( startDir , '..' ) ;
206
-
207
- // If we haven't reached the users home directory, recursively look for the packages directory
208
- if ( parentDir !== homedir ( ) ) {
209
- return findDirectory ( path . join ( startDir , '..' ) , targetDir ) ;
210
- }
211
- }
212
- }
213
-
214
- function yarnInstall ( path : string ) {
215
- return new Promise ( ( resolve , reject ) => {
216
- spawn ( 'yarn' , [ 'install' ] , {
217
- cwd : path ,
218
- stdio : 'ignore' ,
219
- } )
220
- . on ( 'close' , resolve )
221
- . on ( 'error' , ( ) => {
222
- throw new Error ( `Error installing packages` ) ;
223
- } ) ;
224
- } ) ;
225
- }
0 commit comments