Skip to content

Commit b423d3b

Browse files
author
Tsvetan Raikov
committed
Fixed: Changes in package.json are not livesynced
Implemented pt redictable livesync Implement run command to use livesync project changes info as a service
1 parent 07f204a commit b423d3b

32 files changed

+845
-549
lines changed

.vscode/launch.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
{
88
"type": "node",
99
"request": "launch",
10-
"cwd": "${workspaceRoot}/scratch",
10+
"cwd": "${workspaceRoot}",
1111
"sourceMaps": true,
1212
"name": "Launch CLI (Node 6+)",
1313
"program": "${workspaceRoot}/lib/nativescript-cli.js",

lib/bootstrap.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,9 @@ $injector.requireCommand("platform|clean", "./commands/platform-clean");
104104

105105
$injector.requireCommand("livesync", "./commands/livesync");
106106
$injector.require("usbLiveSyncService", "./services/livesync/livesync-service"); // The name is used in https://github.com/NativeScript/nativescript-dev-typescript
107-
$injector.require("iosPlatformLiveSyncServiceLocator", "./services/livesync/ios-platform-livesync-service");
108107
$injector.require("iosLiveSyncServiceLocator", "./services/livesync/ios-device-livesync-service");
109-
$injector.require("androidPlatformLiveSyncServiceLocator", "./services/livesync/android-platform-livesync-service");
110108
$injector.require("androidLiveSyncServiceLocator", "./services/livesync/android-device-livesync-service");
109+
$injector.require("platformLiveSyncService", "./services/livesync/platform-livesync-service");
111110

112111
$injector.require("sysInfo", "./sys-info");
113112

@@ -123,3 +122,4 @@ $injector.requireCommand("post-install-cli", "./commands/post-install");
123122
$injector.requireCommand("update", "./commands/update");
124123

125124
$injector.require("iOSLogFilter", "./services/ios-log-filter");
125+
$injector.require("projectChangesService", "./services/project-changes-service");

lib/commands/appstore-upload.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,12 @@ export class PublishIOS implements ICommand {
6565
};
6666
this.$logger.info("Building .ipa with the selected mobile provision and/or certificate.");
6767
// This is not very correct as if we build multiple targets we will try to sign all of them using the signing identity here.
68-
this.$platformService.buildPlatform(platform, iOSBuildConfig, true).wait();
68+
this.$platformService.preparePlatform(platform).wait();
69+
this.$platformService.buildPlatform(platform, iOSBuildConfig).wait();
6970
ipaFilePath = this.$platformService.lastOutputPath(platform, { isForDevice: iOSBuildConfig.buildForDevice });
7071
} else {
7172
this.$logger.info("No .ipa, mobile provision or certificate set. Perfect! Now we'll build .xcarchive and let Xcode pick the distribution certificate and provisioning profile for you when exporting .ipa for AppStore submission.");
72-
this.$platformService.preparePlatform(platform, true).wait();
73+
this.$platformService.preparePlatform(platform).wait();
7374

7475
let platformData = this.$platformsData.getPlatformData(platform);
7576
let iOSProjectService = <IOSProjectService>platformData.platformProjectService;

lib/commands/build.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ export class BuildCommandBase {
55
executeCore(args: string[]): IFuture<void> {
66
return (() => {
77
let platform = args[0].toLowerCase();
8-
this.$platformService.buildPlatform(platform, null, true).wait();
8+
this.$platformService.preparePlatform(platform).wait();
9+
this.$options.clean = true;
10+
this.$platformService.buildPlatform(platform).wait();
911
if(this.$options.copyTo) {
1012
this.$platformService.copyLastOutput(platform, this.$options.copyTo, {isForDevice: this.$options.forDevice});
1113
}

lib/commands/debug.ts

+22-23
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,32 @@
77
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
88
private $config: IConfiguration,
99
private $usbLiveSyncService: ILiveSyncService,
10+
private $platformService: IPlatformService,
1011
protected $options: IOptions) { }
1112

1213
execute(args: string[]): IFuture<void> {
13-
14-
if (this.$options.watch) {
15-
this.$options.rebuild = false;
14+
if (this.$options.start) {
15+
return this.debugService.debug();
1616
}
1717

18-
if (!this.$options.rebuild && !this.$options.start) {
19-
this.$config.debugLivesync = true;
20-
let applicationReloadAction = (deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture<void> => {
21-
return (() => {
22-
let projectData: IProjectData = this.$injector.resolve("projectData");
23-
24-
this.debugService.debugStop().wait();
18+
this.$platformService.deployPlatform(this.$devicesService.platform).wait();
19+
this.$config.debugLivesync = true;
20+
let applicationReloadAction = (deviceAppData: Mobile.IDeviceAppData): IFuture<void> => {
21+
return (() => {
22+
let projectData: IProjectData = this.$injector.resolve("projectData");
2523

26-
let applicationId = deviceAppData.appIdentifier;
27-
if (deviceAppData.device.isEmulator && deviceAppData.platform.toLowerCase() === this.$devicePlatformsConstants.iOS.toLowerCase()) {
28-
applicationId = projectData.projectName;
29-
}
30-
deviceAppData.device.applicationManager.stopApplication(applicationId).wait();
24+
this.debugService.debugStop().wait();
3125

32-
this.debugService.debug().wait();
33-
}).future<void>()();
34-
};
26+
let applicationId = deviceAppData.appIdentifier;
27+
if (deviceAppData.device.isEmulator && deviceAppData.platform.toLowerCase() === this.$devicePlatformsConstants.iOS.toLowerCase()) {
28+
applicationId = projectData.projectName;
29+
}
30+
deviceAppData.device.applicationManager.stopApplication(applicationId).wait();
3531

36-
return this.$usbLiveSyncService.liveSync(this.$devicesService.platform, applicationReloadAction);
37-
}
38-
return this.debugService.debug();
32+
this.debugService.debug().wait();
33+
}).future<void>()();
34+
};
35+
return this.$usbLiveSyncService.liveSync(this.$devicesService.platform, applicationReloadAction);
3936
}
4037

4138
allowedParameters: ICommandParameter[] = [];
@@ -69,8 +66,9 @@ export class DebugIOSCommand extends DebugPlatformCommand {
6966
$devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
7067
$config: IConfiguration,
7168
$usbLiveSyncService: ILiveSyncService,
69+
$platformService: IPlatformService,
7270
$options: IOptions) {
73-
super($iOSDebugService, $devicesService, $injector, $logger, $childProcess, $devicePlatformsConstants, $config, $usbLiveSyncService, $options);
71+
super($iOSDebugService, $devicesService, $injector, $logger, $childProcess, $devicePlatformsConstants, $config, $usbLiveSyncService, $platformService, $options);
7472
}
7573
}
7674
$injector.registerCommand("debug|ios", DebugIOSCommand);
@@ -84,8 +82,9 @@ export class DebugAndroidCommand extends DebugPlatformCommand {
8482
$devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
8583
$config: IConfiguration,
8684
$usbLiveSyncService: ILiveSyncService,
85+
$platformService: IPlatformService,
8786
$options: IOptions) {
88-
super($androidDebugService, $devicesService, $injector, $logger, $childProcess, $devicePlatformsConstants, $config, $usbLiveSyncService, $options);
87+
super($androidDebugService, $devicesService, $injector, $logger, $childProcess, $devicePlatformsConstants, $config, $usbLiveSyncService, $platformService, $options);
8988
}
9089
}
9190
$injector.registerCommand("debug|android", DebugAndroidCommand);

lib/commands/deploy.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export class DeployOnDeviceCommand implements ICommand {
66
private $mobileHelper: Mobile.IMobileHelper) { }
77

88
execute(args: string[]): IFuture<void> {
9-
return this.$platformService.deployPlatform(args[0]);
9+
return this.$platformService.deployPlatform(args[0], true);
1010
}
1111

1212
public canExecute(args: string[]): IFuture<boolean> {

lib/commands/livesync.ts

+2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ export class LivesyncCommand implements ICommand {
33
private $usbLiveSyncService: ILiveSyncService,
44
private $mobileHelper: Mobile.IMobileHelper,
55
private $options: IOptions,
6+
private $platformService: IPlatformService,
67
private $errors: IErrors) { }
78

89
public execute(args: string[]): IFuture<void> {
10+
this.$platformService.deployPlatform(args[0]).wait();
911
return this.$usbLiveSyncService.liveSync(args[0]);
1012
}
1113

lib/commands/prepare.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export class PrepareCommand implements ICommand {
55

66
execute(args: string[]): IFuture<void> {
77
return (() => {
8-
this.$platformService.preparePlatform(args[0], true).wait();
8+
this.$platformService.preparePlatform(args[0]).wait();
99
}).future<void>()();
1010
}
1111

lib/commands/run.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ export class RunCommandBase {
44
protected $options: IOptions) { }
55

66
public executeCore(args: string[]): IFuture<void> {
7-
if (this.$options.watch) {
8-
this.$platformService.deployPlatform(args[0]).wait();
9-
return this.$usbLiveSyncService.liveSync(args[0]);
10-
} else {
7+
this.$platformService.deployPlatform(args[0]).wait();
8+
if (this.$options.release) {
119
return this.$platformService.runPlatform(args[0]);
1210
}
11+
return this.$usbLiveSyncService.liveSync(args[0]);
1312
}
1413
}
1514

lib/declarations.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,13 @@ interface IOpener {
5151
}
5252

5353
interface ILiveSyncService {
54-
liveSync(platform: string, applicationReloadAction?: (deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[]) => IFuture<void>): IFuture<void>;
55-
forceExecuteFullSync: boolean;
54+
liveSync(platform: string, applicationReloadAction?: (deviceAppData: Mobile.IDeviceAppData) => IFuture<void>): IFuture<void>;
5655
}
5756

5857
interface IPlatformLiveSyncService {
5958
fullSync(postAction?: (deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[]) => IFuture<void>): IFuture<void>;
6059
partialSync(event: string, filePath: string, dispatcher: IFutureDispatcher, afterFileSyncAction: (deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[]) => IFuture<void>): void;
61-
refreshApplication(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[]): IFuture<void>;
60+
refreshApplication(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[], isFullSync: boolean): IFuture<void>;
6261
}
6362

6463
interface IOptions extends ICommonOptions {
@@ -93,10 +92,10 @@ interface IOptions extends ICommonOptions {
9392
sdk: string;
9493
tnsModulesVersion: string;
9594
teamId: string;
96-
rebuild: boolean;
9795
syncAllFiles: boolean;
9896
liveEdit: boolean;
9997
chrome: boolean;
98+
clean: boolean;
10099
}
101100

102101
interface IInitService {

lib/definitions/platform.d.ts

+83-4
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,78 @@ interface IPlatformService {
2727
removePlatforms(platforms: string[]): void;
2828

2929
updatePlatforms(platforms: string[]): IFuture<void>;
30-
preparePlatform(platform: string, force?: boolean, skipModulesAndResources?: boolean): IFuture<boolean>;
31-
buildPlatform(platform: string, buildConfig?: IBuildConfig, forceBuild?: boolean): IFuture<void>;
32-
deployPlatform(platform: string): IFuture<void>;
30+
31+
/**
32+
* Ensures that the specified platform and its dependencies are installed.
33+
* When there are changes to be prepared, it prepares the native project for the specified platform.
34+
* When finishes, prepare saves the .nsprepareinfo file in platform folder.
35+
* This file contains information about current project configuration and allows skipping unnecessary build, deploy and livesync steps.
36+
* @param {string} platform The platform to be prepared.
37+
* @returns {boolean} true indicates that the platform was prepared.
38+
*/
39+
preparePlatform(platform: string, changesInfo?: IProjectChangesInfo): IFuture<boolean>;
40+
41+
/**
42+
* Determines whether a build is necessary. A build is necessary when one of the following is true:
43+
* - there is no previous build.
44+
* - the .nsbuildinfo file in product folder points to an old prepare.
45+
* @param {string} platform The platform to build.
46+
* @param {IBuildConfig} buildConfig Indicates whether the build is for device or emulator.
47+
* @returns {boolean} true indicates that the platform should be build.
48+
*/
49+
shouldBuild(platform: string, buildConfig?: IBuildConfig): IFuture<boolean>;
50+
51+
/**
52+
* Builds the native project for the specified platform for device or emulator.
53+
* When finishes, build saves the .nsbuildinfo file in platform product folder.
54+
* This file points to the prepare that was used to build the project and allows skipping unnecessary builds and deploys.
55+
* @param {string} platform The platform to build.
56+
* @param {IBuildConfig} buildConfig Indicates whether the build is for device or emulator.
57+
* @returns {void}
58+
*/
59+
buildPlatform(platform: string, buildConfig?: IBuildConfig): IFuture<void>;
60+
61+
/**
62+
* Determines whether installation is necessary. It is necessary when one of the following is true:
63+
* - the application is not installed.
64+
* - the .nsbuildinfo file located in application root folder is different than the local .nsbuildinfo file
65+
* @param {Mobile.IDevice} device The device where the application should be installed.
66+
* @returns {boolean} true indicates that the application should be installed.
67+
*/
68+
shouldInstall(device: Mobile.IDevice): boolean;
69+
70+
/**
71+
* Installs the application on specified device.
72+
* When finishes, saves .nsbuildinfo in application root folder to indicate the prepare that was used to build the app.
73+
* * .nsbuildinfo is not persisted when building for release.
74+
* @param {Mobile.IDevice} device The device where the application should be installed.
75+
* @returns {void}
76+
*/
77+
installApplication(device: Mobile.IDevice): IFuture<void>;
78+
79+
/**
80+
* Executes prepare, build and installOnPlatform when necessary to ensure that the latest version of the app is installed on specified platform.
81+
* - When --clean option is specified it builds the app on every change. If not, build is executed only when there are native changes.
82+
* @param {string} platform The platform to deploy.
83+
* @param {boolean} forceInstall When true, installs the application unconditionally.
84+
* @returns {void}
85+
*/
86+
deployPlatform(platform: string, forceInstall?: boolean): IFuture<void>;
87+
88+
/**
89+
* Runs the application on specified platform. Assumes that the application is already build and installed. Fails if this is not true.
90+
* @param {string} platform The platform where to start the application.
91+
* @returns {void}
92+
*/
3393
runPlatform(platform: string): IFuture<void>;
94+
95+
/**
96+
* The emulate command. In addition to `run --emulator` command, it handles the `--available-devices` option to show the available devices.
97+
* @param {string} platform The platform to emulate.
98+
* @returns {void}
99+
*/
34100
emulatePlatform(platform: string): IFuture<void>;
101+
35102
cleanDestinationApp(platform: string): IFuture<void>;
36103
validatePlatformInstalled(platform: string): void;
37104
validatePlatform(platform: string): void;
@@ -60,7 +127,14 @@ interface IPlatformService {
60127
copyLastOutput(platform: string, targetPath: string, settings: {isForDevice: boolean}): void;
61128

62129
lastOutputPath(platform: string, settings: { isForDevice: boolean }): string;
63-
ensurePlatformInstalled(platform: string): IFuture<void>;
130+
131+
/**
132+
* Reads contents of a file on device.
133+
* @param {Mobile.IDevice} device The device to read from.
134+
* @param {string} deviceFilePath The file path.
135+
* @returns {string} The contents of the file or null when there is no such file.
136+
*/
137+
readFile(device: Mobile.IDevice, deviceFilePath: string): IFuture<string>;
64138
}
65139

66140
interface IPlatformData {
@@ -97,4 +171,9 @@ interface INodeModulesBuilder {
97171

98172
interface INodeModulesDependenciesBuilder {
99173
getProductionDependencies(projectPath: string): void;
174+
}
175+
176+
interface IBuildInfo {
177+
prepareTime: string;
178+
buildTime: string;
100179
}

lib/definitions/project-changes.d.ts

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
interface IPrepareInfo {
2+
time: string;
3+
bundle: boolean;
4+
release: boolean;
5+
changesRequireBuild: boolean;
6+
changesRequireBuildTime: string;
7+
}
8+
9+
interface IProjectChangesInfo {
10+
appFilesChanged: boolean;
11+
appResourcesChanged: boolean;
12+
modulesChanged: boolean;
13+
configChanged: boolean;
14+
packageChanged: boolean;
15+
nativeChanged: boolean;
16+
hasChanges: boolean;
17+
changesRequireBuild: boolean;
18+
}
19+
20+
interface IProjectChangesService {
21+
checkForChanges(platform: string): IProjectChangesInfo;
22+
getPrepareInfo(platform: string): IPrepareInfo;
23+
savePrepareInfo(platform: string): void;
24+
getPrepareInfoFilePath(platform: string): string;
25+
currentChanges: IProjectChangesInfo;
26+
}

lib/options.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@ export class Options extends commonOptionsLibPath.OptionsBase {
3838
bundle: { type: OptionType.Boolean },
3939
all: { type: OptionType.Boolean },
4040
teamId: { type: OptionType.String },
41-
rebuild: { type: OptionType.Boolean, default: true },
4241
syncAllFiles: { type: OptionType.Boolean },
4342
liveEdit: { type: OptionType.Boolean },
44-
chrome: { type: OptionType.Boolean }
43+
chrome: { type: OptionType.Boolean },
44+
clean: { type: OptionType.Boolean },
45+
watch: { type: OptionType.Boolean, default: true },
4546
},
4647
path.join($hostInfo.isWindows ? process.env.AppData : path.join(osenv.home(), ".local/share"), ".nativescript-cli"),
4748
$errors, $staticConfig);

0 commit comments

Comments
 (0)