7
7
* file that was distributed with this source code.
8
8
*/
9
9
10
+ import { open } from 'fs-extra'
11
+ import { join } from 'path'
10
12
import { BaseCommand , args } from '@adonisjs/ace'
11
13
12
14
import { Manifest } from '../src/Manifest'
13
- import { ADONIS_ACE_CWD } from '../config/env'
14
-
15
- const sleep = ( timeout : number ) => new Promise ( ( resolve ) => setTimeout ( resolve , timeout ) )
15
+ import { ADONIS_ACE_CWD , ADONIS_BUILD_DIR } from '../config/env'
16
16
17
17
/**
18
18
* Invoke post install instructions
@@ -27,6 +27,33 @@ export default class Invoke extends BaseCommand {
27
27
@args . string ( { description : 'Name of the package for which to invoke post install instructions' } )
28
28
public name : string
29
29
30
+ /**
31
+ * Attempts to access the rc file handling the race condition of
32
+ * it's being accessed by another process.
33
+ */
34
+ private async accessRcFile ( counter = 0 ) {
35
+ const buildDir = ADONIS_BUILD_DIR ( )
36
+ const cwd = ADONIS_ACE_CWD ( ) !
37
+
38
+ /**
39
+ * Return early when we are unaware of the build
40
+ * directory
41
+ */
42
+ if ( ! buildDir ) {
43
+ return
44
+ }
45
+
46
+ try {
47
+ await open ( join ( cwd , buildDir , '.adonisrc.json' ) , 'r+' )
48
+ } catch ( error ) {
49
+ if ( error . code === 'EBUSY' && counter < 3 ) {
50
+ await this . accessRcFile ( counter + 1 )
51
+ } else {
52
+ throw error
53
+ }
54
+ }
55
+ }
56
+
30
57
/**
31
58
* Invoked automatically by ace
32
59
*/
@@ -47,18 +74,11 @@ export default class Invoke extends BaseCommand {
47
74
const { executeInstructions } = await import ( '@adonisjs/sink' )
48
75
await executeInstructions ( this . name , cwd , this . application )
49
76
50
- /**
51
- * When we execute the instructions that updates the `.adonisrc.json` file, we watcher
52
- * copies it's contents to the `build` directory.
53
- *
54
- * Once the copy is in progress, running the ace instructions leads to reading an empty
55
- * `.adonisrc.json` file.
56
- *
57
- * Now there is no simple way to know when the separate process watching and processing
58
- * files will copy the `.adonisrc.json` file. So we add a small cool off period in
59
- * between.
60
- */
61
- await sleep ( 400 )
77
+ try {
78
+ await this . accessRcFile ( )
79
+ } catch ( error ) {
80
+ }
81
+
62
82
await new Manifest ( cwd , this . logger ) . generate ( )
63
83
}
64
84
}
0 commit comments