1- import { CreatePlan , Resource , ResourceSettings } from 'codify-plugin-lib' ;
2- import { ResourceConfig } from 'codify-schemas' ;
3- import * as fs from 'node:fs' ;
1+ import { CreatePlan , Resource , ResourceSettings , getPty } from 'codify-plugin-lib' ;
2+ import { OS , ResourceConfig } from 'codify-schemas' ;
3+ import * as fs from 'node:fs/promises' ;
4+ import os from 'node:os' ;
45import path from 'node:path' ;
56import plist from 'plist' ;
67
7- import { codifySpawn } from '../../utils/codify-spawn.js' ;
88import { Utils } from '../../utils/index.js' ;
99import Schema from './android-studio-schema.json' ;
1010import { AndroidStudioPlist , AndroidStudioVersionData } from './types.js' ;
@@ -21,6 +21,7 @@ export class AndroidStudioResource extends Resource<AndroidStudioConfig> {
2121 override getSettings ( ) : ResourceSettings < AndroidStudioConfig > {
2222 return {
2323 id : 'android-studio' ,
24+ operatingSystems : [ OS . Darwin ] ,
2425 schema : Schema ,
2526 parameterSettings : {
2627 directory : { type : 'directory' , default : '/Applications' } ,
@@ -50,6 +51,8 @@ export class AndroidStudioResource extends Resource<AndroidStudioConfig> {
5051 }
5152
5253 override async create ( plan : CreatePlan < AndroidStudioConfig > ) : Promise < void > {
54+ const $ = getPty ( ) ;
55+
5356 if ( ! this . allAndroidStudioVersions ) {
5457 this . allAndroidStudioVersions = await this . fetchAllAndroidStudioVersions ( )
5558 }
@@ -64,16 +67,14 @@ export class AndroidStudioResource extends Resource<AndroidStudioConfig> {
6467 : versionToDownload . download . find ( ( v ) => v . link . includes ( 'mac.dmg' ) ) !
6568
6669 // Create a temporary tmp dir
67- const temporaryDirQuery = await codifySpawn ( 'mktemp -d' ) ;
68- const temporaryDir = temporaryDirQuery . data . trim ( ) ;
70+ const temporaryDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'codify-android-' ) )
6971
7072 try {
7173
7274 // Download and unzip the terraform binary
73- await codifySpawn ( `curl -fsSL --progress-bar ${ downloadLink . link } -o android-studio.dmg` , { cwd : temporaryDir } ) ;
74-
75+ await $ . spawn ( `curl -fsSL ${ downloadLink . link } -o android-studio.dmg` , { cwd : temporaryDir } ) ;
7576
76- const { data } = await codifySpawn ( 'hdiutil attach android-studio.dmg' , { cwd : temporaryDir } ) ;
77+ const { data } = await $ . spawn ( 'hdiutil attach android-studio.dmg' , { cwd : temporaryDir } ) ;
7778 const mountedDir = data . split ( / \n / )
7879 . find ( ( l ) => l . includes ( '/Volumes/' ) )
7980 ?. split ( ' ' )
@@ -85,28 +86,27 @@ export class AndroidStudioResource extends Resource<AndroidStudioConfig> {
8586 }
8687
8788 try {
88- const { data : contents } = await codifySpawn ( 'ls' , { cwd : mountedDir } )
89+ const contents = await fs . readdir ( mountedDir ) ;
8990
9091 // Depending on it's preview or regular the name is different
91- const appName = contents . split ( / \n / )
92+ const appName = contents
9293 . find ( ( l ) => l . includes ( 'Android' ) )
9394
94- await codifySpawn ( `rsync -rl "${ appName } " Applications/` , { cwd : mountedDir , requiresRoot : true } )
95-
96-
95+ // Must rsync because mounted dirs are read-only (can't delete via mv)
96+ await $ . spawn ( `rsync -rl "${ appName } " Applications/` , { cwd : mountedDir } )
9797 } finally {
9898 // Unmount
99- await codifySpawn ( `hdiutil detach "${ mountedDir } "` )
99+ await $ . spawnSafe ( `hdiutil detach "${ mountedDir } "` )
100100 }
101101
102102 } finally {
103103 // Delete the tmp directory
104- await codifySpawn ( `rm -r ${ temporaryDir } ` )
104+ await fs . rm ( temporaryDir , { recursive : true , force : true } ) ;
105105 }
106106 }
107107
108108 override async destroy ( ) : Promise < void > {
109- await codifySpawn ( 'rm -r " /Applications/Android Studio.app" ', { requiresRoot : true } )
109+ await fs . rm ( ' /Applications/Android Studio.app', { force : true , recursive : true } ) ;
110110 }
111111
112112 private async fetchAllAndroidStudioVersions ( ) : Promise < AndroidStudioVersionData [ ] > {
@@ -121,7 +121,7 @@ export class AndroidStudioResource extends Resource<AndroidStudioConfig> {
121121
122122 private async addPlistData ( location : string ) : Promise < { location : string , plist : AndroidStudioPlist } | null > {
123123 try {
124- const file = fs . readFileSync ( path . join ( location , '/Contents/Info.plist' ) , 'utf8' ) ;
124+ const file = await fs . readFile ( path . join ( location , '/Contents/Info.plist' ) , 'utf8' ) ;
125125 const plistData = plist . parse ( file ) as unknown as AndroidStudioPlist ;
126126
127127 return { location, plist : plistData } ;
0 commit comments