1
0
mirror of https://gitcode.com/github-mirrors/react-native-update-cli.git synced 2025-09-16 09:41:38 +08:00
Code Issues Packages Projects Releases Wiki Activity GitHub Gitee
This commit is contained in:
sunnylqm
2021-10-10 12:39:00 +08:00
parent 32d7ed9b00
commit 03a4108a08
8 changed files with 107 additions and 135 deletions

29
LICENSE
View File

@@ -1,29 +0,0 @@
BSD 3-Clause License
Copyright (c) 2020, reactnativecn
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,7 +1,3 @@
/**
* Created by tdzl2003 on 2/13/16.
*/
const fetch = require('node-fetch');
const defaultEndpoint = 'http://u.reactnative.cn/api';
let host = process.env.PUSHY_REGISTRY || defaultEndpoint;
@@ -140,11 +136,11 @@ async function uploadFile(fn, key) {
throw new Error(
`此文件大小${(fileSize / 1048576).toFixed(
1,
)}m, 超出当前额度${maxSize}。您可以考虑升级付费业务以提升此额度。详情请访问${pricingPageUrl}`,
)}m, 超出当前额度${maxSize}。您可以考虑升级付费业务以提升此额度。详情请访问: ${pricingPageUrl}`,
);
}
const bar = new ProgressBar(' Uploading [:bar] :percent :etas', {
const bar = new ProgressBar(' 上传中 [:bar] :percent :etas', {
complete: '=',
incomplete: ' ',
total: fileSize,
@@ -177,13 +173,7 @@ async function uploadFile(fn, key) {
Object.assign(new Error(body), { status: resp.statusCode }),
);
}
resolve(
body
? // qiniu
JSON.parse(body)
: // aliyun oss
{ hash: formData.key },
);
resolve({ hash: formData.key });
},
);
});

View File

@@ -1,7 +1,3 @@
/**
* Created by tdzl2003 on 2/13/16.
*/
import { question } from './utils';
import fs from 'fs';
const Table = require('tty-table');
@@ -15,7 +11,7 @@ const validPlatforms = {
export function checkPlatform(platform) {
if (!validPlatforms[platform]) {
throw new Error(`Invalid platform '${platform}'`);
throw new Error(`无法识别的平台 '${platform}'`);
}
return platform;
}
@@ -42,9 +38,9 @@ export async function listApp(platform) {
const list = platform ? data.filter((v) => v.platform === platform) : data;
const header = [
{ value: 'App Id' },
{ value: 'App Name' },
{ value: 'Platform' },
{ value: '应用 id' },
{ value: '应用名称' },
{ value: '平台' },
];
const rows = [];
for (const app of list) {
@@ -54,9 +50,9 @@ export async function listApp(platform) {
console.log(Table(header, rows).render());
if (platform) {
console.log(`\nTotal ${list.length} ${platform} apps`);
console.log(`\ ${list.length} ${platform} 个应用`);
} else {
console.log(`\nTotal ${list.length} apps`);
console.log(`\ ${list.length} 个应用`);
}
return list;
}
@@ -65,7 +61,7 @@ export async function chooseApp(platform) {
const list = await listApp(platform);
while (true) {
const id = await question('Enter appId:');
const id = await question('输入应用 id:');
const app = list.find((v) => v.id === (id | 0));
if (app) {
return app;
@@ -75,13 +71,13 @@ export async function chooseApp(platform) {
export const commands = {
createApp: async function ({ options }) {
const name = options.name || (await question('App Name:'));
const name = options.name || (await question('应用名称:'));
const { downloadUrl } = options;
const platform = checkPlatform(
options.platform || (await question('Platform(ios/android):')),
options.platform || (await question('平台(ios/android):')),
);
const { id } = await post('/app/create', { name, platform });
console.log(`Created app ${id}`);
console.log(`已成功创建应用id: ${id}`);
await this.selectApp({
args: [id],
options: { platform, downloadUrl },
@@ -91,10 +87,10 @@ export const commands = {
const { platform } = options;
const id = args[0] || chooseApp(platform);
if (!id) {
console.log('Canceled');
console.log('已取消');
}
await doDelete(`/app/${id}`);
console.log('Ok.');
console.log('操作成功');
},
apps: async function ({ options }) {
const { platform } = options;
@@ -102,7 +98,7 @@ export const commands = {
},
selectApp: async function ({ args, options }) {
const platform = checkPlatform(
options.platform || (await question('Platform(ios/android):')),
options.platform || (await question('平台(ios/android):')),
);
const id = args[0] || (await chooseApp(platform)).id;

View File

@@ -1,7 +1,3 @@
/**
* Created by tdzl2003 on 2/22/16.
*/
const path = require('path');
import { getRNVersion, translateOptions } from './utils';
import * as fs from 'fs-extra';
@@ -197,7 +193,7 @@ async function pack(dir, output) {
});
zipfile.end();
});
console.log('Bundled saved to: ' + output);
console.log('ppk热更包已生成并保存到: ' + output);
}
function readEntire(entry, zipFile) {
@@ -515,7 +511,7 @@ function diffArgsCheck(args, options, diffFn) {
export const commands = {
bundle: async function ({ options }) {
const platform = checkPlatform(
options.platform || (await question('Platform(ios/android):')),
options.platform || (await question('平台(ios/android):')),
);
let {
@@ -553,7 +549,7 @@ export const commands = {
await pack(path.resolve(intermediaDir), realOutput);
const v = await question('Would you like to publish it?(Y/N)');
const v = await question('是否现在上传此热更包?(Y/N)');
if (v.toLowerCase() === 'y') {
await this.publish({
args: [realOutput],

View File

@@ -1,21 +1,20 @@
#!/usr/bin/env node
/**
* Created by tdzl2003 on 2/13/16.
*/
const {loadSession} = require('./api');
const { loadSession } = require('./api');
const updateNotifier = require('update-notifier');
import { printVersionCommand } from './utils/index.js';
const pkg = require('../package.json');
updateNotifier({pkg}).notify({isGlobal: true});
updateNotifier({ pkg }).notify({ isGlobal: true });
function printUsage({args}) {
function printUsage({ args }) {
// const commandName = args[0];
// TODO: print usage of commandName, or print global usage.
console.log('Usage is under development now.')
console.log('Visit `https://github.com/reactnativecn/react-native-pushy` for early document.');
console.log('Usage is under development now.');
console.log(
'Visit `https://github.com/reactnativecn/react-native-pushy` for early document.',
);
process.exit(1);
}
@@ -39,15 +38,15 @@ function run() {
global.USE_ACC_OSS = argv.options['acc'];
loadSession()
.then(()=>commands[argv.command](argv))
.catch(err=>{
.then(() => commands[argv.command](argv))
.catch((err) => {
if (err.status === 401) {
console.log('Not loggined.\nRun `pushy login` at your project directory to login.');
console.log('尚未登录。\n请在项目目录中运行`pushy login`命令来登录');
return;
}
console.error(err.stack);
process.exit(-1);
});
};
}
run();

View File

@@ -30,7 +30,7 @@ export async function listPackage(appId) {
}
console.log(Table(header, rows).render());
console.log(`\nTotal ${data.length} package(s).`);
console.log(`\n ${data.length} 个包`);
return data;
}
@@ -38,7 +38,7 @@ export async function choosePackage(appId) {
const list = await listPackage(appId);
while (true) {
const id = await question('Enter Package Id:');
const id = await question('输入原生包 id:');
const app = list.find((v) => v.id === (id | 0));
if (app) {
return app;
@@ -50,7 +50,7 @@ export const commands = {
uploadIpa: async function ({ args }) {
const fn = args[0];
if (!fn || !fn.endsWith('.ipa')) {
throw new Error('Usage: pushy uploadIpa <ipaFile>');
throw new Error('使用方法: pushy uploadIpa ipa后缀文件');
}
const {
versionName,
@@ -62,13 +62,13 @@ export const commands = {
if (appIdInPkg && appIdInPkg !== appId) {
throw new Error(
`appId不匹配当前ipa${appIdInPkg}, 当前update.json${appId}`,
`appId不匹配当前ipa: ${appIdInPkg}, 当前update.json: ${appId}`,
);
}
if (appKeyInPkg && appKeyInPkg !== appKey) {
throw new Error(
`appKey不匹配当前ipa${appKeyInPkg}, 当前update.json${appKey}`,
`appKey不匹配当前ipa: ${appKeyInPkg}, 当前update.json: ${appKey}`,
);
}
@@ -80,12 +80,12 @@ export const commands = {
buildTime,
});
saveToLocal(fn, `${appId}/package/${id}.ipa`);
console.log(`Ipa uploaded: ${id}`);
console.log(`已成功上传ipa原生包id: ${id}`);
},
uploadApk: async function ({ args }) {
const fn = args[0];
if (!fn || !fn.endsWith('.apk')) {
throw new Error('Usage: pushy uploadApk <apkFile>');
throw new Error('使用方法: pushy uploadApk apk后缀文件');
}
const {
versionName,
@@ -97,13 +97,13 @@ export const commands = {
if (appIdInPkg && appIdInPkg !== appId) {
throw new Error(
`appId不匹配当前apk${appIdInPkg}, 当前update.json${appId}`,
`appId不匹配当前apk: ${appIdInPkg}, 当前update.json: ${appId}`,
);
}
if (appKeyInPkg && appKeyInPkg !== appKey) {
throw new Error(
`appKey不匹配当前apk${appKeyInPkg}, 当前update.json${appKey}`,
`appKey不匹配当前apk: ${appKeyInPkg}, 当前update.json: ${appKey}`,
);
}
@@ -115,25 +115,25 @@ export const commands = {
buildTime,
});
saveToLocal(fn, `${appId}/package/${id}.apk`);
console.log(`Apk uploaded: ${id}`);
console.log(`已成功上传apk原生包id: ${id}`);
},
parseIpa: async function ({ args }) {
const fn = args[0];
if (!fn || !fn.endsWith('.ipa')) {
throw new Error('Usage: pushy parseIpa <ipaFile>');
throw new Error('使用方法: pushy parseIpa ipa后缀文件');
}
console.log(await getIpaInfo(fn));
},
parseApk: async function ({ args }) {
const fn = args[0];
if (!fn || !fn.endsWith('.apk')) {
throw new Error('Usage: pushy parseApk <apkFile>');
throw new Error('使用方法: pushy parseApk apk后缀文件');
}
console.log(await getApkInfo(fn));
},
packages: async function ({ options }) {
const platform = checkPlatform(
options.platform || (await question('Platform(ios/android):')),
options.platform || (await question('平台(ios/android):')),
);
const { appId } = await getSelectedApp(platform);
await listPackage(appId);

View File

@@ -26,11 +26,11 @@ exports.commands = {
});
replaceSession({token});
await saveSession();
console.log(`Welcome, ${info.name}.`);
console.log(`欢迎使用 pushy 热更新服务, ${info.name}.`);
},
logout: async function (){
await closeSession();
console.log('Logged out.');
console.log('已退出登录');
},
me: async function (){
const me = await get('/user/me');

View File

@@ -1,13 +1,4 @@
/**
* Created by tdzl2003 on 4/2/16.
*/
const {
get,
post,
put,
uploadFile,
} = require('./api');
const { get, post, put, uploadFile } = require('./api');
import { question, saveToLocal } from './utils';
import { checkPlatform, getSelectedApp } from './app';
@@ -17,17 +8,24 @@ async function showVersion(appId, offset) {
const { data, count } = await get(`/app/${appId}/version/list`);
console.log(`Offset ${offset}`);
for (const version of data) {
let packageInfo = version.packages.slice(0, 3).map(v=>v.name).join(', ');
let packageInfo = version.packages
.slice(0, 3)
.map((v) => v.name)
.join(', ');
const count = version.packages.length;
if (count > 3) {
packageInfo += `...and ${count-3} more`;
packageInfo += `...and ${count - 3} more`;
}
if (count === 0) {
packageInfo = `(no package)`;
} else {
packageInfo = `[${packageInfo}]`;
}
console.log(`${version.id}) ${version.hash.slice(0, 8)} ${version.name} ${packageInfo}`);
console.log(
`${version.id}) ${version.hash.slice(0, 8)} ${
version.name
} ${packageInfo}`,
);
}
return data;
}
@@ -38,10 +36,17 @@ async function listVersions(appId) {
await showVersion(appId, offset);
const cmd = await question('page Up/page Down/Begin/Quit(U/D/B/Q)');
switch (cmd.toLowerCase()) {
case 'u': offset = Math.max(0, offset - 10); break;
case 'd': offset += 10; break;
case 'b': offset = 0; break;
case 'q': return;
case 'u':
offset = Math.max(0, offset - 10);
break;
case 'd':
offset += 10;
break;
case 'b':
offset = 0;
break;
case 'q':
return;
}
}
}
@@ -50,14 +55,21 @@ async function chooseVersion(appId) {
let offset = 0;
while (true) {
const data = await showVersion(appId, offset);
const cmd = await question('Enter versionId or page Up/page Down/Begin(U/D/B)');
const cmd = await question(
'Enter versionId or page Up/page Down/Begin(U/D/B)',
);
switch (cmd.toLowerCase()) {
case 'U': offset = Math.max(0, offset - 10); break;
case 'D': offset += 10; break;
case 'B': offset = 0; break;
default:
{
const v = data.find(v=>v.id === (cmd | 0));
case 'U':
offset = Math.max(0, offset - 10);
break;
case 'D':
offset += 10;
break;
case 'B':
offset = 0;
break;
default: {
const v = data.find((v) => v.id === (cmd | 0));
if (v) {
return v;
}
@@ -67,47 +79,55 @@ async function chooseVersion(appId) {
}
export const commands = {
publish: async function({args, options}) {
publish: async function ({ args, options }) {
const fn = args[0];
const {name, description, metaInfo } = options;
const { name, description, metaInfo } = options;
if (!fn || !fn.endsWith('.ppk')) {
throw new Error('Usage: pushy publish <ppkFile> --platform ios|android');
throw new Error(
'使用方法: pushy publish ppk后缀文件 --platform ios|android',
);
}
const platform = checkPlatform(options.platform || await question('Platform(ios/android):'));
const platform = checkPlatform(
options.platform || (await question('平台(ios/android):')),
);
const { appId } = await getSelectedApp(platform);
const { hash } = await uploadFile(fn);
const { id } = await post(`/app/${appId}/version/create`, {
name: name || await question('Enter version name:') || '(未命名)',
name: name || (await question('输入版本名称: ')) || '(未命名)',
hash,
description: description || await question('Enter description:'),
metaInfo: metaInfo || await question('Enter meta info:'),
description: description || (await question('输入版本描述:')),
metaInfo: metaInfo || (await question('输入自定义的 meta info:')),
});
// TODO local diff
saveToLocal(fn, `${appId}/ppk/${id}.ppk`);
console.log(`Version published: ${id}`);
console.log(`已成功上传新热更包id: ${id}`);
const v = await question('Would you like to bind packages to this version?(Y/N)');
const v = await question('是否现在将此热更应用到原生包上?(Y/N)');
if (v.toLowerCase() === 'y') {
await this.update({args:[], options:{versionId: id, platform}});
await this.update({ args: [], options: { versionId: id, platform } });
}
},
versions: async function({options}) {
const platform = checkPlatform(options.platform || await question('Platform(ios/android):'));
versions: async function ({ options }) {
const platform = checkPlatform(
options.platform || (await question('平台(ios/android):')),
);
const { appId } = await getSelectedApp(platform);
await listVersions(appId);
},
update: async function({args, options}) {
const platform = checkPlatform(options.platform || await question('Platform(ios/android):'));
update: async function ({ args, options }) {
const platform = checkPlatform(
options.platform || (await question('平台(ios/android):')),
);
const { appId } = await getSelectedApp(platform);
const versionId = options.versionId || (await chooseVersion(appId)).id;
const pkgId = options.packageId || (await choosePackage(appId)).id;
await put(`/app/${appId}/package/${pkgId}`, {
versionId,
});
console.log('Ok.');
}
console.log('操作成功');
},
};