#重复 #代码块 #JSON #多线程 #报告 #查找 #重复查找

bin+lib superdiff

在您的代码库中搜索类似或重复的代码块

7 个稳定版本

2.2.0 2023 年 3 月 2 日
2.1.2 2023 年 1 月 12 日
2.1.1 2023 年 1 月 2 日
2.0.3 2022 年 12 月 29 日
2.0.2 2022 年 12 月 27 日

#1626命令行实用程序

每月 27 次下载

GPL-3.0 许可证

38KB
784

superdiff

您正在努力从文件中删除类似或重复的代码吗?您怀疑某些代码块可能是复制粘贴的,但略有不同,以至于正常的 diff 方法不起作用吗?您厌倦了逐个检查代码中的重复块了吗?

如果是这样,这可能正是您需要的工具!

功能

  • 查找重复的代码片段
  • 查找相似足够的代码片段
  • JSON 报告以实现 jq 集成
  • 足够快(17k 代码行,块大小为 10,Levenshtein 阈值为 10 需要 00:01:12)
  • 可以在多个文件中检查重复的代码
  • Vim 集成!
  • 多线程

限制

  • 对于大文件不是即时完成的
  • 多线程仅适用于多个文件(单个文件运行时没有区别)

简短示例

$ superdiff -l 1 -b 5 examples/really-bad-code.py
=== MATCH ===
File: examples/really-bad-code.py
Lines: [5, 11]
Size: 5
$ find src vim-superdiff -type f | superdiff -l 1 -b 7 --worker-threads 4
=== MATCH ===
File: src/types.rs
Lines: [87, 185]
Size: 7

=== MATCH ===
File: vim-superdiff/autoload/superdiff.vim
Lines: [136, 152]
Size: 7

用法

假设您有一些文件 examples/really-bad-code.py,您想要检查。

examples/really-bad-code.py
#!/usr/bin/env python

class SomeClass:
    def __init__(self):
        self.alpha = 12
        self.beta = 14
        self.gamma = 16
        self.is_bad = True

    def reset(self):
        self.alpha = 12
        self.beta = 14
        self.gamma = 16
        self.is_bad = True

    def do_something(self):
        d = {}

        import random
        for i in range(20):
            if i % 3 == 0: continue
            d[i] = random.randrange(1, 1001)
            d[i ** 2] = d[i] ** 2
            d[d[i]] = i

    def do_something_else(self):
        d = {}

        import random
        for i in range(21):
            if i % 3 == 1: continue
            d[i] = random.randrange(1, 1001)
            d[i ** 2] = d[i]
            d[d[i]] = i

inst = SomeClass()
inst.reset()

您有一种感觉,这可能很糟糕,所以您使用了这个工具。

$ superdiff -b 4 examples/really-bad-code.py
=== MATCH ===
File: "examples/really-bad-code.py"
Lines: [5, 11]
Size: 5

A total of 1 unique match(es) were found in the 1 file(s).

哇!您找到了这个真是太好了!但也许文件中有一些地方不是完全相同的副本,但相似度足够高。

$ superdiff -b 4 -t 5 examples/really-bad-code.py
=== MATCH ===
File: "examples/really-bad-code.py"
Lines: [16, 26]
Size: 10

=== MATCH ===
File: "examples/really-bad-code.py"
Lines: [5, 11]
Size: 5

嗯,显然有一个相似度很高的重复函数!现在(假设函数的输出相当长,而不是可笑的短),您想知道第 30 行是否涉及到重复的代码,所以您这样做

$ superdiff --reporting-mode json -b 5 -t 5 examples/really-bad-code.py > output.json
$ cat output.json | jq
{
  "files": {
    "examples/really-bad-code.py": {
      "count_blocks": 4
    }
  },
  "matches": [
    {
      "blocks": {
        "examples/really-bad-code.py": [
          {
            "block_length": 5,
            "starting_line": 11
          },
          {
            "block_length": 5,
            "starting_line": 5
          }
        ]
      },
      "files": {
        "examples/really-bad-code.py": {
          "count_blocks": 2
        }
      }
    },
    {
      "blocks": {
        "examples/really-bad-code.py": [
          {
            "block_length": 10,
            "starting_line": 26
          },
          {
            "block_length": 10,
            "starting_line": 16
          }
        ]
      },
      "files": {
        "examples/really-bad-code.py": {
          "count_blocks": 2
        }
      }
    }
  ],
  "version": "2.1.2"
}
$ cat output.json | jq '.matches | map(select((.blocks."examples/really-bad-code.py" | any(.starting_line <= 30 and .starting_line + .block_length >= 30))))'
[
  {
    "files": {
      "examples/really-bad-code.py": {
        "count_blocks": 2
      }
    },
    "blocks": {
      "examples/really-bad-code.py": [
        {
          "starting_line": 16,
          "block_length": 10
        },
        {
          "starting_line": 26,
          "block_length": 10
        }
      ]
    }
  }
]

注意:如果有人发现更好的 jq 查询方法,请提交拉取请求并/或告诉我。

Vim 集成

目前还处于开发中,但以下是我们拥有的

  • 使用 :SDLoad 加载 JSON(确保您在运行 superdiff 的同一目录中)
  • 打开一个文件进行编辑
  • 运行 :SDLocal 以突出显示匹配的代码块
  • 对匹配的块运行 :SDQuery 以查找其他类似的代码块

检查 vimdocs 以获取更多选项和命令。

asciicast

基准测试

这些数字是为了给出一个粗略估计,说明在某些文件的情况下需要多长时间。这不是科学的。我只是简单地将 time 添加到开始处并复制了 real 时间。

本基准测试所使用的数据可以在 scripts/populate-data.sh 中找到。

版本 测试名称 参数 时间
2.0.3 TerrariaClone -b5 -t5json 40.284秒
2.0.3 TerrariaClone -b5json 0.489秒
2.1.2 TerrariaClone -b5 -t5json 27.876秒
2.1.2 TerrariaClone -b5json 0.473秒
2.2.0 TerrariaClone -b5 -t5 --worker-threads4json 13.409秒
2.2.0 TerrariaClone -b5 --worker-threads4json 0.348秒

依赖项

~1.6–2.6MB
~51K SLoC