Skip to content
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

feat: rewrite the backend to use the build hook #19

Merged
merged 9 commits into from
Feb 4, 2024
Merged

feat: rewrite the backend to use the build hook #19

merged 9 commits into from
Feb 4, 2024

Conversation

frostming
Copy link
Contributor

@frostming frostming commented Feb 2, 2024

这个 PR 的改动范围可能比较大,我会把改动点一一列出。这也是我最近有用 Mina 的需求,如果你觉得不符合你的用法不想 merge,我只能 fork 一个新的项目。

Change list

  • 使用 pdm-backend 的 Hook 功能实现 backend,这样 Mina-backend 不暴露任何 backend 界面,用户只需要在 build-system.requires 中加入 mina-build 并依旧使用 pdm-backend 即可。
  • 同时本项目的构建实现自举,构建时使用当前工作目录中的 hooks.py ,避免了需要先发版本项目才能用。
  • 🚨 config settings 的key 改成了 mina-target 因为 -- 看起来并没有必要
  • 🚨 pyproject默认构建目标配置字段改成了 default-target
  • 🚨 不再暴露 mina.backend,原有项目的 build-backend 设置需要更新。
  • 🚨 去掉了 raw-dependencies 项配置,因为已有 override 设定控制是追加还是覆盖,另一方面依赖包括默认依赖和可选依赖,配置会很复杂,单一个 raw-dependencies 不能满足需要。即使存在一些用例,仅希望追加依赖,而覆盖其他字段,考虑到这个用例还是比较少,而且可以重复base的依赖解决
  • 不再要求package依赖必须包含在项目依赖中,避免重复配置。
  • CLI 不再依赖 PDM,而是作为 PDM plugin,需要与PDM同时安装,已修改安装说明

有任何异议欢迎反馈

@GreyElaina
Copy link
Owner

不妨试试用 dependencies group 配置分包特有的依赖……我想先确认一下,不同的 dependencies group 可以提供相互冲突的依赖吗?

@frostming
Copy link
Contributor Author

不妨试试用 dependencies group 配置分包特有的依赖……我想先确认一下,不同的 dependencies group 可以提供相互冲突的依赖吗?

可是可以,但是不能一起lock

@GreyElaina
Copy link
Owner

README 我后面会重写一下。

不妨试试用 dependencies group 配置分包特有的依赖……我想先确认一下,不同的 dependencies group 可以提供相互冲突的依赖吗?

可是可以,但是不能一起lock

good, 这样在有些情况下就不需要 raw-dependencies 了: 我们可以直接用这个特性。
不过还有一个问题我想考虑一下:如果有一个 core 包为其他 mina package 所依赖,那如果不用 raw-dependencies 怎么处理会比较好。

“不再要求package依赖必须包含在项目依赖中,避免重复配置。”
这是表示 package 的依赖现在是隐式的叠加在 workspace 的 dependencies 上吗?

@frostming
Copy link
Contributor Author

如何安装子包的依赖需要另行考虑,但最好不要通过重复配置解决

“不再要求package依赖必须包含在项目依赖中,避免重复配置。”
这是表示 package 的依赖现在是隐式的叠加在 workspace 的 dependencies 上吗?

override = False情况下字段的值都是merge的,包含dependencies

@GreyElaina
Copy link
Owner

GreyElaina commented Feb 2, 2024

如何安装子包的依赖需要另行考虑,但最好不要通过重复配置解决

“不再要求package依赖必须包含在项目依赖中,避免重复配置。”
这是表示 package 的依赖现在是隐式的叠加在 workspace 的 dependencies 上吗?

override = False情况下字段的值都是merge的,包含dependencies

那不妨试试直接将分包的依赖系统挂靠在整个 dependencies group 系统上?虽然 pylance 可能会骂我怎么找不到包。
我这个猜想依赖于 project.dependencies 是某个 base or project or default 的 group。

Copy link
Owner

@GreyElaina GreyElaina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果可以,我还是希望能使用 dependencies group 来处理分包的依赖,除此之外还需要保留 raw deps 用来处理分包之间的依赖关系。
除此之外……uh,backend hooks L44-L47 那段逻辑看起来好怪

@RF-Tar-Railt
Copy link
Contributor

RF-Tar-Railt commented Feb 3, 2024

raw-dep现有用法包括

  • 声明某个子包需要依赖另外的子包
  • 在某个子包只能使用某个依赖的低版本时用raw声明额外的版本限制(例如某个子包只能用pyd-v1时,通过raw声明pydantic<2;但是类似这种情况会产生环境冲突的问题)

另外一点,子包的project.dependencies既可以只写依赖名称(跟随workspace的版本)也可以加上版本

@frostming
Copy link
Contributor Author

frostming commented Feb 3, 2024

raw-dep现有用法包括

其实总结一下,就是一个不被pdm resolver收集的依赖集合

我现在的改动以后,子包的依赖都不会被PDM收集到。然而又产生问题,如果我想收集呢?
所以现在讨论的是如何引入子包的依赖,重新设计这个,但肯定不是用之前的raw-dep的方式

现在的改动是把逻辑简化到简单的继承追加,或是覆盖,二者择其一。先从一个简单的模型出发,后面补充行为更容易。

optional groups是一种方法,但这里有个麻烦的问题

子包引用workspace的某个optional group,那么这个group还出现在workspace的optional group(并被其他子包所继承)吗?

Signed-off-by: Frost Ming <[email protected]>
@frostming
Copy link
Contributor Author

frostming commented Feb 3, 2024

如果可以,我还是希望能使用 dependencies group 来处理分包的依赖,除此之外还需要保留 raw deps 用来处理分包之间的依赖关系。

我倒觉得另一种方法比较好(先不说实现可能)

不弄乱optional dependencies,而是在workspace中显式依赖子包,因为现在子包不止一个,我们需要用一种方法让builder构建正确的子包,一个建议:

[tool.pdm.dev-dependencies]
workspace = [
    "-e file:///${PROJECT_ROOT}/#egg=foo",   # 使用 mina-target=foo构建
    "-e file:///${PROJECT_ROOT}/#egg=bar",   # 使用 mina-target=bar构建
]

这样没有改变对optional-dependencies 字段意义,只是在构建 ${PROJECT_ROOT} 依赖时加了一个mina-target参数,同时子包各自的依赖可以被builder收集到。

@GreyElaina
Copy link
Owner

GreyElaina commented Feb 3, 2024

子包引用workspace的某个optional group,那么这个group还出现在workspace的optional group(并被其他子包所继承)吗?

这点倒简单……直接接管这方面的逻辑,让 group 直接被独占,仅对 mina 相关逻辑可见,mina 则作为一个 workspace manager 协助性质的管理这些,例如 pdm mina focus pkg1 pkg2 ,或是在执行 pdm install 的时候生成 prompt 询问用户要初始化哪些环境这样,这也能顺便处理一下 pyright(mypy 啥的也能问一问先),往当前目录扔点啥垃圾,然后再集成一个 pre-commit 把这些见不得 commit 的要扫掉的赶紧扫掉。
当然,这种情况下 pdm.lock 会被搞得一团糟,我建议同时处理这方面的情况。

以及,在设计上,workspace 是不会被 publish 的,其只暴露给项目本身作为 editable package 使用。

@GreyElaina
Copy link
Owner

GreyElaina commented Feb 3, 2024

现在子包不止一个,我们需要用一种方法让builder构建正确的子包

错,这可能破坏 editable package 吧,如果我 avilla-console 依赖 avilla-core@v1 然后我本地开发 v2(反正 break 了),这样如果你对着整个 workspace install,哦豁,what a bad move,你把 pypi 上的 avilla-core@v1 拉下来了,这种情况我觉得不应该出现。

@GreyElaina
Copy link
Owner

GreyElaina commented Feb 3, 2024

对于子包的构建……嗯,这些子包的构建……确实,如果我子包声明一些 metadata,那要怎么处理,我想你应该说的是这个问题吧。
竟然如此,可以考虑一下弱约束 that package 的版本(install的时候导向editable),然后再用 mina 对 pdm install 的 prompt 进行 workspace setup,把子包装成 editiable package
什么?break 没修完?没修完你 build 什么。

@frostming
Copy link
Contributor Author

frostming commented Feb 3, 2024

以及,在设计上,workspace 是不会被 publish 的,其只暴露给项目本身作为 editable package 使用。

这个 PR 的思想就是减少规则,简化逻辑,既然workspace的配置是用来被继承的,它完全可以是可以publish的,那么workspace的metadata就应该一视同仁,没有额外的规则

错,这可能破坏 editable package 吧,如果我 avilla-console 依赖 avilla-core@v1 然后我本地开发 v2(反正 break 了),这样如果你对着整个 workspace install,哦豁,what a bad move,你把 pypi 上的 avilla-core@v1 拉下来了,这种情况我觉得不应该出现。

这是个问题,但我感觉这是实现的问题,PDM现在的逻辑是如果碰到同名的包已经被editable安装了,就不会安装pypi的包,所以感觉应该没问题。

而且,用optional group似乎也解决不了,甚至子包都不能被editable安装,因为子包在workspace的眼里他不是个包。

最后有没想过这东西这么难设计,是因为workspace他太复杂了,有各种互相依赖、元数据复用等问题。
不过没关系,我已经把这个实现直接拷贝使用了,这就是hooks的好处。

@GreyElaina
Copy link
Owner

GreyElaina commented Feb 3, 2024

这个 PR 的思想就是减少规则,简化逻辑,既然workspace的配置是用来被继承的,它完全可以是可以publish的,那么workspace的metadata就应该一视同仁,没有额外的规则

好消息,我现在不在乎这方面。那么便一视同仁……如果用到了有问题再修。

我已经在 #19 (comment) 提出了一个初步思路。

@GreyElaina
Copy link
Owner

GreyElaina commented Feb 3, 2024

最后有没想过这东西这么难设计,是因为workspace他太复杂了

当时的我:我就只想分割一下……什么,这些东西?我现在用不到不做

workspace 可以 publish……嗯,即使现在你也可以直接丢掉 mina 直接 build entire workspace,你自己把控好炸了我再看看怎么修,没用到的我先开摆

好消息,根本不用碰,mina 从原理层面只是替换 project describe,竟然如此没必要去管 workspace 怎样,连 optional dependencies 也不需要管。至于 cli,啊啊,如果用 optional dependencies + editable replace,只有后者是必须要修改 cli 行为……嗯

@frostming
Copy link
Contributor Author

frostming commented Feb 3, 2024

好消息,我现在不在乎这方面。那么便一视同仁……如果用到了有问题再修。

其实这一点也不重要,如果default-target配置了,或者干脆workspace就是其中一个子包,build backend 永远看到是子包中的其中一个,看不到 workspace,所以就算直接用 python -m build 也是能正常构建的。

竟然如此,可以考虑一下弱约束 that package 的版本(install的时候导向editable),然后再用 mina 对 pdm install 的 prompt 进行 workspace setup,把子包装成 editiable package
什么?break 没修完?没修完你 build 什么。

抱歉没太明白,不要太跳跃了。

先理清问题,现在剩下的问题是,workspace pdm install 的时候如何 包含子包的依赖,以及子包本身如何被安装成 editable。

对于第一个问题,我上面的评论有补充,你可以继续解释 你认为的${PROJECT_ROOT} 方案的问题

对于第二个问题,因为

build backend 永远看到是子包中的其中一个

那么现在PDM的行为是(你配置了 default-target 情况下)会安装 default-target,而我们希望它两个都安装。其实,在恰当的目录结构下,即子包都位于同一个父目录下,那么 editable 了一个就相当于 editable 了所有,当然,只是 path 暴露正确了,但是没有实际 run build

@GreyElaina
Copy link
Owner

嗯……有个神奇的问题:default-target 只是在无法控制 config settings 或环境变量的情况下为 pdm mina build 指定需要编译的子包,先让我想想看这个到底和 install 有没有关系……应该没有,install 就只是 workspace setup,如果要真的装进某个其他的环境也会是相同的行为才是。

@frostming
Copy link
Contributor Author

frostming commented Feb 3, 2024

最后有没想过这东西这么难设计,是因为workspace他太复杂了,有各种互相依赖、元数据复用等问题。

pdm-project/pdm#1505 仍在摆烂中

我会想到用mina 是发现传统的分包方式会碰到project file(README/LICENSE) 复用不了的问题,需要每个子包拷一份,而我非常受不了repeat和copy。这也正是我为什么对现在的dependency配置方式不满的原因

@GreyElaina
Copy link
Owner

GreyElaina commented Feb 3, 2024

那么……hmm,Requirement 不能塞别的东西……如果可以:

[package]
dependencies = [
    "that_package; mina-workspace != enabled"
]

pyproject.toml 对手动修改开放的吧,说白了,raw deps 就是不在 mina workspace 下被启用的依赖,那就得了……但是 PEP 508 描述的行为似乎不让我这么做。好吧这倒是引出了能丢开 raw deps 的方法:只需要自动过滤掉 mina packages,或者截流到本地的 editable package。

@RF-Tar-Railt
Copy link
Contributor

最后有没想过这东西这么难设计,是因为workspace他太复杂了,有各种互相依赖、元数据复用等问题。

pdm-project/pdm#1505 仍在摆烂中

我会想到用mina 是发现传统的分包方式会碰到project file(README/LICENSE) 复用不了的问题,需要每个子包拷一份,而我非常受不了repeat和copy。这也正是我为什么对现在的dependency配置方式不满的原因

诶等会,现在Mina允许子包设置单独的proj file吗@GreyElaina

@GreyElaina
Copy link
Owner

现在Mina允许子包设置单独的proj file吗

完全没有问题,写就是了。

@RF-Tar-Railt
Copy link
Contributor

最后有没想过这东西这么难设计,是因为workspace他太复杂了,有各种互相依赖、元数据复用等问题。

pdm-project/pdm#1505 仍在摆烂中

我会想到用mina 是发现传统的分包方式会碰到project file(README/LICENSE) 复用不了的问题,需要每个子包拷一份,而我非常受不了repeat和copy。这也正是我为什么对现在的dependency配置方式不满的原因

诶等会,现在Mina允许子包设置单独的proj file吗@GreyElaina

傻了,这俩可以指定文件路径的

@GreyElaina
Copy link
Owner

GreyElaina commented Feb 3, 2024

很好,我们不用什么 optional-dependencies,也不用什么 raw-dependencies 了,直接写给分包的 dependencies,然后在 install via mina 的时候暴露为 optional dependencies 再提供 prompt 就没问题了。不过还是得小心,这个仍然需要 #19 (comment) 提供的处理分包间依赖的方法(或许可以丢个简单的 version check,如果改了就给他报个 warning 或者 err。

此外,workspace 依赖分包似乎会引发一些循环依赖
别点炒饭了好吗求求你了

@frostming
Copy link
Contributor Author

frostming commented Feb 3, 2024

所以还是没懂为什么不依靠 build backend 去收集依赖,这是已有的机制。而非要让 cli 去处理

我是倾向于重 backend 轻 front-end

@GreyElaina
Copy link
Owner

所以还是没懂为什么不依靠 builder去收集依赖而非要让 cli 去处理

我是非常希望 backend first 不到不得已不要强绑定一个 frontend

#19 (comment) 这一设计下,丢个形似 mina-targetmina-workspace-target 即可?

@frostming
Copy link
Contributor Author

frostming commented Feb 3, 2024

所以还是没懂为什么不依靠 builder去收集依赖而非要让 cli 去处理

我是非常希望 backend first 不到不得已不要强绑定一个 frontend

#19 (comment) 这一设计下,丢个形似 mina-targetmina-workspace-target 即可?

我们目的是安装时候包含子包,说白了就是为了开发workspace方便,至于构建和publish单一个hook就解决了,所以放dev dependencies就可以,不涉及循环依赖

@GreyElaina
Copy link
Owner

我们目的是安装时候包含子包,放dev dependencies就可以,不涉及循环依赖

ok……还是得处理分包间依赖。
以及 cli 可以代劳一部分苦劳,帮忙配置一下 devdeps?

@frostming
Copy link
Contributor Author

可以,放着吧

@GreyElaina
Copy link
Owner

pdm add [-T/--mina-target] target_pkg

@GreyElaina GreyElaina merged commit 2a7b3ba into GreyElaina:master Feb 4, 2024
@frostming frostming deleted the rewrite-backend branch February 4, 2024 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants