Skip to content

Merge release into master #4143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Nov 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
adc72a8
fix(preview-api): remove release option from IPreviewAppLiveSyncData …
Fatme Nov 7, 2018
3dd44c1
chore: fix unit tests
Fatme Nov 7, 2018
77dd128
fix: fix project creation with github url passed as template
DimitarTachev Nov 12, 2018
b2afcf7
fix: fix linting errors
DimitarTachev Nov 13, 2018
937e050
Merge pull request #4124 from NativeScript/tachev/app-creation-github
Nov 13, 2018
8d80a75
feat(preview-api): Add api for getting logs from preview app
Fatme Nov 13, 2018
bf262d5
chore: fix unit tests
Fatme Nov 14, 2018
5832c89
fix(deps): update chokidar, so we can watch dirs with `(`
rosen-vladimirov Nov 14, 2018
9ddeac1
release: update CHANGELOG for 5.0.1
rosen-vladimirov Nov 14, 2018
b8e7861
Merge pull request #4136 from NativeScript/vladimirov/changelog-501
rosen-vladimirov Nov 14, 2018
9de52b7
chore: bump version to 5.0.2
rosen-vladimirov Nov 14, 2018
f53bb0c
Merge pull request #4137 from NativeScript/vladimirov/bump-ver-5.0.2
rosen-vladimirov Nov 14, 2018
f79baa2
Merge pull request #4133 from NativeScript/vladimirov/update-chokidar
rosen-vladimirov Nov 14, 2018
bc32b6b
Merge pull request #4106 from NativeScript/fatme/remove-release-preview
Nov 14, 2018
5df9866
Merge pull request #4131 from NativeScript/fatme/device-log-preview-api
Nov 16, 2018
37f2696
feat(preview-api): expose public api for getting device's warnings
Fatme Nov 13, 2018
662d56c
chore: fix unit tests
Fatme Nov 14, 2018
b3bc007
chore: fix PR comments
Fatme Nov 16, 2018
986673d
Merge pull request #4132 from NativeScript/fatme/preview-api-device-w…
Nov 16, 2018
8b29f3a
fix: store the platform status on `platform add` in order to avoid an…
DimitarTachev Nov 16, 2018
03d9ba3
fix: skip clean platform in case it has not been prepared
rosen-vladimirov Nov 16, 2018
1afcdc3
Merge pull request #4139 from NativeScript/tachev/store-platform-stat…
Nov 19, 2018
0eb71b6
Merge branch 'release' into 'master'
DimitarTachev Nov 19, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
NativeScript CLI Changelog
================

5.0.1 (2018, November 14)
==
### Implemented
* [Implemented #4083](https://github.com/NativeScript/nativescript-cli/pull/4083): API: Add public API for deviceFound and deviceLost for preview devices
* [Implemented #4087](https://github.com/NativeScript/nativescript-cli/pull/4087): API: Expose public method for getting the qr code of playground app
* [Implemented #4093](https://github.com/NativeScript/nativescript-cli/pull/4093): API: Expose public api for starting the livesync operation to preview app

### Fixed
* [Fixed #2670](https://github.com/NativeScript/nativescript-cli/issues/2670): Command line `tns run android --clean` rebuilds
* [Fixed #4043](https://github.com/NativeScript/nativescript-cli/issues/4043): `tns preview` fails when local plugin is referenced with tag in `package.json`
* [Fixed #4046](https://github.com/NativeScript/nativescript-cli/issues/4046):`tns debug ios` does not work with bigger projects on slower devices
* [Fixed #4055](https://github.com/NativeScript/nativescript-cli/pull/4055): API: Remove persisted emulator's data on deviceLost event
* [Fixed #4056](https://github.com/NativeScript/nativescript-cli/pull/4056): API: `TypeError: Invalid Version: null` is thrown when emulator is stopped immediately after start
* [Fixed #4071](https://github.com/NativeScript/nativescript-cli/issues/4071): Unable to run `tns test <platform>`
* [Fixed #4073](https://github.com/NativeScript/nativescript-cli/pull/4073): Error is thrown when Node.js 11 is used
* [Fixed #4076](https://github.com/NativeScript/nativescript-cli/issues/4076): Cannot connect to device socket when run debug with justlaunch
* [Fixed #4079](https://github.com/NativeScript/nativescript-cli/pull/4079): API: Reset errors when fallback to list avds from director
* [Fixed #4090](https://github.com/NativeScript/nativescript-cli/issues/4090): `tns preview` and `tns platform add ...` issue
* [Fixed #4096](https://github.com/NativeScript/nativescript-cli/issues/4096): NativeScript v4 is not using the v4 of the app templates during project creation
* [Fixed #4100](https://github.com/NativeScript/nativescript-cli/issues/4100): Apply `before-plugins.gradle` file in the plugin `build.gradle`


5.0.0 (2018, November 1)
==

Expand Down
63 changes: 61 additions & 2 deletions lib/base-package-manager.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,62 @@
import { isInteractive } from "./common/helpers";

export class BasePackageManager {
export abstract class BasePackageManager implements INodePackageManager {
public abstract install(packageName: string, pathToSave: string, config: INodePackageManagerInstallOptions): Promise<INpmInstallResultInfo>;
public abstract uninstall(packageName: string, config?: IDictionary<string | boolean>, path?: string): Promise<string>;
public abstract view(packageName: string, config: Object): Promise<any>;
public abstract search(filter: string[], config: IDictionary<string | boolean>): Promise<string>;
public abstract searchNpms(keyword: string): Promise<INpmsResult>;
public abstract getRegistryPackageData(packageName: string): Promise<any>;
public abstract getCachePath(): Promise<string>;

constructor(
protected $childProcess: IChildProcess,
protected $fs: IFileSystem,
private $hostInfo: IHostInfo,
private $pacoteService: IPacoteService,
private packageManager: string
) { }

public async isRegistered(packageName: string): Promise<boolean> {
if (this.isURL(packageName) || this.$fs.exists(packageName) || this.isTgz(packageName)) {
return false;
}

try {
const viewResult = await this.view(packageName, { name: true });

// `npm view nonExistingPackageName` will return `nativescript`
// if executed in the root dir of the CLI (npm 6.4.1)
const packageNameRegex = new RegExp(packageName, "i");
const isProperResult = packageNameRegex.test(viewResult);

return isProperResult;
} catch (e) {
return false;
}
}

public async getPackageNameParts(fullPackageName: string): Promise<INpmPackageNameParts> {
// support <reserved_name>@<version> syntax, for example [email protected]
// support <scoped_package_name>@<version> syntax, for example @nativescript/[email protected]
const lastIndexOfAtSign = fullPackageName.lastIndexOf("@");
let version = "";
let templateName = "";
if (lastIndexOfAtSign > 0) {
templateName = fullPackageName.substr(0, lastIndexOfAtSign).toLowerCase();
version = fullPackageName.substr(lastIndexOfAtSign + 1);
}

return {
name: templateName || fullPackageName,
version: version
};
}

public async getPackageFullName(packageNameParts: INpmPackageNameParts): Promise<string> {
return packageNameParts.version ? `${packageNameParts.name}@${packageNameParts.version}` : packageNameParts.name;
}

protected getPackageManagerExecutableName(): string {
let npmExecutableName = this.packageManager;

Expand Down Expand Up @@ -44,7 +93,7 @@ export class BasePackageManager {
array.push(`--${flag}`);
array.push(`${config[flag]}`);
} else if (config[flag]) {
if (flag === "dist-tags" || flag === "versions") {
if (flag === "dist-tags" || flag === "versions" || flag === "name") {
array.push(` ${flag}`);
continue;
}
Expand All @@ -57,4 +106,14 @@ export class BasePackageManager {

return array.join(" ");
}

private isTgz(packageName: string): boolean {
return packageName.indexOf(".tgz") >= 0;
}

private isURL(str: string): boolean {
const urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$';
const url = new RegExp(urlRegex, 'i');
return str.length < 2083 && url.test(str);
}
}
1 change: 1 addition & 0 deletions lib/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ $injector.require("androidLiveSyncService", "./services/livesync/android-livesyn
$injector.require("iOSLiveSyncService", "./services/livesync/ios-livesync-service");
$injector.require("usbLiveSyncService", "./services/livesync/livesync-service"); // The name is used in https://github.com/NativeScript/nativescript-dev-typescript
$injector.require("previewAppLiveSyncService", "./services/livesync/playground/preview-app-livesync-service");
$injector.require("previewAppLogProvider", "./services/livesync/playground/preview-app-log-provider");
$injector.require("previewAppPluginsService", "./services/livesync/playground/preview-app-plugins-service");
$injector.require("previewSdkService", "./services/livesync/playground/preview-sdk-service");
$injector.requirePublicClass("previewDevicesService", "./services/livesync/playground/devices/preview-devices-service");
Expand Down
8 changes: 8 additions & 0 deletions lib/commands/preview.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { DEVICE_LOG_EVENT_NAME } from "../common/constants";

export class PreviewCommand implements ICommand {
public allowedParameters: ICommandParameter[] = [];
private static MIN_SUPPORTED_WEBPACK_VERSION = "0.17.0";

constructor(private $bundleValidatorHelper: IBundleValidatorHelper,
private $errors: IErrors,
private $liveSyncService: ILiveSyncService,
private $logger: ILogger,
private $networkConnectivityValidator: INetworkConnectivityValidator,
private $projectData: IProjectData,
private $options: IOptions,
private $previewAppLogProvider: IPreviewAppLogProvider,
private $previewQrCodeService: IPreviewQrCodeService) { }

public async execute(): Promise<void> {
this.$previewAppLogProvider.on(DEVICE_LOG_EVENT_NAME, (deviceId: string, message: string) => {
this.$logger.info(message);
});

await this.$liveSyncService.liveSync([], {
syncToPreviewApp: true,
projectDir: this.$projectData.projectDir,
Expand Down
31 changes: 29 additions & 2 deletions lib/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ interface INodePackageManager {
*/
view(packageName: string, config: Object): Promise<any>;

/**
* Checks if the specified string is name of a packaged published in the NPM registry.
* @param {string} packageName The string to be checked.
* @return {Promise<boolean>} True if the specified string is a registered package name, false otherwise.
*/
isRegistered(packageName: string): Promise<boolean>;

/**
* Separates the package name and version from a specified fullPackageName.
* @param {string} fullPackageName The full name of the package like [email protected].
* @return {INpmPackageNameParts} An object containing the separated package name and version.
*/
getPackageNameParts(fullPackageName: string): Promise<INpmPackageNameParts>

/**
* Returns the full name of an npm package based on the provided name and version.
* @param {INpmPackageNameParts} packageNameParts An object containing the package name and version.
* @return {string} The full name of the package like [email protected].
*/
getPackageFullName(packageNameParts: INpmPackageNameParts): Promise<string>

/**
* Searches for a package.
* @param {string[]} filter Keywords with which to perform the search.
Expand Down Expand Up @@ -59,6 +80,7 @@ interface IPackageInstallationManager {
getLatestVersion(packageName: string): Promise<string>;
getNextVersion(packageName: string): Promise<string>;
getLatestCompatibleVersion(packageName: string, referenceVersion?: string): Promise<string>;
getLatestCompatibleVersionSafe(packageName: string, referenceVersion?: string): Promise<string>;
getInspectorFromCache(inspectorNpmPackageName: string, projectDir: string): Promise<string>;
}

Expand Down Expand Up @@ -353,6 +375,11 @@ interface INpmsPackageData {
maintainers: INpmsUser[];
}

interface INpmPackageNameParts {
name: string;
version: string;
}

interface IUsername {
username: string;
}
Expand Down Expand Up @@ -537,9 +564,9 @@ interface IEnvOptions {

interface IAndroidBuildOptionsSettings extends IAndroidReleaseOptions, IRelease, IHasAndroidBundle { }

interface IHasAndroidBundle {
interface IHasAndroidBundle {
androidBundle?: boolean;
}
}

interface IAppFilesUpdaterOptions extends IBundle, IRelease, IOptionalWatchAllFiles, IHasUseHotModuleReloadOption { }

Expand Down
8 changes: 7 additions & 1 deletion lib/definitions/preview-app-livesync.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ declare global {
stopLiveSync(): Promise<void>;
}

interface IPreviewAppLiveSyncData extends IProjectDir, IAppFilesUpdaterOptionsComposition, IEnvOptions { }
interface IPreviewAppLiveSyncData extends IProjectDir, IHasUseHotModuleReloadOption, IBundle, IEnvOptions { }

interface IPreviewSdkService extends EventEmitter {
getQrCodeUrl(options: IHasUseHotModuleReloadOption): string;
Expand All @@ -18,10 +18,15 @@ declare global {
}

interface IPreviewAppPluginsService {
getPluginsUsageWarnings(data: IPreviewAppLiveSyncData, device: Device): string[];
comparePluginsOnDevice(data: IPreviewAppLiveSyncData, device: Device): Promise<void>;
getExternalPlugins(device: Device): string[];
}

interface IPreviewAppLogProvider extends EventEmitter {
logData(log: string, deviceName: string, deviceId: string): void;
}

interface IPreviewQrCodeService {
getPlaygroundAppQrCode(options?: IPlaygroundAppQrCodeOptions): Promise<IDictionary<IQrCodeImageData>>;
getLiveSyncQrCode(url: string): Promise<IQrCodeImageData>;
Expand All @@ -45,5 +50,6 @@ declare global {
updateConnectedDevices(devices: Device[]): void;
getDeviceById(id: string): Device;
getDevicesForPlatform(platform: string): Device[];
getPluginsUsageWarnings(data: IPreviewAppLiveSyncData, device: Device): string[];
}
}
14 changes: 7 additions & 7 deletions lib/definitions/project-changes.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
interface IAppFilesHashes {
appFilesHashes: IStringDictionary;
appFilesHashes?: IStringDictionary;
}

interface IPrepareInfo extends IAddedNativePlatform, IAppFilesHashes {
time: string;
bundle: boolean;
release: boolean;
projectFileHash: string;
changesRequireBuild: boolean;
changesRequireBuildTime: string;
time?: string;
bundle?: boolean;
release?: boolean;
projectFileHash?: string;
changesRequireBuild?: boolean;
changesRequireBuildTime?: string;
iOSProvisioningProfileUUID?: string;
}

Expand Down
6 changes: 3 additions & 3 deletions lib/node-package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { BasePackageManager } from "./base-package-manager";
import { exported, cache } from "./common/decorators";
import { CACACHE_DIRECTORY_NAME } from "./constants";

export class NodePackageManager extends BasePackageManager implements INodePackageManager {
export class NodePackageManager extends BasePackageManager {
constructor(
$childProcess: IChildProcess,
private $errors: IErrors,
private $fs: IFileSystem,
$fs: IFileSystem,
$hostInfo: IHostInfo,
private $logger: ILogger,
private $httpClient: Server.IHttpClient,
$pacoteService: IPacoteService) {
super($childProcess, $hostInfo, $pacoteService, 'npm');
super($childProcess, $fs, $hostInfo, $pacoteService, 'npm');
}

@exported("npm")
Expand Down
30 changes: 13 additions & 17 deletions lib/package-installation-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ export class PackageInstallationManager implements IPackageInstallationManager {
return maxSatisfying || latestVersion;
}

public async getLatestCompatibleVersionSafe(packageName: string, referenceVersion?: string): Promise<string> {
let version = "";
const canGetVersionFromNpm = await this.$packageManager.isRegistered(packageName);
if (canGetVersionFromNpm) {
version = await this.getLatestCompatibleVersion(packageName, referenceVersion);
}

return version;
}

public async install(packageToInstall: string, projectDir: string, opts?: INpmInstallOptions): Promise<any> {
try {
const pathToSave = projectDir;
Expand Down Expand Up @@ -101,6 +111,7 @@ export class PackageInstallationManager implements IPackageInstallationManager {
if (this.$fs.exists(pathToInspector)) {
return true;
}

return false;
}

Expand All @@ -110,28 +121,13 @@ export class PackageInstallationManager implements IPackageInstallationManager {
packageName = possiblePackageName;
}

// check if the packageName is url or local file and if it is, let npm install deal with the version
if (this.isURL(packageName) || this.$fs.exists(packageName) || this.isTgz(packageName)) {
version = null;
} else {
version = version || await this.getLatestCompatibleVersion(packageName);
}

version = version || await this.getLatestCompatibleVersionSafe(packageName);
const installResultInfo = await this.npmInstall(packageName, pathToSave, version, dependencyType);
const installedPackageName = installResultInfo.name;

const pathToInstalledPackage = path.join(pathToSave, "node_modules", installedPackageName);
return pathToInstalledPackage;
}

private isTgz(packageName: string): boolean {
return packageName.indexOf(".tgz") >= 0;
}

private isURL(str: string): boolean {
const urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$';
const url = new RegExp(urlRegex, 'i');
return str.length < 2083 && url.test(str);
return pathToInstalledPackage;
}

private async npmInstall(packageName: string, pathToSave: string, version: string, dependencyType: string): Promise<INpmInstallResultInfo> {
Expand Down
17 changes: 16 additions & 1 deletion lib/package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class PackageManager implements INodePackageManager {
private $options: IOptions,
private $yarn: INodePackageManager,
private $userSettingsService: IUserSettingsService
) {}
) { }

@cache()
protected async init(): Promise<void> {
Expand Down Expand Up @@ -42,6 +42,21 @@ export class PackageManager implements INodePackageManager {
return this.packageManager.searchNpms(keyword);
}

@invokeInit()
public async isRegistered(packageName: string): Promise<boolean> {
return this.packageManager.isRegistered(packageName);
}

@invokeInit()
public async getPackageFullName(packageNameParts: INpmPackageNameParts): Promise<string> {
return this.packageManager.getPackageFullName(packageNameParts);
}

@invokeInit()
public async getPackageNameParts(fullPackageName: string): Promise<INpmPackageNameParts> {
return this.packageManager.getPackageNameParts(fullPackageName);
}

@invokeInit()
public getRegistryPackageData(packageName: string): Promise<any> {
return this.packageManager.getRegistryPackageData(packageName);
Expand Down
Loading