From 9da88cd0eef735e63212f176cc30dd3e220e1c0c Mon Sep 17 00:00:00 2001 From: Sang_Sang33 Date: Wed, 6 Jul 2022 11:52:36 +0800 Subject: [PATCH 1/2] add: hpm-cli md Signed-off-by: Sang_Sang33 --- .../1.\346\246\202\350\277\260.md" | 21 + .../2.HPMCLI.md" | 110 +++++ .../3.bundleJson.md" | 403 ++++++++++++++++++ .../4.GUI.md" | 82 ++++ ...22\344\273\266\345\274\200\345\217\221.md" | 290 +++++++++++++ .../6.API\345\217\202\350\200\203.md" | 391 +++++++++++++++++ 6 files changed, 1297 insertions(+) create mode 100644 "CLI \346\217\222\344\273\266\345\274\200\345\217\221/1.\346\246\202\350\277\260.md" create mode 100644 "CLI \346\217\222\344\273\266\345\274\200\345\217\221/2.HPMCLI.md" create mode 100644 "CLI \346\217\222\344\273\266\345\274\200\345\217\221/3.bundleJson.md" create mode 100644 "CLI \346\217\222\344\273\266\345\274\200\345\217\221/4.GUI.md" create mode 100644 "CLI \346\217\222\344\273\266\345\274\200\345\217\221/5.\346\217\222\344\273\266\345\274\200\345\217\221.md" create mode 100644 "CLI \346\217\222\344\273\266\345\274\200\345\217\221/6.API\345\217\202\350\200\203.md" diff --git "a/CLI \346\217\222\344\273\266\345\274\200\345\217\221/1.\346\246\202\350\277\260.md" "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/1.\346\246\202\350\277\260.md" new file mode 100644 index 0000000..20cf949 --- /dev/null +++ "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/1.\346\246\202\350\277\260.md" @@ -0,0 +1,21 @@ +## 概念 +[HPM CLI](https://hpm-beta.cbg.huawei.com/#/cn/help/command):HarmonyOS的包管理器命令行工具,通常被IDE集成使用,也用于持续集成环境中。 + +[bundle.json](https://hpm-beta.cbg.huawei.com/#/cn/help/bundle):包的元数据描述文件,文件格式为JSON,声明包的名称,版本,类型,描述等信息。 + +[HPM CLI UI](https://hpm-beta.cbg.huawei.com/#/cn/help/gui):HPM CLI工具的可视化GUI页面,通过`hpm ui`命令启动。 + +[plugin](https://hpm-beta.cbg.huawei.com/#/cn/help/plugin):可由hpm-cli安装的hpm包,是插件的发布单元。 + +[addon](https://hpm-beta.cbg.huawei.com/#/cn/help/plugin):可以理解为UI插件,包含于plugin,不能独立发布,一个cli插件可以包含UI,也可以不含UI,也可以发布一个只含UI的插件包。 + +## 架构图参考 + +架构图参考 + + +plugin、addon都是发布类型为*publishAs: plugin*的组件包,plugin主要是对HPM CLI额外命令的能力扩展,addon主要是对HPM CLI UI额外页面的能力扩展。 + +HPM CLI会在全局目录下解析组件依赖关系,筛选发布类型为*publishAs: plugin*的组件包,根据[元数据bundle.json](https://hpm-beta.cbg.huawei.com/#/cn/help/bundle)里提供的入口*entry*,执行插件提供的方法,并注入HPM CLI提供给插件的[API](https://hpm-beta.cbg.huawei.com/#/cn/help/hpmapi)实现插件注入的逻辑。 + +**插件都需要通过全局安装的方式下载到全局目录(globalRepo)下** diff --git "a/CLI \346\217\222\344\273\266\345\274\200\345\217\221/2.HPMCLI.md" "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/2.HPMCLI.md" new file mode 100644 index 0000000..4724c7e --- /dev/null +++ "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/2.HPMCLI.md" @@ -0,0 +1,110 @@ +# HPM CLI + +HPM CLI 的是HarmonyOS的包管理器命令行工具,通常被IDE集成使用,也可用于持续集成环境中。 + +### 如何安装: + +1. 设置`npm`镜像源 +建议将 npm 源配置为国内镜像,例如设置为华为云镜像源。 +```shell +npm config set registry https://repo.huaweicloud.com +``` + +2. 下载`hpm-cli` +打开命令行工具,执行如下命令安装最新版本HPM。 +```shell +npm install -g @ohos/hpm-cli +``` + +3. 检查是否安装成功 +安装完成后,执行如下命令: +```shell +hpm -V +``` +终端输出日志为最新版本(如 1.5.0、1.4.5)则表示安装成功。 + +`tips`: + - `hpm-cli`仅支持`nodejs 12.x`及以上版本,请提前在机器上安装好`nodejs`; + - 如果网络不能直接访问`Internet`,需要通过代理服务器才可以访问,请先配置[npm代理](https://device.harmonyos.com/cn/docs/documentation/guide/npm_proxy-0000001054491032); + +### 如何更新版本: + +```sh +npm update -g @ohos/hpm-cli +``` +### 如何卸载: + +```sh +npm rm -g @ohos/hpm-cli +``` + +### 如何更改配置 +配置文件存放在~/.hpm/hpmrc, 显示默认配置,执行: +```sh +hpm config +``` +设置配置,执行: +```sh +hpm config set key value +``` +配置文件的内容如下所示: +```properties +registry = https://repo.harmonyos.com + +# 登录设置 +# loginUser = invitation_code + +# 路径设置 +shellPath = C:\WINDOWS\System32\cmd.exe +globalRepo = C:\Users\username\.hpm\global + +# 网络设置 +# no_proxy = *.server.com +# http_proxy = http://account:pwd@proxy_server:port +# https_proxy = http://account:pwd@proxy_server:port +strictSsl = true + +# 其他设置 +# privateSupport = true|false +# ignoreBundles = @ohos/llvm,@ohos/gn, +# OSPlatform = Auto|linux|darwin|win32 +# restoreCodeSegment = true|false +``` + +### 常用命令: + +| 命令类别 | 命令行 | 含义说明 | +| ------------------ | ------------------------------ | ------------------------------------------------------------ | +| 版本查询 | hpm -V 或 hpm --version | 查看hpm-cli 版本号。 | +| 帮助查询 | hpm -h | 查看命令帮助列表 | +| 创建 | hpm init bundle | 创建组件工程 | +| | hpm init -t template | 根据模板创建脚手架工程 | +| 安装 | hpm install 或hpm i | 安装bundle.json中依赖的组件 | +| | hpm install bundle@version | 安装指定组件版本 | +| 卸载 | hpm uninstall bundle | 删除depedencies依赖的组件。 | +| | hpm remove 或hpm rm bundlename | 删除depedencies依赖的组件 | +| 查看 | hpm list 或者 hpm ls | 显示当前组件/发行版所有的组件树 | +| | hpm dependencies | 生成当前组件/发行版依赖关系图(html格式) | +| 搜索 | hpm search name | 搜索组件,--json,可以以json格式输出 -type 可以设置搜索组件的类型,包括bundle,distribution,code-segment,solution | +| 设置hpm配置项 | hpm config set key value | 设置配置值,如服务器地址,网络代理 | +| | hpm config delete key | 删除配置 | +| | hpm config get key | 获取单个配置项 | +| | hpm config list | 获取所有的配置项列表 | +| 更新 | hpm update | 更新当前组件依赖的组件的版本 | +| | hpm check-update | 检查依赖的组件版本是否有更新 | +| 编译 | hpm build | 编译组件/发行版 | +| | hpm dist | 发行版打包(依赖bundle.json的scripts中的dist脚本) | +| 打包 | hpm pack | 本地组件打包依赖 | +| 烧录 | hpm run flash | 烧录固件(依赖bundle.json的scripts中的flash脚本) | +| 发布 | hpm publish | 发布组件,发布的组件在仓库中必须唯一,且版本唯一(需要账号登录) | +| 执行扩展命令 | hpm run | 执行bundle.json文件中定义的scripts脚本命令,支持多个命令可用 && 连接 | +| 生成秘钥 | hpm gen-keys | 生成公钥/私钥对,将公钥配置到HPM服务端,可以实现hpm-cli 免密登录,发布组件 | +| 生成第三方开源说明 | hpm gen-notice | 根据每个组件的说明,生成一份合并后的第三方开源说明的合并文件 | +| 解压文件 | hpm extract或x | 解压文件. 支持格式'zip','tar','tgz' 和'.tar.gz' | +| 启动HPM UI | hpm ui | 启动HPM UI | +| 切换语言 | hpm lang | 切换语言 | +| 插件转换 | hpm x2h | 把一个包发布到HPM, 支持的包类型有'gradle', 'maven'和'npm' | +| 代码还原 | hpm code clean | 删除code-segment类型的组件还原路径下的目录文件 | +| | hpm code restore | 还原code-segment类型的组件还原路径下的目录文件 | +| 下载资源 | hpm fetch | 获取当前平台(win32、linux、darwin)的资源url并解压 | + diff --git "a/CLI \346\217\222\344\273\266\345\274\200\345\217\221/3.bundleJson.md" "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/3.bundleJson.md" new file mode 100644 index 0000000..b6cad05 --- /dev/null +++ "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/3.bundleJson.md" @@ -0,0 +1,403 @@ +## 完整的元数据示例 + +```json +{ + "name": "@org/name", + "version": "1.0.0-semver", + "description": "Brief description", + "license": "MIT OR Apache V2 OR UNLICENSED OR ...", + "publishAs": "source OR code-segment OR binary OR distribution", + "hompage": "https://hpm.harmonyos.com/#/@scope/name", + "repository": "https://git@gitee.com:foo/bar.git", + "author": { + "name": "hos", + "email": "my@email.com", + "url": "http://my.homepage.com" + }, + "rom": "16M", + "ram": "6.4K", + "contributors": [ + { + "name": "hos", + "email": "hos@email.com", + "url": "http://hos.homepage.com" + }, + { + "name": "jack", + "email": "jack@email.com", + "url": "http://jack.homepage.com" + } + ], + "keywords": [ + "foo", + "bar" + ], + "tags": [ + "kernel", + "test", + "drivers" + ], + "dirs": { + "src": [ + "src/**/*.c" + ], + "headers": [ + "headers/**/*.h" + ], + "bin": [ + "bin/**/*.o" + ] + }, + "scripts": { + "build": "make", + "test": "echo test", + "e2e": "hpm run build && hpm run test && hpm run pack", + "pre_install": "echo before install hook event", + "after_install": "echo after install hook event", + "pre_build": "echo before build hook event", + "after_build": "echo after build hook event", + "pre_dist": "echo before distribute hook event", + "after_dist": "echo after distribute hook event", + "pre_pack": "echo before package hook event", + "after_pack": "echo after package hook event" + }, + "dependencies": { + "@scope/keeplatest": "^3.0.0", + "@scope/bundle_with_envs": { + "version": "^3.0.0", + "target": "arm", + "xxx": [ + "yyy", + "zzz" + ] + }, + "@scope/fixversion": "2.0.0", + "#tools": { + "@scope/tool_a": "1.0.0", + "@scope/tool_b": "1.0.0" + }, + "#options": { + "?@scope/opt_bundle1": "1.0.0", + "?@scope/opt_bundle2": "2.0.0" + } + }, + "excludes": [ + "@scope/opt_b1_in_dist", + "@scope/opt_b2_in_dist" + ], + "envs": { + "target": "arm", + "sysroot": "./dir", + "dumpmachine": "" + }, + "ohos": { + "os": "1.0.0", + "board": "hi3516", + "kernel": "liteos-a" + }, + "base": { + "name": "@scope/wifi_iot_hi3861", + "version": "1.0.0" + }, + "segment": { + "destpath": "domain/system" + } +} +``` + +## 每个字段说明 + +### name + +​bundle的名称,格式如@org/name,全局唯一,其中org为组织的名称,name为组件的名称,不同组织下,可以有同名的组件。 +除了@和/作为分隔符之外,组件名称只能包含小写字母、数字和下划线,长度限制不能超过200个字符。 + +### version + +bundle的版本,组件的内容更改后,需要更新version字段。名称+版本是组件的唯一标识,格式需符合语义化版本规范:如1.0.0,2.1.2-beta,详情请参考:。 + +### description + +【可选】一句话描述组件是什么,不超过500字,详细描述请放在README.md文档中。 + +### license + +组件使用的许可协议,如MIT,Apache-2.0,或其他。license的详细描述请放在根目录的LICENSE文件中。 +license命名需遵循spdx license规范,详情请参考:。 +若license不在spdx清单里,请发送license原文、可信认证等资料到hpm公开邮箱,等待工作人员审批。 + +### publishAs + +组件的发布形式: + +- binary:二进制形式,组件发布会经过build操作,只会将二进制内容打包发布到组件仓库。 +- source:源代码形式,组件发布会将源代码打包直接发布到组件仓库。 +- code-segment:只作为代码片段,被其他组件引用(如复制到指定路径),无需编译。 +- distribution:发行版形式,组件中的编译构建脚本及包含的组件依赖关系发布到组件仓库。 +- plugin: 插件形式。 + +### hompage + +【可选】组件的主页URL地址。 + +### repository + +【可选】组件的开源代码仓库地址。 + +### author + +​【可选】:组件的作者,只能填写一个人,格式如name(homepage)邮件和主页不是必须的。 +​以下是完整的格式,后续支持简化的格式name(homepage)。 + +```json +{ + "author": { + "name": "hos", + "email": "my@email.com", + "url": "http://my.homepage.com" + } +} +``` + +### rom + +【可选】组件预计会占用的空间大小,默认单位为byte,也可以填写单位如k,m 如:10k,26m,1.4k,1024。 + +### ram + +【可选】组件预计会占用的内存大小,可以填写单位如k,m 如:10k,1.2m,3m,1024。 + +### contributors + +【可选】【数组】组件贡献者列表,单个贡献者的格式同author一致。 + +```json +{ + "contributors": [ + { + "name": "hos", + "email": "hos@email.com", + "url": "http://hos.homepage.com" + }, + { + "name": "jack", + "email": "jack@email.com", + "url": "http://jack.homepage.com" + } + ] +} +``` + +### keywords + +​【可选】:组件的关键字列表,用于在HPM平台搜索使用。 + +```json +{ + "keywords":["iot","file"] +} +``` + +### tags + +​【可选】:组件的分类标签,用户在HPM平台过滤使用,需要参照HPM定义的Category填写,否则无法生效。 + +```json +{ + "tags":["application","kernel"] +} +``` + +### dirs + +​定义组件打包后的目录结构。 +当publishAs为binary时需要指定 headers和bin目录,它们的值满足glob匹配规则,系统会根据定义的规则匹配出对应的文件,然后将文件放入对应的headers或者bin目录中。 + +​例如: + +```json +{ + "dirs": { + "headers": [ + "headers/**/*.h" + ], + "bin": [ + "bin/**/*.o" + ] + } +} +``` + +​当publishAs为source时需要指定目录,会将所有文件打包。 + +```json +{ + "dirs": { + "src": [ "src/**/*.c" ] + } +} +``` + +​当publishAs为code-segment时不需要目录,会将所有文件打包。 + +### scripts + +​【可选】:hpm除了预置的几个编译构建打包命令如install,build,dist,pack之外,其余的命令可以用户自己扩展。 + +- 自定义命令:自己命名的命令,通过hpm run xxxcmd的方式执行,命令的执行调用第三方工具执行,可以多个链接执行。(注意执行命令的shell,如果shell不支持(如cmd),需要修改命令,或通过hpm config set shellPath修改) +- 命令钩子:可以在标准的命令执行前后执行其他动作。通过pre_cmd或after_cmd的方式定义命令,表示在执行cmd命令前先执行的动作,after_cmd的方式。 + +```json +{ + "scripts": { + "build": "make", + "test": "echo test", + "e2e": "hpm run build && hpm run test && hpm run pack", + "pre_install": "echo before install hook event", + "after_install": "echo after install hook event", + "pre_build": "echo before build hook event", + "after_build": "echo after build hook event", + "pre_dist": "echo before distribute hook event", + "after_dist": "echo after distribute hook event", + "pre_pack": "echo before package hook event", + "after_pack": "echo after package hook event" + } +} +``` + +### dependencies + +组件的依赖关系分为运行态依赖,和开发态依赖。运行态依赖指的是系统运行时必须的组件,会和依赖的组件一起参与编译。 +开发依赖只在被直接依赖的bundle生效,作为开发当前组件需要的组件,运行时不需要依赖,间接依赖的不会被下载。 +定义组件的依赖关系,格式如下,可以指定组件的名称,版本以及环境变量(非必需)。 +可以针对依赖的组件进行标签化格式如 #tag : {... }。 +​可以定义可选组件,以?开头。 + +```json +{ + "dependencies": { + "@scope/keeplatest": "^3.0.0", + "@scope/bundle_with_envs": { + "version": "^3.0.0", + "target": "arm", + "xxx": [ + "yyy", + "zzz" + ] + }, + "@scope/fixversion": "2.0.0", + "#tools": { + "@scope/tool_a": "1.0.0", + "@scope/tool_b": "1.0.0" + }, + "#options": { + "?@scope/opt_bundle1": "1.0.0", + "?@scope/opt_bundle2": "2.0.0" + } + } +} +``` + +### excludes + +​实现发行版的可裁剪功能,针对发行版,在继承的基础发行版上裁剪掉可选的组件。 +​如下图:基础发行版(base_dist)定义了两个可选组件(?开头的)。 + +```json +{ + "name":"base_dist", + "dependencies": [ + "?opt_bundle1", + "?opt_bundle2", + "normal_bundle" + ] +} +``` + +在新的发行版上裁剪掉这两个可选组件,加入一个新的组件(new_bundle)。 + +```json +{ + "name":"new_dist", + "base":"base_dist", + "excludes": ["opt_bundle1","opt_bundle2"], + "dependencies": { + "new_bundle": "1.0.0" + } +} +``` + +### envs + +​组件编译的环境变量,在dist 和build中可以使用到整个依赖树上的环境变量。 +​假如bundleA变量。 + +```json +{ + "envs": { + "os": "harmonyos", + "sysroot": "./dir", + "dumpmachine": "" + } +} +``` + +​可以在执行命令时,在引用该变量$os ,下面的"hpm run echo"命令会输出"hello harmonyos"。 + +```json +{ + "scripts": { + "echo": "echo hello $os" + } +} +``` + +### ohos + +​描述支持的HarmohyOS相关的信息:如OS版本,内核,以及支持的开发板。 + +```json +{ + "ohos": { + "os": "1.0.0", + "board": "hi3516,hi3861", + "kernel": "liteos-a" + } +} +``` + +### base + +​针对发行版,即publishAs为distribution:描述该发行版所继承的发行版和版本,格式如下: + +```json +{ + "base": { + "name": "@ohos/wifi_iot_hi3861", + "version": "1.0.0" + } +} +``` + +### segment + +针对code-segment类型组件必须,定义组件源码的还原路径。 +当整个项目工程中下载此组件,会将此组件的源码拷贝至相对于项目根路径的`destpath`路径下。 + +```json +{ + "segment": { + "destpath": "domain/system" + } +} +``` + +### copyRight(可选) + +声明组件的版权人信息 + +```json +{ + "copyRight": "Copyright (c) 20019-2022 hos(my@emaill.com)" +} +``` \ No newline at end of file diff --git "a/CLI \346\217\222\344\273\266\345\274\200\345\217\221/4.GUI.md" "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/4.GUI.md" new file mode 100644 index 0000000..6e985bd --- /dev/null +++ "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/4.GUI.md" @@ -0,0 +1,82 @@ + + +# GUI 图形化界面 + +为了适配开发者差异化使用习惯以及简化操作等,HPM CLI支持可视化操作界面,方便快捷。CLI图形化界面提供组件包管理、依赖管理、任务执行、设置等功能模块,介绍如下: + +## 如何启动 + +* 在本地创建hpm-project目录。 +* cd 到hpm-project目录下。 +* 执行hpm init命令初始化项目。 +* 执行hpm ui命令启动图形化页面,管理项目。 + +```shell +mkdir hpm-project +cd hpm-project +hpm init +hpm ui +``` + +**注:如果本地已有HPM的工程,可直接在工程的bundle.json文件所在目录下执行*hpm ui*命令。** + + +## 组件包管理 + +- 查询组件包信息 +- 编辑组件包信息 +- 查询依赖组件清单,以及自述文档(Readme文件) + +preject + +## 依赖管理 + +- 查询组件包依赖组件详情(包括版本更新情况) +- 追溯到组件的版本及代码库 +- 删除依赖组件 +- 更新组件版本 +- 查询依赖关系图 + +deps + + +## 任务执行 + +- 自定义任务及命令 +- 编辑任务命令并下发 +- 实时反馈任务命令输出结果 + +task + +## 设置 + +在此页面可以完成以下操作: + +- 设置HPM的配置项包括 + - Registry:注册中心地址 + + - Shellpath:hpm执行命令的默认终端(可以配置为cmd.exe 或git bash等) + + - LoginUser:登录用户的(邀请码),需要从HPM网站的个人中心查看,在发布组件的时候需要用到(结合秘钥一起使用) + + - GlobalRepo:全局安全的组件存放路径(即hpm install -g xxx) + + - HttpProxy:http请求使用的代理服务器地址 + + - HttpsProxy:http请求使用的代理服务器地址 + + - NoProxy:无需代理的网络请求地址清单(支持逗号分隔) + +- 用户添加的配置项(环境变量) + - 包括安装工具组件包生成的变量 + +config + +- HPM插件管理 + - 管理已安装的插件(卸载、激活、更新) + - 在插件市场安装插件 + +plugin + +market + diff --git "a/CLI \346\217\222\344\273\266\345\274\200\345\217\221/5.\346\217\222\344\273\266\345\274\200\345\217\221.md" "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/5.\346\217\222\344\273\266\345\274\200\345\217\221.md" new file mode 100644 index 0000000..a7d17c3 --- /dev/null +++ "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/5.\346\217\222\344\273\266\345\274\200\345\217\221.md" @@ -0,0 +1,290 @@ + +# 插件开发 + +建议使用hpm-cli版本1.5.0及以上。 + +## plugin插件 + +### 1. 初始化pluin插件项目 + +* 在本地创建plugin-demo目录。 +* cd 到plugin-demo目录下。 +* 执行hpm init命令生成plugin插件模板文件。 + +```shell +mkdir plugin-demo +cd plugin-demo +hpm init -t plugin +``` + +init plugin + +### 2. 本地安装plugin插件 + +* 在plugin-demo目录下执行本地安装命令。 + +```shell +hpm i . -g +``` + +install plugin + +### 3. 查看扩展的命令并执行 + +```shell +hpm -h +hpm hello +``` + +debug plugin + +### 4. plugin模板文件介绍 + +``` +plugin-demo +├─bundle.json // HPM包描述文件 +├─index.js // HPMCLI包入口文件 +├─LICENSE // LICENSE +├─README.md // README.md +``` + +#### bundle.json文件必填字段介绍 + +```json +{ + "name": "@ohos/hpm_cli_plugin_hello", // 插件名称,注意插件命名规范 + "version": "0.0.1", // 版本号,遵循semver规范 + "license": "MIT", // 协议 + "description": "echo hello world by hpm-cli.", // 描述信息 + "publishAs": "plugin", // 发布类型必须为plugin + "plugin": { + "entry": "index.js" // HPMCLI包入口文件 + }, + "dirs": { + ".": [ + "index.js" // hpm pack打包时的文件目录 + ] + } +} +``` + +#### index.js + +入口文件导出一个函数,该函数接收[hpmApi](https://hpm-beta.cbg.huawei.com/#/cn/help/hpmapi),如下: + +```javascript +const bundleJson = require('./bundle.json'); +// 以插件名称作为i18n词条的命名空间 +const pluginName = bundleJson.name +// 注册i18n词条 +function registI18nResource(hpmApi) { + const en = { + description: "echo hello world in the terminal.", + hello: "hello world." + }; + const zh = { + description: "在命令行中输出hello world。", + hello: "你好,世界。" + } + hpmApi.i18n.addLocalization("en", en, { pluginName }); + hpmApi.i18n.addLocalization("zh", zh, { pluginName }); +} + +module.exports = (hpmApi) => { + // 先注入i18n词条 + registI18nResource(hpmApi); + // 注册命令 + hpmApi.registerCmd( + 'hello', + { + description: hpmApi.i18n.getMessage(`${pluginName}.description`), + }, + (...args) => { + hpmApi.i18n.log(`${pluginName}.hello`); + }, + false + ) +} +``` + +## addon插件 + +### 1. 初始化addon插件项目 + +```shell +mkdir addon-demo +cd addon-demo +hpm init -t addon +``` + +### 2. 本地安装addon插件 + +* 在addon-demo目录下执行本地安装命令。 + +```shell +hpm i . -g +``` + +### 3. 执行hpm ui命令查看扩展的web页面 + +```shell +hpm ui +``` + +debug plugin + +### 4. addon模板文件介绍 + +``` +addon-demo +├─bundle.json // * HPM包描述文件 +├─server.js // HPMCLIUI服务端入口文件 +├─LICENSE // * LICENSE +├─README.md // * README.md +├─ui // * UI静态资源存放目录 +| ├─index.html // * 入口文件 +| ├─js // 逻辑js +| | └index.js +| ├─img // * 图片(被img标签解析,支持的类型以img标签为准) +| | └plugin.svg +| ├─css // 样式 +| | └index.css +| ├─register.js // ClientAddonApi调用文件,功能参考ClientAddonApi文档, 注册一些UI功能,只会在初始化调用一次(运行在插件的宿主环境中) +| | +``` + +#### bundle.json文件必填字段介绍 + +```json +{ + "name": "@ohos/hpm_cli_addon_hello", // 注意插件命名规范 + "version": "0.0.1", // 版本 + "publishAs": "plugin", // 发布类型 + "dirs":{ + ".":["ui", "entry.js"] // 根目录包含的文件/文件夹 + }, + "plugin": { + "ui": { // 插件UI配置 + "source": "ui", // ui静态资源存放目录 + "router": "server.js", // addon插件的HPM_CLI_UI服务端入口文件 + "extensionPoint": "side.menu.main", // UI扩展点 + "callAddonApi": "register.js", // 调用ClientAddonApi的文件 + "config": { // UI 配置, 和扩展点对应, 详细配置查阅扩展点配置 + "entry": "index.html", // UI 入口文件 (默认index.html) + "icon": "img/plugin.png", // 图标 + "label": "hello" // 菜单tip内文本(需要在调用ClientAddonApi注册国际化) + } + } + } +} +``` + +#### server.js + +注册`express`路由到HPM_CLI_UI服务端。 +入口文件导出一个函数,该函数接收[serverApi](https://hpm-beta.cbg.huawei.com/#/cn/help/hpmapi),如下: + +```javascript +const bundleJson = require('./bundle.json') +module.exports = (serverApi) => { + const routes = { + method: 'get', + path: '/hello', + async callback(req, res, next) { + try { + const result = { + code: 200, + status: 'success', + message: 'hello, world!' + }; + res.send(result); + } catch (err) { + next(err); + } + } + } + const routePath = '/hi' + const routeId = bundleJson.name + serverApi.registerRouter({ routes, routePath, routeId }) +} +``` + +#### register.js + +注册i18n词条,`clientAddonApi`请查阅[API参考](https://hpm-beta.cbg.huawei.com/#/cn/help/hpmapi)。 + +```javascript +(function(){ + const { + ClientAddonApi, + addonEvent, + } = window.top.HPM_CLI_UI + const registI18nResource = (name) => { + const clientAddonApi = new ClientAddonApi(); + const zh_CN = { + hello: '你好,世界。' + } + const en = { + hello: 'hello,world.' + } + clientAddonApi.addLocalization('zh_CN', zh_CN, { pluginName: name }); + clientAddonApi.addLocalization('en', en, { pluginName: name }); + } + addonEvent.subscribe('registered', name => { + registI18nResource(name) + }) +})() +``` + +### 4. UI各扩展点配置 + +* __side.menu.main__ + +描述:左侧菜单,可由多个插件扩展多个菜单: + +```json +{ + "config": { + "entry": "index.html", // UI 入口文件 (默认index.html) + "icon": "img/darkIcon.png", // 图标 + "label": "repo" // 菜单tip内文本(需要在调用ClientAddonApi注册国际化) + } +} +``` + +* __task.toolbar.right.btns__ + +描述:任务工具栏右侧按钮组,只能在输出按钮右侧扩展一个按钮,可支持多个插件扩展不同命令: + +```json +{ + "config": { + "clean": { // 与任务名对应, UI目录下必须包含该目录 + "entry": "index.html", // 该任务下的入口文件(默认index.html) + "lightIcon": "img/lightReport.svg", // 该任务扩展按钮的白色主题按钮图标 + "darkIcon": "img/darkReport.svg", // 该任务扩展按钮的黑色主题按钮图标 + "label": "result.label" // 该任务扩展按钮的文本(图标文本必须至少配置一个) + }, + "notice": { // 同上 + "entry": "index.html", + "lightIcon": "img/lightReport.svg", + "darkIcon": "img/darkReport.svg", + "label": "result.label" + } + } +} +``` + +- 使用前端框架开发可将编译后的`js、css、html`文件作为`addon`插件的入口文件。 + +## 调试 + +- `plugin`插件的调试 + - 在插件工程下通过`hpm i . -g`命令将开发的插件安装到hpmcli的全局目录下,可通过`hpm -h`查看注入的命令并执行此命令。 + - 每次修改插件源码后都需要重新执行`hpm i . -g`命令。 +- `addon`插件的调试 + - 在插件工程下执行`hpm i . -g`命令,安装完成后执行`hpm ui`命令,可在HPMCLIUI页面上查看。 + - 每次修改插件源码后都需要重新执行`hpm i . -g`命令,以及断开`hpm ui`命令的进程,重新执行`hpm ui`命令拉起服务。 +- Tips: + - 服务端路由注册请参考[express框架](https://github.com/expressjs/express)。 + - 命令参数、选项请参考[commander框架](https://github.com/tj/commander.js)。 diff --git "a/CLI \346\217\222\344\273\266\345\274\200\345\217\221/6.API\345\217\202\350\200\203.md" "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/6.API\345\217\202\350\200\203.md" new file mode 100644 index 0000000..dc5c549 --- /dev/null +++ "b/CLI \346\217\222\344\273\266\345\274\200\345\217\221/6.API\345\217\202\350\200\203.md" @@ -0,0 +1,391 @@ +# hpmApi 参考 +**hpmApi是hpmcli提供给`cli`插件开发的api,提供注册命令到hpmcli、以及设置hpm配置项等功能。** + +#### hpmApi.registerCmd(name, options, action, isUiTask): 在插件中注册命令到hpmcli中 +* name 定义注册命令的名称,安装后可通过hpm {name}执行插件注入的命令。 +* options 定义命令的选项。 +* action 定义命令的回调函数。 +* isUiTask 是否显示在GUI视图上。 + +```typescript +interface CommandOptions { + readonly [key: string]: string +} +interface Options { + readonly description: string + readonly args?: string + options: CommandOptions +} +type fn = (...args: any[]) => void | Promise +``` + +```javascript +//entry.js +module.exports = (hpmApi) => { + hpmApi.registerCmd( + 'hello', + { + description: 'console.log hello world in the terminal.' + }, + (...args) => { + console.log('hello world.'); + }, + false + ) +} +``` + +#### hpmApi.i18n: i18n词条相关的api + +##### hpmApi.i18n.addLocalization(lang,resource,meta): 注册插件的i18n词条 +* lang 定义词条的语言环境。 +* resource 定义插件注册的语言资源。 +* meta 定义插件词条的命名空间。 + +```typescript +type Lang = "en" | "zh" +interface Resource { + readonly [key: string]: string +} +interface Meta { + readonly pluginName: string +} +``` +```javascript +//entry.js +const pluginName = 'hello' +function registI18nResource(hpmApi) { + const en = { + hello: "hello world." + }; + const zh = { + hello: "你好,世界。" + } + hpmApi.i18n.addLocalization("en", en, { pluginName }); + hpmApi.i18n.addLocalization("zh", zh, { pluginName }); +} +module.exports = (hpmApi) => { + registI18nResource(hpmApi); +} +``` + +##### hpmApi.i18n.log(log, params, logOption): 基于hpmcli的语言环境进行日志输出 +* key +* params +* logOption + +```typescript +// silent: true 在日志文件中输出信息,不会打印打命令行界面上。 +interface LogOption { + readonly silent: boolean +} +interface LogParams { + readonly [key: string]: string +} +``` +```javascript +//entry.js +module.exports = (hpmApi) => { + hpmApi.i18n.log(`${pluginName}.hello`); //根据hpmcli当前语言环境(hpm lang)在终端中输出相应词条的内容。 +} +``` + +##### hpmApi.i18n.getMessage(key, params) +* key 词条key +* params +* Returns: 返回key、params对应的词条内容 + +```javascript +//entry.js +module.exports = (hpmApi) => { + const message = hpmApi.i18n.getMessage(`${pluginName}.hello`); +} +``` + +```javascript +//entry.js +const pluginName = 'hello' +function registI18nResource(hpmApi) { + const en = { + description: "console.log hello world in the terminal.", + hello: "hello world." + }; + const zh = { + description: "在命令行中输出hello world。", + hello: "你好,世界。" + } + + hpmApi.i18n.addLocalization("en", en, { pluginName }); + hpmApi.i18n.addLocalization("zh", zh, { pluginName }); +} + +module.exports = (hpmApi) => { + // 先注入i18n词条 + registI18nResource(hpmApi); + hpmApi.registerCmd( + 'hello', + { + description: hpmApi.i18n.getMessage(`${pluginName}.description`), + }, + (...args) => { + i18n.log(`${pluginName}.hello`); + }, + false + ) +} +``` + +#### hpmApi.getVersion(): 获取当前hpmcli的版本号 +* Returns: + +```javascript +//entry.js +module.exports = (hpmApi) => { + const version = hpmApi.getVersion() + console.log(version) //当前hpmcli的版本号, 例如1.4.0 +} +``` + +#### hpmApi.getConfig(): 获取.hpmrc文件下的配置项 +* Returns: + +```typescript +interface Config { + [key: string]: string | boolean | number +} +``` + +#### hpmApi.setConfig(config): 添加、修改hpm配置项 +* config: + +#### hpmApi.deleteConfig(configKeys): 删除配置项 +* configKeys: + +以下为当前.hpmrc文件的内容 +```properties +registry = https://repo.harmonyos.com +shellPath = C:\WINDOWS\System32\cmd.exe +globalRepo = C:\Users\username\.hpm\global +strictSsl = false +OSPlatform = win32 +restoreCodeSegment = true +``` + +```javascript +//entry.js +module.exports = (hpmApi) => { + const hpmConfig = hpmApi.getConfig() + console.log(hpmConfig) + /* currentConfig + { + registry: "https://repo.harmonyos.com", + shellPath: "C:\\WINDOWS\\System32\\cmd.exe", + globalRepo: "C:\\Users\\username\\.hpm\\global", + strictSsl: false, + OSPlatform: "win32", + restoreCodeSegment: false + } + */ + const newConfig = { + loginUser: "xxxx", + shellPath: "D:\\GIT\\bin\\bash.exe", + no_proxy: "*.server.com" + } + hpmApi.setConfig(newConfig) + /* currentConfig + { + registry: "https://repo.harmonyos.com", + shellPath: "D:\\GIT\\bin\\bash.exe", + globalRepo: "C:\\Users\\username\\.hpm\\global", + strictSsl: false, + OSPlatform: "win32", + restoreCodeSegment: false, + loginUser: "xxxx", + no_proxy: "*.server.com" + } + */ + const deleteConfigKeys = ['restoreCodeSegment', 'no_proxy'] + hpmApi.deleteConfig(deleteConfigKeys) + /* currentConfig + { + registry: "https://repo.harmonyos.com", + shellPath: "D:\\GIT\\bin\\bash.exe", + globalRepo: "C:\\Users\\username\\.hpm\\global", + strictSsl: false, + OSPlatform: "win32", + loginUser: "xxxx" + } + */ +} +``` + +#### hpmApi.eventTypes: 获取hpmcli支持的命令钩子,详细信息见下文`EventTypes`枚举类型 +* Returns: + +#### hpmApi.on(type, action): 订阅hpmcli的命令hook事件 +* type: +* action: + +```typescript +enum EventTypes { + //安装 + beforeEachInstall = "beforeEachInstall", + afterEachInstall = "afterEachInstall", + beforeAllInstall = "beforeAllInstall", + afterAllInstall = "afterAllInstall", + //编译 + beforeEachBuild = "beforeEachBuild", + afterEachBuild = "afterEachBuild", + beforeAllBuild = "beforeAllBuild", + afterAllBuild = "afterAllBuild", + //发行版 + beforeDist = "beforeDist", + afterDist = "afterDist", + //打包 + beforePack = "beforePack", + afterPack = "afterPack", + //发布 + beforePublish = "beforePublish", + afterPublish = "afterPublish", + //卸载 + beforeUninstall = "beforeUninstall", + afterUninstall = "afterUninstall", +} +type CallBack = () => void +``` +在插件中订阅hpmcli标准命令执行的hooks,例子如下: +```javascript +//entry.js +module.exports = (hpmApi) => { + hpmApi.on(hpmApi.eventTypes.afterDist, () => { + console.log('echo after distribute hook event') + }) + hpmApi.on(hpmApi.eventTypes.afterAllInstall, () => { + console.log('echo after all bundle installed hook event') + }) +} +``` + +# Server Api 参考 +**serverApi为hpmcli_ui提供给`ui`插件的服务端api,提供注册express路由的功能。** + +#### serverApi.registerRouter(router): 注册路由到hpmcliui服务端 +* router: 参考下方Router接口定义 + +```typescript +interface Router { + readonly routePath: string //服务端路由的路径 + readonly routeId: string //服务端路由的唯一id + readonly routes: Routes // 路由实例数组,具体Route定义参考express路由 +} +type Routes = Route[] | Route +type Method = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head' +type RouteCallback = (req: any, res: any, next: Next) => void | Promise +type Next = (...args: any[]) => void +// 具体route定义参考express路由 +interface Route { + readonly method: Method + readonly path: string + readonly callback: RouteCallback +} +``` +* 基于以下例子安装插件,hpm ui -p 3000 -d启动服务后,可通过请求http://localhost:3000/api/hi/hello 访问注册到服务端的接口。 +```javascript +//server.js +module.exports = (serverApi) => { + const routes = { + method: 'get', + path: '/hello', + async callback(req, res, next) { + try { + const result = { + code: 200, + status: 'success', + message: 'hello, world!' + }; + res.send(result); + } catch (err) { + next(err); + } + } + } + const routePath = '/hi' + const routeId = 'hi' + serverApi.registerRouter({ routes, routePath, routeId }) +} +``` + +# HPM_CLI_UI 参考 + +#### `HPM_CLI_UI` 是核心UI创建的全局对象, 所有插件通过`window.top`即可访问, 对象结构如下: + +``` +window.HPM_CLI_UI = { + addonEvent, // 事件总线, 用于核心UI和插件通信 + Vue, // 核心UI的Vue类, 插件可使用此类快速开发vue应用 + Event, // addonEvent的类, 可创建一个新的事件对象 + http, // 核心UI封装的axios实例, 可使用此对象发起http请求, 并共用核心UI的请求响应拦截器 + i18n, // i18n对象, 用于国际化显示, 具体请查阅vue-i18n文档 + isDarkMode, // 当前主题是否为夜间模式 (会响应主题切换) + wsConnectSuccess, // webSocket的连接状态 (会响应网络断开) + ClientAddonApi, // ClientAddonApi类, 具体请查阅ClientAddonApi章节 +}; +``` + +#### addonEvent + +addonEvent 向addon提供的事件: + - `addonLoaded`: ui插件的iframe的onload事件 + - `beforeAddonDestroy`: ui插件的销毁事件,(插件销毁后插件内部的所有addonEvent的订阅都会被移除,除了持久订阅的事件) + - `themeChange(isDarkMode: boolean)`: 主题切换事件 + - `localeChange(locale: string)`: 语言切换事件 + - `onTaskRun(task: object)`: 当前任务点击运行的事件 + - `onTaskStop(task: object)`: 当前任务点击停止的事件 + - `registered(name: string)`: 生成script标签加载callAddonApi文件 + +#### clientAddonApi + +| 函数名 | 说明 | +| ------------------ | ------------------------------------------------------------ | +| getSupportLanguage | 获取当前系统支持的语言 | +| addLocalization | 注册国际化, 注册的词条核心UI自动划分pluginName命名空间,可通过i18n.t('pluginName.a.b.c')访问, 参数中的lang为当前语言key, message为词条对象, meta中必须包含pluginName | + +__注:__ 只能在核心UI支持的语言内扩展 +```typescript +// ClientAddonApi类实现ClientAddon接口 +interface ClientAddon { + getSupportLanguage: () => SupportLanguage[] + addLocalization: (lang: Language, message: Message, meta: Meta) => void +} +type Language = 'en' | 'zh_CN' +interface SupportLanguage { + readonly key: Language + readonly label: string +} +interface Meta { + readonly pluginName: string +} +interface Message { + readonly [key: string]: string +} +``` +```javascript +// register.js 注册插件的i18词条,此js文件会被hpmcliui以script标签加载,建议以自执行函数运行,防止遍历污染全局。 +(function () { + const { + ClientAddonApi, + addonEvent, + } = window.top.HPM_CLI_UI + const name = 'hi' + const registI18nResource = (name) => { + const clientAddonApi = new ClientAddonApi(); + const zh_CN = { hi: '你好,世界!' } + const en = { hi: 'hello,world!' } + clientAddonApi.addLocalization('zh_CN', zh_CN, { pluginName: name }); + clientAddonApi.addLocalization('en', en, { pluginName: name }); + } + addonEvent.subscribe('registered', name => { + registI18nResource(name) + }) +})() +``` -- Gitee From 5d75f8183b822ab5893c8ec25880dbdc3db91673 Mon Sep 17 00:00:00 2001 From: Sang_Sang33 Date: Wed, 6 Jul 2022 11:53:07 +0800 Subject: [PATCH 2/2] add: ci md Signed-off-by: Sang_Sang33 --- ...15\344\275\234\346\214\207\345\215\227.md" | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 "CI\351\227\250\346\210\267\345\274\200\345\217\221\346\235\277\344\277\241\346\201\257\345\241\253\345\206\231\346\223\215\344\275\234\346\214\207\345\215\227.md" diff --git "a/CI\351\227\250\346\210\267\345\274\200\345\217\221\346\235\277\344\277\241\346\201\257\345\241\253\345\206\231\346\223\215\344\275\234\346\214\207\345\215\227.md" "b/CI\351\227\250\346\210\267\345\274\200\345\217\221\346\235\277\344\277\241\346\201\257\345\241\253\345\206\231\346\223\215\344\275\234\346\214\207\345\215\227.md" new file mode 100644 index 0000000..0ee3e34 --- /dev/null +++ "b/CI\351\227\250\346\210\267\345\274\200\345\217\221\346\235\277\344\277\241\346\201\257\345\241\253\345\206\231\346\223\215\344\275\234\346\214\207\345\215\227.md" @@ -0,0 +1,68 @@ +# CI门户开发板信息填写操作指南 +#### 1. 新增开发板 +- 进入我的开发板界面,点击创建开发板按钮进入新增开发板编辑界面 +> 管理中心 > 我的开发板 > 创建开发板 + +![image](http://image.huawei.com/tiny-lts/v1/images/7679e14dc4d884f636c9f50b634098eb_2548x1263.png) + +- 填写卡片信息 + +![image](http://image.huawei.com/tiny-lts/v1/images/de0fd128b10f65915b77b9b816546bc7_1005x1236.png) + +##### 配置项说明 + + - 开发板企业级LOGO:必填,只允许上传一张照片 + - 开发板图片:必填,只允许上传一张照片 + - 芯片系统LOGO:必填,只允许上传一张照片 + - 开发板名称:开发板名称不能为空 + - 开发板规格:输入至少1条规格信息 + - 场景分类:单选,根据开发板案例功能进行分类,例如:智能家居、媒体娱乐、移动办公... + - OS分类:单选,根据开发板案例复杂度分为轻量系统,小型系统,标准系统 + - OS support:多选,根据开发板支持的系统版本进行选择,如:1.0.1 LTS、1.1.0 LTS... + - Communication:多选,通过开发板通信协议选择 + - 工具:单选,选择开发工具,如:HUAWEI DevEco Studio、HUAWEI DevEco Device Tool + +------------ + +#### 2.开发板详情编辑 + +![image](http://image.huawei.com/tiny-lts/v1/images/c477506ebd3f31f7d646dfe335e78c46_1576x5659.png) + +##### 配置项说明 + - 开发板名称与开发板图片为上一步填写卡片信息时获取的信息 + - 描述信息:添加不超过200字的开发板描述信息 + - 概述:必填,开发板概述信息 + - 功能特性:添加至少1条特性,介绍各个相关组件的功能,可以进行添加或删除 + - 原理图:添加至少1张关于开发板的原理图,可以进行添加或删除 + - 正面视图:必填,开发板的正面视角图 + - 反面视图:补充展示存在于开发板背面的元器件或其他固件 + - 管脚介绍:进一步对原理图相关引脚进行介绍 + - 接口介绍:添加开发板的相关接入介绍 + - 参考资料(技术参考、已知限制):开发板技术资料补充/提供、开发板所存在的使用限制说明 + - 开源发行版:必填,否/是(选择开发板的发行版名称,开发板详情页将提供发行版各历史版本的下载) + - 开发板样例:选择或输入搜索添加开发板的样例,开发板详情页将展示样例卡片(样例描述信息,点击跳转样例详情)。 + +- 开源发行版、开发板样例信息详情页展示 + +![image](http://image.huawei.com/tiny-lts/v1/images/c966c652be04f9b3d5591bcb55f21062_2094x1082.png) + +------------ + +##### 开源发行版名称查找 + +进入[HPM官网](https://repo.harmonyos.com/#/cn/solution),通过左侧的过滤器的OS版本、内核、开发板字段查找开发板的开源发行版名称 + +![image](http://image.huawei.com/tiny-lts/v1/images/906ab5feb5a5c9f0aa8a8b423f25a0b6_1734x1022.png) + +------------ + +#### 3.开发板适配指导 + +![image](http://image.huawei.com/tiny-lts/v1/images/365c659e4f0410fd75b8a0ead351c7ad_1597x2143.png) + +##### 配置项说明 + - 硬件准备:添加需要准备的硬件工具以及数量,通过+号可以添加多条数据 + - 开发环境准备:代码拉取、编译、烧录等所需软件环境描述,如:Linux编译服务器、Windows工作台、开发工具、驱动等 + - 编译调试:基础编译环境的搭建安装描述,如:环境变量配置,python安装等 + - 烧录:开发板镜像程序烧录指导 + -- Gitee