又开发了一个优雅的小工具!

在开源项目中,Issues是一个强大的功能,用于跟踪bug、功能请求和任务。然而,随着项目的发展,Issues可能会变得难以管理,特别是当你需要离线访问或进行深入分析时。

当然GitHub Issues除了上述功能以外,做在线笔记也非常的方便,它支持Markdown语法,还能打标签、分层等等,还天然的支持评论功能。由于我本人就非常热衷于使用Issue做笔记,但是问题就是在离线环境下无法使用,那么能不能把Issue作为离线Markdown文件下载到本地呢?

答案显然是可以的,也是我本次项目的主要功能之一。

issue2file是一个用Go语言编写的命令行工具,它可以将GitHub仓库中的Issues导出为本地Markdown文件,并提供多种强大的功能:

1)完整内容保留:保留Issue的标题、内容、标签、状态、创建时间等信息

2)评论支持:可选择性地下载Issue的所有评论

除此之外,我想了想能不能通过AI扩展一下?答案显然也是可以的,所以还补充了如下功能:

3)AI分析:集成AI功能,可以对Issues进行智能分析和总结

4)数据可视化:自动生成多种图表,包括Issue状态分布、标签分布和时间趋势等

项目介绍

还是先说一下使用方式吧,当然如果想要支持私有仓库和AI功能的话,需要拿到自己的Github Token和DeepSeek的API Token。

1)仓库地址

https://github.com/ibarryyan/issue2file

2)工具构建

go mod tidy 
go build 

3)使用方式

最简单的使用方式就是直接运行可执行文件,加上仓库链接作为参数,比如

./issue2file ibarryyan/golang-tips-100

如果想要拉取自己的私有仓库就要先生成一个自己的Github Token,然后使用命令行参数或者配置文件进行启动,详细说明可以参考:

https://github.com/ibarryyan/issue2file/blob/master/README.md

当然了,还有额外的参数能支持生成图表分析仓库的所有Issue,主要有Issue创建时间趋势、状态分析和标签分布等几个维度:

技术实现

issue2file采用模块化设计,主要包含以下几个核心组件:

1)配置管理:使用Viper库处理配置文件

2)GitHub API交互:使用go-github库获取Issues数据

3)Markdown生成:将Issue数据转换为Markdown格式

4)AI分析:集成AI能力对Issues进行分析

5)图表生成:使用go-echarts库生成数据可视化图表

关键技术点

1)配置管理

项目使用Viper库来处理配置,支持从配置文件中读取各种参数:

func InitConfig() {viper.SetConfigName("config")viper.SetConfigType("conf")viper.AddConfigPath(".")if err := viper.ReadInConfig(); err != nil {log.Fatalf("Error reading config file: %s", err)}// 读取配置项Config.GitHubToken = viper.GetString("gitHubToken")Config.AIToken = viper.GetString("aiToken")Config.CommentEnable = viper.GetBool("commentEnable")Config.AIEnable = viper.GetBool("aiEnable")Config.ChartEnable = viper.GetBool("chartEnable")Config.OutputDir = viper.GetString("outputDir")Config.SummaryFile = viper.GetString("summaryFile")
}

2)GitHub API交互

使用go-github库与GitHub API进行交互,获取Issues数据:

func FetchIssues(owner, repo string) ([]*github.Issue, error) {ctx := context.Background()ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: Config.GitHubToken},)tc := oauth2.NewClient(ctx, ts)client := github.NewClient(tc)opt := &github.IssueListByRepoOptions{State:     "all",Sort:      "created",Direction: "desc",ListOptions: github.ListOptions{PerPage: 100,},}var allIssues []*github.Issuefor {issues, resp, err := client.Issues.ListByRepo(ctx, owner, repo, opt)if err != nil {return nil, err}allIssues = append(allIssues, issues...)if resp.NextPage == 0 {break}opt.Page = resp.NextPage}return allIssues, nil
}

3)Markdown生成

将Issue数据转换为结构化的Markdown文件:

func GenerateMarkdown(issue *github.Issue, comments []*github.IssueComment) string {var md strings.Builder// 添加标题md.WriteString(fmt.Sprintf("# %s\n\n", *issue.Title))// 添加元数据md.WriteString(fmt.Sprintf("- **Issue编号**: #%d\n", *issue.Number))md.WriteString(fmt.Sprintf("- **创建者**: %s\n", *issue.User.Login))md.WriteString(fmt.Sprintf("- **创建时间**: %s\n", issue.CreatedAt.Format("2006-01-02 15:04:05")))md.WriteString(fmt.Sprintf("- **状态**: %s\n", *issue.State))// 添加标签if len(issue.Labels) > 0 {md.WriteString("- **标签**: ")for i, label := range issue.Labels {if i > 0 {md.WriteString(", ")}md.WriteString(*label.Name)}md.WriteString("\n")}// 添加正文md.WriteString("\n## 内容\n\n")md.WriteString(*issue.Body)// 添加评论if len(comments) > 0 {md.WriteString("\n\n## 评论\n\n")for _, comment := range comments {md.WriteString(fmt.Sprintf("### %s 评论于 %s\n\n", *comment.User.Login, comment.CreatedAt.Format("2006-01-02 15:04:05")))md.WriteString(*comment.Body)md.WriteString("\n\n---\n\n")}}return md.String()
}

4)AI分析

集成AI能力,对Issues进行智能分析和总结:

func AnalyzeIssues(issues []*github.Issue) (string, error) {if !Config.AIEnable || Config.AIToken == "" {return "", errors.New("AI analysis is disabled or token is not provided")}// 准备AI分析的输入数据var input strings.Builderinput.WriteString("请分析以下GitHub Issues,并提供总结报告:\n\n")for _, issue := range issues {input.WriteString(fmt.Sprintf("Issue #%d: %s\n", *issue.Number, *issue.Title))input.WriteString(fmt.Sprintf("状态: %s\n", *issue.State))input.WriteString(fmt.Sprintf("创建时间: %s\n", issue.CreatedAt.Format("2006-01-02")))input.WriteString("标签: ")for i, label := range issue.Labels {if i > 0 {input.WriteString(", ")}input.WriteString(*label.Name)}input.WriteString("\n\n")// 限制内容长度,避免超出AI API的限制body := *issue.Bodyif len(body) > 500 {body = body[:500] + "..."}input.WriteString(body)input.WriteString("\n\n---\n\n")}// 调用AI API进行分析analysis, err := callAIAPI(input.String())if err != nil {return "", err}return analysis, nil
}

5)图表生成

使用go-echarts库生成数据可视化图表:

func GenerateCharts(issues []*github.Issue, outputDir string) error {if !Config.ChartEnable {return nil}// 生成状态分布图if err := generateStatusChart(issues, outputDir); err != nil {return err}// 生成标签分布图if err := generateTagsChart(issues, outputDir); err != nil {return err}// 生成时间趋势图if err := generateTimeChart(issues, outputDir); err != nil {return err}return nil
}

全部代码目前已经开源,大家可以去Github上拉取~~

开源成果

issue2file项目在开源后的一周内就获得了29个star,这种积极的社区反馈不仅验证了项目的价值,也为未来的发展提供了动力。

在这里主要感谢@ruanyf老师在《科技爱好者周刊》中的推荐!

总结与规划

issue2file成功地实现了将GitHub Issues转换为本地Markdown文件的核心功能,并通过AI分析和数据可视化等特性提供了额外的价值。

基于社区反馈和项目愿景,未来的发展计划包括:

功能增强

  • 添加增量更新功能,只下载新的或更新的Issues
  • 增强AI分析能力,提供更深入的洞察

用户体验改进

  • 提供Web界面,使非技术用户也能轻松使用
  • 添加进度显示和更详细的日志
  • 完善文档和示例

如果你对这个项目感兴趣,欢迎访问GitHub仓库(https://github.com/ibarryyan/issue2file),给项目点个star,或者贡献代码!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/94068.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/94068.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【安装教程】Docker Desktop 安装与使用教程

文章目录一、环境要求二、安装步骤2.1 安装 WSL 2(适用于非专业版 Windows 10 及 Windows 11)2.2 安装 Docker Desktop2.3 汉化 DDocker Desktop2.4 卸载 Docker Desktop三、使用 Docker3.1验证安装3.2. 拉取镜像3.3. 运行容器3.4. 查看容器3.5.更改容器…

Hutool 的 WordTree(敏感词检测)

package cn.hutool.dfa;WordTree 继承自 HashMap<Character, WordTree>&#xff0c;表示一个字符到子树的映射&#xff0c;构成一颗“词树”&#xff08;类似 Trie 树&#xff09;&#xff0c;用于快速匹配字符串中的词语&#xff08;敏感词检测、关键词匹配等&#xff0…

Makefile 从入门到精通:自动化构建的艺术

引入 在软件开发的世界里&#xff0c;“编译” 是绕不开的环节&#xff0c;但手动编译大型项目时&#xff0c;重复输入编译命令的痛苦&#xff0c;相信每个开发者都深有体会。Makefile 作为自动化构建的基石&#xff0c;能让编译过程“一键完成”&#xff0c;甚至智能判断文件变…

利用DeepSeek将Rust程序的缓冲输出改写为C语言实现提高输出效率

在前面多语言测试中&#xff0c;遇到一个难以置信的问题&#xff0c;rust的输出到文件比c语言还快&#xff0c;这是不合情理的&#xff0c;通过对两者输出语句的比较&#xff0c;发现了不同。 rust程序在输出到stdout前有这么一句 let mut writer BufWriter::with_capacity(6…

Java Optional 类教程详解

一、Optional 类核心定位Optional 是 Java 8 引入的函数式容器类&#xff08;java.util.Optional&#xff09;&#xff0c;专为​​显式空值处理​​设计。其核心价值在于&#xff1a;消除 60% 以上的传统 null 检查代码通过类型系统强制空值声明&#xff0c;降低 NPE 风险支持…

Agent X MCP 把想法编译成现实

多模态GUI智能体协作型AI魔搭社区MCPMCP 硬件

cv快速input

效果<view class"miniWhether-box-lss"><view class"content-inp-text">快递单号</view><input class"content-inp-input" type"text"v-model"expressInfo.expressNo" placeholder"填写快递单号&…

[AI8051U入门第十二步]W5500-Modbus TCP从机

学习目标: 1、了解Modbus Tcp协议 2、学习Modbus Tcp 从机程序驱动 3、使用 Modbus Pull调试一、Modbus TCP介绍? Modbus TCP 是一种基于 TCP/IP 网络的工业通信协议,是 Modbus 协议家族中的一员,专门为以太网环境设计。它是 Modbus RTU(串行通信)协议的扩展,将 Modbus…

Python编程基础与实践:Python循环结构基础

循环结构 学习目标 通过本课程的学习&#xff0c;学员可以掌握Python中for循环和while循环的基本使用方法&#xff0c;了解如何利用循环结构来重复执行代码块&#xff0c;以及如何使用break和continue语句来控制循环的执行流程。 相关知识点 循环结构 学习内容 1 循环结构 1.1 …

趣谈设计模式之模板方法模式-老板,你的数字咖啡制作好了,请享用!

模板方法模式 定义了一套算法的骨架&#xff0c;讲某些具体的步骤延迟到子类中实现。 主要用于不改变算法结构的情况下重新定义算法的某些步骤&#xff0c;以适应新的需求。 模板方法的角色 抽象类&#xff1a; 作为算法的骨架&#xff0c;该抽象类中包含了算法的核心部分和…

技术栈:基于Java语言的搭子_搭子社交_圈子_圈子社交_搭子小程序_搭子APP平台

一、市场背景1、社会发展与生活方式转变城市化进程加快&#xff1a;随着城市化不断推进&#xff0c;大量人口涌入城市&#xff0c;人们生活的物理空间距离拉近了&#xff0c;但人际关系却在一定程度上变得疏离。传统的基于血缘、地缘建立起的紧密社交关系难以满足城市生活中的多…

字典在VBA与VB.NET的区别,举例说明

简述&#xff1a;在VBA中&#xff0c;字典通常使用Scripting.Dictionary对象&#xff0c;通过CreateObject("Scripting.Dictionary")创建。它需要引用Microsoft Scripting Runtime库&#xff08;scrrun.dll&#xff09;。VBA字典的方法包括Exists、Add、Remove等&…

2024年网络安全案例

以下是2024年造成严重损失的网络安全典型案例&#xff0c;涵盖市政系统、金融交易、区块链平台、国家级攻击及全球性IT故障五大领域&#xff0c;按损失规模和技术危害性综合排序&#xff1a;---一、市政基础设施攻击 1. 加拿大汉密尔顿市勒索软件事件 - 损失&#xff1a;183…

PINN+贝叶斯:深度学习中的魔改新思路

2025深度学习发论文&模型涨点之——PINN贝叶斯PINN通过将物理定律&#xff08;如偏微分方程PDEs&#xff09;嵌入神经网络的损失函数中&#xff0c;使得模型能够利用已知的物理规律来指导学习过程&#xff0c;从而在数据有限或噪声较多的情况下实现更高的准确性。然而&…

零基础-动手学深度学习-8.3. 语言模型和数据集

很至关重要的一章: 8.3.1. 学习语言模型 8.3.2. 马尔可夫模型与n元语法 n元语法看的序列长度是固定的&#xff0c; 存储的序列长是有限且可控的&#xff0c;使用统计方法的时候通常使用这个模型&#xff01;&#xff01;&#xff01;统计方法&#xff01;&#xff01;&#x…

C++ 模板初阶

什么是模板&#xff1f; 模板&#xff08;Template&#xff09;是 C 中实现泛型编程的核心工具。它允许我们编写与具体数据类型无关的代码&#xff0c;从而实现代码复用和类型安全。为什么需要模板&#xff1f; 举个生活中的例子&#xff1a;如果你要造一个能装水的杯子&#x…

DockerFile文件执行docker bulid自动构建镜像

文章目录一、Dockerfile介绍二、Dockerfile镜像制作和流程使用三、Dockerfile文件的制作镜像的分层结构四、Dockerfile文件格式五、Dockerfile相关指令5.1 FROML&#xff1a;指定基础镜像5.2 LABEL&#xff1a;指定镜像元数据5.3 RUN&#xff1a;执行shell指令5.4 ENV&#xff…

osloader!DoGlobalInitialization函数分析之HW_CURSOR--NTLDR源代码分析之设置光标

第一部分&#xff1a; VOID DoGlobalInitialization(IN PBOOT_CONTEXT BootContextRecord){//// Turn the cursor off//HW_CURSOR(0,127);D:\srv03rtm\base\boot/inc/bldrx86.h:258:#define HW_CURSOR (*ExternalServicesTable->HardwareCursor)第二部分&#xff…

Elasticsearch 索引及节点级别增删改查技术

以下是针对 Elasticsearch 索引及节点级别增删改查技术做的简短总结&#xff1a; 一、索引操作创建索引 功能&#xff1a;指定分片、副本数及映射规则[2][4]。示例&#xff1a;PUT /<index_name>​&#xff0c;可定义 settings&#xff08;如分片数&#xff09;和 mappin…

烽火HG680-KD_海思MV320处理器-安卓9-原厂系统升级包-针对解决烧录不进系统的问题

烽火HG680-KD_海思MV320处理器-安卓9-原厂系统升级包&#xff08;注意是&#xff08;原机系统&#xff09;&#xff09;-主要是针对解决TTL烧录后仍然不进系统使用。HG680-KD&#xff0f;HG680-KE&#xff0f;HG680-KF&#xff0f;HG680-KX 均通用。 说明&#xff1a; 前一个…