如何限制 go 代码引用模块的目录?

2022-06-26 08:55:27 +08:00
 sadfQED2
一个 mvc 结构的 go 语言项目,正常情况下应该是 controller 层调用 service ,service 调用 model



但是,总有一些屌毛,可能由于紧急情况,可能是懒,在偶尔周末加班等没人 CR 的时候,controller 层调其他 controller 里面的方法,controller 也在调 model 方法。偶尔还他妈 model 调 contrller 代码。刚开始可能就一两处这样写,但是后续的人改这种代码,也只能接着这样写。最终项目崩塌,成为真正的屎山。



很多年前,我在另外一家公司写 php 的时候,我记得当时项目是对代码引用做了限制,如果写出上面这样乱引用代码,提交的时候直接被拒。想请问一下 go 语言里面能否加这种配置呢?在哪加?知道的麻烦给个关键词吧
2218 次点击
所在节点    程序员
22 条回复
wenerme
2022-06-26 09:11:04 +08:00
如果是限制外部 .golangci.yml 配置 ban

```
linters-settings:
depguard:
list-type: blacklist # 限制列表
packages:
- golang.org/x/net/context
```


但是你说的这个属于代码规范层面了,不是限制问题,你限制了,他也能绕开,所以是规范,规范是靠人维护和遵守的,规则只能保证部分。
napsterwu
2022-06-26 09:41:58 +08:00
你以前那个应该是在 git hook 里写了一些检测脚本吧
joesonw
2022-06-26 09:47:49 +08:00
这种引用的检测自己实现一个 lint 非常简单,ast 的知识都不需要了解。可以写一段代码手动扫描,或者实现一个 golangci-lint 的 custom linter (这个比较麻烦,算编译成 go plugin ,go 版本和系统要完全一致才可以,意味着最好是用的时候编译)
issakchill
2022-06-26 09:56:56 +08:00
感觉拉个会 叼一下人 会方便点
sadfQED2
2022-06-26 10:35:20 +08:00
@napsterwu 是的,但是我不知道怎么实现的
sadfQED2
2022-06-26 10:37:04 +08:00
@issakchill 有编程规范,但是项目里面有部分是外包,隔三差五换人。隔三差五拉个会说这种事挺累的
Trim21
2022-06-26 10:46:13 +08:00
可以设置 golangci-lint ,用 depguard 写一个非常复杂的配置。

或者写个 go 的脚本在 ci 里面跑一下,用 go 标准库的 go 语言 parser ,不算错误处理三行就能列出一个文件所有的 import 。然后直接 has prefix 就行

https://pkg.go.dev/go/parser#ParseFile
Trim21
2022-06-26 10:47:37 +08:00
Trim21
2022-06-26 10:51:16 +08:00
不过如果是比较复杂的情况,比如想要阻止的“controller 调 controller”是一个结构体调用其他方法的话,实现起来就比较麻烦了
hubqin
2022-06-26 11:15:38 +08:00
了解下 go 的 internal 目录,不想被其他目录之外引用,就放在这个目录
fgwmlhdkkkw
2022-06-26 11:33:46 +08:00
你整个依赖注入,让用的人方便不久好了吗?
fgwmlhdkkkw
2022-06-26 11:34:09 +08:00
@fgwmlhdkkkw #11 久 =》 就
singerll
2022-06-26 11:34:49 +08:00
让领导跟外包公司谈好,推的人出现这种情况扣钱。
CoderGeek
2022-06-26 14:00:35 +08:00
想问下 对 go 了解不多 用 grpc 的模式下

1. 前端或移动端向 endpoint 发送请求
2. grpc-gateway 作为 reversed proxy ,首先承接到请求,然后转发到对应的 GRPC endpoint
3. Grpc service 的 handler 接收到请求
1. 做 request validation
2. 把外部的 entity 转为内部 entity
4. Grpc service 的 controller 接收到请求
1. 进行业务逻辑运算,可能会调用 gateway 的部分 function
2. 也可能会调用其他 controller 的 function
5. Grpc handler 拿到 controller 的运算结果
1. 如果出错,返回 error ,被 middleware 接住 error ,进行 log ,然后返回
2. 如果没有出错,获得结果后,调用 mapper ,把 internal entity 转为 external entity
6. grpc-gateway 拿到 handler 的计算结果,返回给 caller

这样的 mvc 结构 controller 层调其他 controller 有什么问题吗就是弊端 望指教
sadfQED2
2022-06-26 15:23:36 +08:00
@CoderGeek controller 互调最终结果就是代码逻辑混乱,代码完全不可读
sadfQED2
2022-06-26 15:25:17 +08:00
@singerll 大家都打工的,扣别人钱感觉不太合适了。以前公司遇见过这种限制,所以想加个限制,直接从根源上解决问题
codeMore
2022-06-26 16:53:24 +08:00
同 10 楼,可以用 go 的 internal 目录去限制,语言自带的
BeautifulSoap
2022-06-26 16:59:04 +08:00
你要知道,调用什么层 = 引用了这个层的包

所以直接写个脚本,用正则检测各个层的目录下有没有引入不想引入的层包不就好了?
如果是 github 的话这种功能我一般都是直接写到 github actions 里的,不让提 pr
realpg
2022-06-26 17:59:12 +08:00
@sadfQED2 #5
PHP 时代我们也做过
直接检查包名,M 、C 是固定目录的,框架规定,然后允许引用的包进行判断
但是这么管不了不 import ,直接写全路径的,这种可以结合代码 review 罚钱解决
zjj19950716
2022-06-27 13:56:09 +08:00
controller 也在调 model 方法。偶尔还他妈 model 调 contrller 代码。
不会循环应用吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/862236

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX