1
1
import * as path from "path" ;
2
2
import * as temp from "temp" ;
3
3
import { AndroidDeviceHashService } from "./android-device-hash-service" ;
4
+ import { executeActionByChunks } from "../../helpers" ;
5
+ import { DEFAULT_CHUNK_SIZE } from '../../constants' ;
4
6
5
7
export class AndroidDeviceFileSystem implements Mobile . IDeviceFileSystem {
6
8
private _deviceHashServices = Object . create ( null ) ;
@@ -51,28 +53,24 @@ export class AndroidDeviceFileSystem implements Mobile.IDeviceFileSystem {
51
53
}
52
54
53
55
public async transferFiles ( deviceAppData : Mobile . IDeviceAppData , localToDevicePaths : Mobile . ILocalToDevicePathData [ ] ) : Promise < void > {
54
- // TODO: Do not start all promises simultaneously as this leads to error EMFILE on Windows for too many opened files.
55
- // Use chunks (for example on 100).
56
- await Promise . all (
57
- _ ( localToDevicePaths )
58
- . filter ( localToDevicePathData => this . $fs . getFsStats ( localToDevicePathData . getLocalPath ( ) ) . isFile ( ) )
59
- . map ( async localToDevicePathData => {
60
- const devicePath = localToDevicePathData . getDevicePath ( ) ;
61
- await this . adb . executeCommand ( [ "push" , localToDevicePathData . getLocalPath ( ) , devicePath ] ) ;
62
- await this . adb . executeShellCommand ( [ "chmod" , "0777" , path . dirname ( devicePath ) ] ) ;
63
- }
64
- )
65
- . value ( )
66
- ) ;
67
-
68
- await Promise . all (
69
- _ ( localToDevicePaths )
70
- . filter ( localToDevicePathData => this . $fs . getFsStats ( localToDevicePathData . getLocalPath ( ) ) . isDirectory ( ) )
71
- . map ( async localToDevicePathData =>
72
- await this . adb . executeShellCommand ( [ "chmod" , "0777" , localToDevicePathData . getDevicePath ( ) ] )
73
- )
74
- . value ( )
75
- ) ;
56
+ const directoriesToChmod : string [ ] = [ ] ;
57
+ const action = async ( localToDevicePathData : Mobile . ILocalToDevicePathData ) => {
58
+ const fstat = this . $fs . getFsStats ( localToDevicePathData . getLocalPath ( ) ) ;
59
+ if ( fstat . isFile ( ) ) {
60
+ const devicePath = localToDevicePathData . getDevicePath ( ) ;
61
+ await this . adb . executeCommand ( [ "push" , localToDevicePathData . getLocalPath ( ) , devicePath ] ) ;
62
+ await this . adb . executeShellCommand ( [ "chmod" , "0777" , path . dirname ( devicePath ) ] ) ;
63
+ } else if ( fstat . isDirectory ( ) ) {
64
+ const dirToChmod = localToDevicePathData . getDevicePath ( ) ;
65
+ directoriesToChmod . push ( dirToChmod ) ;
66
+ }
67
+ } ;
68
+
69
+ await executeActionByChunks < Mobile . ILocalToDevicePathData > ( localToDevicePaths , DEFAULT_CHUNK_SIZE , action ) ;
70
+
71
+ const dirsChmodAction = ( directoryToChmod : string ) => this . adb . executeShellCommand ( [ "chmod" , "0777" , directoryToChmod ] ) ;
72
+
73
+ await executeActionByChunks < string > ( _ . uniq ( directoriesToChmod ) , DEFAULT_CHUNK_SIZE , dirsChmodAction ) ;
76
74
77
75
// Update hashes
78
76
const deviceHashService = this . getDeviceHashService ( deviceAppData . appIdentifier ) ;
@@ -82,25 +80,12 @@ export class AndroidDeviceFileSystem implements Mobile.IDeviceFileSystem {
82
80
}
83
81
84
82
public async transferDirectory ( deviceAppData : Mobile . IDeviceAppData , localToDevicePaths : Mobile . ILocalToDevicePathData [ ] , projectFilesPath : string ) : Promise < Mobile . ILocalToDevicePathData [ ] > {
85
- const devicePaths : string [ ] = [ ] ;
86
83
const currentShasums : IStringDictionary = { } ;
87
-
88
- await Promise . all (
89
- localToDevicePaths . map ( async localToDevicePathData => {
90
- const localPath = localToDevicePathData . getLocalPath ( ) ;
91
- const stats = this . $fs . getFsStats ( localPath ) ;
92
- if ( stats . isFile ( ) ) {
93
- const fileShasum = await this . $fs . getFileShasum ( localPath ) ;
94
- currentShasums [ localPath ] = fileShasum ;
95
- }
96
-
97
- devicePaths . push ( `"${ localToDevicePathData . getDevicePath ( ) } "` ) ;
98
- } )
99
- ) ;
84
+ const deviceHashService = this . getDeviceHashService ( deviceAppData . appIdentifier ) ;
85
+ const devicePaths : string [ ] = await deviceHashService . generateHashesFromLocalToDevicePaths ( localToDevicePaths , currentShasums ) ;
100
86
101
87
const commandsDeviceFilePath = this . $mobileHelper . buildDevicePath ( await deviceAppData . getDeviceProjectRootPath ( ) , "nativescript.commands.sh" ) ;
102
88
103
- const deviceHashService = this . getDeviceHashService ( deviceAppData . appIdentifier ) ;
104
89
let filesToChmodOnDevice : string [ ] = devicePaths ;
105
90
let tranferredFiles : Mobile . ILocalToDevicePathData [ ] = [ ] ;
106
91
const oldShasums = await deviceHashService . getShasumsFromDevice ( ) ;
@@ -113,16 +98,15 @@ export class AndroidDeviceFileSystem implements Mobile.IDeviceFileSystem {
113
98
const changedShasums : any = _ . omitBy ( currentShasums , ( hash : string , pathToFile : string ) => ! ! _ . find ( oldShasums , ( oldHash : string , oldPath : string ) => pathToFile === oldPath && hash === oldHash ) ) ;
114
99
this . $logger . trace ( "Changed file hashes are:" , changedShasums ) ;
115
100
filesToChmodOnDevice = [ ] ;
116
- await Promise . all (
117
- _ ( changedShasums )
118
- . map ( ( hash : string , filePath : string ) => _ . find ( localToDevicePaths , ldp => ldp . getLocalPath ( ) === filePath ) )
119
- . map ( localToDevicePathData => {
120
- tranferredFiles . push ( localToDevicePathData ) ;
121
- filesToChmodOnDevice . push ( `"${ localToDevicePathData . getDevicePath ( ) } "` ) ;
122
- return this . transferFile ( localToDevicePathData . getLocalPath ( ) , localToDevicePathData . getDevicePath ( ) ) ;
123
- } )
124
- . value ( )
125
- ) ;
101
+
102
+ const transferFileAction = async ( hash : string , filePath : string ) => {
103
+ const localToDevicePathData = _ . find ( localToDevicePaths , ldp => ldp . getLocalPath ( ) === filePath ) ;
104
+ tranferredFiles . push ( localToDevicePathData ) ;
105
+ filesToChmodOnDevice . push ( `"${ localToDevicePathData . getDevicePath ( ) } "` ) ;
106
+ return this . transferFile ( localToDevicePathData . getLocalPath ( ) , localToDevicePathData . getDevicePath ( ) ) ;
107
+ } ;
108
+
109
+ await executeActionByChunks < string > ( changedShasums , DEFAULT_CHUNK_SIZE , transferFileAction ) ;
126
110
}
127
111
128
112
if ( filesToChmodOnDevice . length ) {
0 commit comments