github0null / eide

An embedded development environment for mcs51/stm8/avr/cortex-m/riscv on VsCode.
https://em-ide.com
MIT License
632 stars 70 forks source link

[bug] EIDE 无法正确处理 .tar.xz 工具链包 #262

Closed MingcongBai closed 4 months ago

MingcongBai commented 1 year ago

What are you doing?

Linux 环境下,在 EIDE 中下载 MTI GCC 对应的工具链包(.tar.xz 格式)。

Describe the bug

下载和解压工具链包后,EIDE 报错显示工具链不可用,检查默认安装位置 (~/.eide/tools/mti_gcc) 后,发现里面只有一个解压了 .xz 的 .tar 文件。

To Reproduce

见上

Expected behavior

EIDE 应该解压 .xz 后同时解压 .tar。

Screenshots

N/A

Desktop (please complete the following information):

Additional context

N/A

github0null commented 1 year ago

对于 linux,仅支持普通的 tar 包解压,不会根据后缀 tar.gz tar.xz 等调用特定命令解压

请提供较通用的格式,比如 zip, 7z

这样更便于完全统一解压命令

MingcongBai commented 1 year ago

对于 linux,仅支持普通的 tar 包解压,不会根据后缀 tar.gz tar.xz 等调用特定命令解压

请提供较通用的格式,比如 zip, 7z

这样更便于完全统一解压命令

了解,我修改一下 index.json 后会在 eide_default_external_tools_index 仓库开个 PR。

Rongronggg9 commented 1 year ago

不会根据后缀 tar.gz tar.xz 等调用特定命令解压……这样更便于完全统一解压命令

GNU tar 和 BSD tar 均可在解压(x mode)和列出(t mode)时自动检测文件格式。

Reading compressed archive is even simpler: you don’t need to specify any additional options as GNU tar recognizes its format automatically. Thus, the following commands will list and extract the archive created in previous example:

# List the compressed archive
$ tar tf archive.tar.gz
# Extract the compressed archive
$ tar xf archive.tar.gz

https://www.gnu.org/software/tar/manual/tar.html#gzip

(c mode only) Compress the resulting archive with ${program}. In extract or list modes, this option is ignored. Note that this tar implementation recognizes ${format} compression automatically when reading archives.

https://man.freebsd.org/cgi/man.cgi?tar(1)

因此,只需 tar -xf $tarball 即可统一解压命令。

github0null commented 1 year ago

@Rongronggg9

因此,只需 tar -xf $tarball 即可统一解压命令。

目前在非 win32 环境中,对于后缀带有 tar 字样的, 默认就是用的 tar -xvf

但实际对于 tar.xz,可能要使用 -xvJf

https://github.com/github0null/eide/blob/b8699d329e23095d0e0cb77d3f29f897aaa7385f/src/Compress.ts#L66-L69

Rongronggg9 commented 1 year ago

目前在非 win32 环境中,对于后缀带有 tar 字样的, 默认就是用的 tar -xvf 但实际对于 tar.xz,可能要使用 -xvJf

流行的 tar 实现中,只有 Busybox tar 需要在解包时指定格式。

GNU tar 为每种受支持的压缩格式硬编码了 magic 并被优先用于格式识别,不能识别时回落到扩展名识别。因此只有 magic 和扩展名均不正确的 tar.xz 才可能需要使用 -J,实际使用中应只有一种情况需要特别指定压缩格式,即从 stdin 而非文件读入归档时。(src/buffer.c

GNU tar 不会出现前面所述的「外层 xz 被解压而内层 tar 未被解包」的情况,GNU tar 调用外部程序后是直接通过管道传回,不会在磁盘上创建临时文件。如果 GNU tar 不能识别格式,只会报错退出,不会执行任何进一步操作。这个问题应该另有原因。

BSD tar 的情况类似。


实际上,对于 .tar.*,EIDE 根本没有使用 tar 来解包,而是直接使用了 7z。解压外层而不解包内层 tar 正是 7z 的典型行为。问题在于 EIDE 的扩展名检测是粗大的: https://github.com/github0null/eide/blob/f8ad4c56116beb6b89199a69d606ad95af72d9e9/src/Compress.ts#L163 https://github.com/github0null/node-utility/blob/cb1e5e59e138f7fe997eb2118d9c2f65f0109d7a/File.ts#L22 zipFile.suffix 实际上就是 Path.extname,返回文件狭义的(即最外层的)扩展名。因此,*.tar.xz 的 suffix 就是 xz,看似取巧的 startsWith() 在这里起不到任何预期作用。eide_default_external_tools_index 中的 zip_type 在这里并没有被使用。

获取广义扩展名的现有实现可供参考: https://github.com/ruyadorno/path-complete-extname GNU tar 支持的扩展名列表: https://git.savannah.gnu.org/cgit/tar.git/tree/src/suffix.c?h=release_1_34

github0null commented 1 year ago

OK,软件逻辑错误后面会修复的