## 发布到 pypi

### 打包

```shell
python3 -m pip install --upgrade build
python3 -m build
```

### 测试平台

上传

```shell
python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
```

安装

注：extra-index-url 会从 pypi 安装依赖库，以避免 [此问题](https://gitee.com/MulanRevive/mulan-rework/issues/I9CC0N)。
```shell
python3 -m pip install -U --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple ulang
```

### 正式发布平台

上传

```shell
python3 -m twine upload --repository pypi dist/*
```

安装

```shell
python3 -m pip install --index-url https://pypi.org/simple/ ulang
```

### 更新已有安装

install 添加选项 -U

注：上传到平台后，也许有三分钟延迟才能通过 pip install 安装新版本

安装特定版本的包：
pip install <包名>==<版本号>

## 常用调试方法

`中.py`中的`ast.dump`和`格式化节点`可查看语法树细节，与原 exe 或者逆向生成的作比较基本可确定问题所在。

语法分析器中的`调试`常量置为 True 可查看各个语法对应处理方法的调用顺序

### VS Code 调试

调试开始后进入交互，可触发断点。尚不知如何在调试时加入参数，如带源文件路径。

### 语法树实现缘由

如果遇到不明为何生成该语法树的情况，可以借用木兰转 python 代码，查看对应 python
代码。参考[此 commit](https://gitee.com/MulanRevive/mulan-rework/commit/3a6d807c67adab4745f63e3b81d0858631c04c68)。

比如字符串插值为何使用 ast.Mod，可用木兰代码：

```javascript
a = 3
print("`a`b`a`")
```

运行转换为 python 代码，可见 % 运算符：

```terminal
$ python3 -m ulang --dump-py test/str.ul
import sys
from math import *
ARGV = sys.argv[1:]
a = 3
print('%sb%s' % (str(a), str(a)))
```

## 常见错误

```plaintext
  File "/Users/xuanwu/work/木兰/prototype/分析器.py", line 120, in 语法分析器
    @分析器母机.production('操作符: 名词_操作符 二元操作符 操作数 块')
  File "/opt/miniconda3/lib/python3.7/site-packages/rply/parsergenerator.py", line 77, in production
    raise ParserGeneratorError("Expecting :")
rply.errors.ParserGeneratorError: Expecting :
```

语法规则中, ":"必须前后带空格

`运算符 == ast.And()`导致:
TypeError: expected some sort of operator, but got <_ast.And object at 0x105a06518>
改为比较类型: `isinstance(运算符, ast.Add)`

## [rply](https://github.com/alex/rply) 学习笔记

运行测试用例：

```terminal
$ pytest tests
================================================================= test session starts ==================================================================
platform darwin -- Python 3.7.6, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: .../rply
plugins: hypothesis-5.5.4, arraydiff-0.3, remotedata-0.3.2, openfiles-0.4.0, doctestplus-0.5.0, astropy-header-0.1.2
collected 49 items                                                                                                                                     

tests/test_both.py .                                                                                                                             [  2%]
tests/test_lexer.py ..........                                                                                                                   [ 22%]
tests/test_parser.py ..........                                                                                                                  [ 42%]
tests/test_parsergenerator.py ........                                                                                                           [ 59%]
tests/test_tokens.py .....                                                                                                                       [ 69%]
tests/test_utils.py .....                                                                                                                        [ 79%]
tests/test_warnings.py ....                                                                                                                      [ 87%]
tests/test_ztranslation.py ssssss                                                                                                                [100%]

============================================================ 43 passed, 6 skipped in 0.23s =============================================================
```

参考[rply 的 CI 过程](https://travis-ci.org/github/alex/rply/jobs/728603786)，运行 rpython 相关测试。

已在本地[运行测试](https://github.com/alex/rply/pull/104)，运行`.travis/run.sh`。

rpython 支持中文规则名, 如`lg.add("所有", r".*", re.DOTALL)`, 只需文件首加`# -*- coding: utf-8 -*-`

为解决报错行号问题，需从 rply 源码安装：`$python3 setup.py install`

### IDE 相关

VSC 下避免回车自动插入 tab，关掉“detect identation”

vsc 下默认不自动保存. 只有圆点提示文件未保存, 很不显眼.

VSC 下终端使用的 python 无法转为与系统终端相同的 conda 环境。PyCharm 下可以。

### git 常用

同步远程分支：git fetch -p
列出本地分支：git branch -a
删除本地分支：git branch -d xxx
可以放心删除，如果有未与主分支合并的内容，会警告提示使用 -D

fork 分支与原库同步：

```shell
git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git

git fetch upstream
git checkout master
git merge upstream/master
```

同时push到gitee和github两个库：

```shell
git remote set-url --add --push origin https://gitee.com/MulanRevive/mulan-rework.git
git remote set-url --add --push origin https://github.com/MulanRevive/mulan-rework.git
```

### conda 常用

conda activate 【某环境】
conda deactivate
conda env list

## eve 相关设置

https://docs.python-eve.org/en/stable/quickstart.html 到数据库配置 settings.py 之前已复现.

### 安装 MongoDB

https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/

$ brew services start mongodb-community@4.4
==> Tapping homebrew/services
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-services'...
remote: Enumerating objects: 46, done.
remote: Counting objects: 100% (46/46), done.
remote: Compressing objects: 100% (46/46), done.
remote: Total 958 (delta 22), reused 9 (delta 0), pack-reused 912
Receiving objects: 100% (958/958), 270.77 KiB | 693.00 KiB/s, done.
Resolving deltas: 100% (396/396), done.
Tapped 1 command (38 files, 348.9KB).
==> Successfully started `mongodb-community` (label: homebrew.mxcl.mongodb-community)

$ brew services stop mongodb-community@4.4
Stopping `mongodb-community`... (might take a while)
==> Successfully stopped `mongodb-community` (label: homebrew.mxcl.mongodb-community)

### 代码统计

```shell
scc --by-file --count-as ul:ruby
```

### RST 文件验证

```shell
python -m readme_renderer README.rst -o /tmp/README.html
```
