excavate 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +69 -0
  3. data/.github/workflows/links.yml +94 -0
  4. data/.github/workflows/rake-metanorma.yaml +2 -10
  5. data/.github/workflows/rake.yml +5 -71
  6. data/.github/workflows/release.yml +8 -6
  7. data/.gitignore +24 -2
  8. data/.rubocop_todo.yml +22 -22
  9. data/README.adoc +50 -10
  10. data/docs/Gemfile +12 -0
  11. data/docs/_config.yml +108 -0
  12. data/docs/assets/logo.svg +1 -0
  13. data/docs/concepts/archive-formats.adoc +116 -0
  14. data/docs/concepts/excavate-path.adoc +199 -0
  15. data/docs/concepts/extractor-architecture.adoc +157 -0
  16. data/docs/concepts/format-detection.adoc +131 -0
  17. data/docs/concepts/index.adoc +45 -0
  18. data/docs/concepts/recursive-extraction.adoc +130 -0
  19. data/docs/developer/architecture/design-principles.adoc +153 -0
  20. data/docs/developer/architecture/diagrams.adoc +154 -0
  21. data/docs/developer/architecture/extending.adoc +194 -0
  22. data/docs/developer/architecture/extractor-pattern.adoc +165 -0
  23. data/docs/developer/architecture/format-detection.adoc +154 -0
  24. data/docs/developer/architecture/index.adoc +79 -0
  25. data/docs/developer/code-style.adoc +235 -0
  26. data/docs/developer/contributing.adoc +139 -0
  27. data/docs/developer/debugging.adoc +235 -0
  28. data/docs/developer/index.adoc +69 -0
  29. data/docs/developer/release-process.adoc +186 -0
  30. data/docs/developer/testing.adoc +215 -0
  31. data/docs/examples/batch-font-extraction.adoc +137 -0
  32. data/docs/examples/extract-msi-installer.adoc +139 -0
  33. data/docs/examples/filter-by-pattern.adoc +166 -0
  34. data/docs/examples/index.adoc +43 -0
  35. data/docs/examples/rails-upload-handler.adoc +199 -0
  36. data/docs/getting-started/basic-usage.adoc +389 -0
  37. data/docs/getting-started/common-workflows.adoc +286 -0
  38. data/docs/getting-started/index.adoc +79 -0
  39. data/docs/getting-started/installation.adoc +224 -0
  40. data/docs/getting-started/quick-start.adoc +225 -0
  41. data/docs/guides/advanced-usage/error-handling.adoc +266 -0
  42. data/docs/guides/advanced-usage/index.adoc +57 -0
  43. data/docs/guides/advanced-usage/performance-tuning.adoc +264 -0
  44. data/docs/guides/advanced-usage/recursive-extraction.adoc +220 -0
  45. data/docs/guides/basic-usage/extracting-files.adoc +244 -0
  46. data/docs/guides/basic-usage/file-iteration.adoc +257 -0
  47. data/docs/guides/basic-usage/filter-patterns.adoc +265 -0
  48. data/docs/guides/basic-usage/index.adoc +61 -0
  49. data/docs/guides/basic-usage/selective-extraction.adoc +227 -0
  50. data/docs/guides/formats/cab-format.adoc +156 -0
  51. data/docs/guides/formats/format-comparison.adoc +200 -0
  52. data/docs/guides/formats/index.adoc +96 -0
  53. data/docs/guides/formats/msi-format.adoc +140 -0
  54. data/docs/guides/formats/rpm-format.adoc +146 -0
  55. data/docs/guides/formats/sevenzip-format.adoc +132 -0
  56. data/docs/guides/formats/tar-format.adoc +137 -0
  57. data/docs/guides/formats/xar-pkg-format.adoc +156 -0
  58. data/docs/guides/index.adoc +64 -0
  59. data/docs/guides/use-cases/batch-processing.adoc +260 -0
  60. data/docs/guides/use-cases/font-extraction.adoc +149 -0
  61. data/docs/guides/use-cases/index.adoc +56 -0
  62. data/docs/guides/use-cases/installer-analysis.adoc +209 -0
  63. data/docs/index.adoc +287 -0
  64. data/docs/reference/api.adoc +405 -0
  65. data/docs/reference/cli.adoc +331 -0
  66. data/docs/reference/error-classes.adoc +187 -0
  67. data/docs/reference/formats/extension-mapping.adoc +174 -0
  68. data/docs/reference/formats/index.adoc +129 -0
  69. data/docs/reference/formats/supported-formats.adoc +148 -0
  70. data/docs/reference/index.adoc +39 -0
  71. data/docs/resources/compatibility.adoc +239 -0
  72. data/docs/resources/faq.adoc +181 -0
  73. data/docs/resources/glossary.adoc +120 -0
  74. data/docs/resources/index.adoc +54 -0
  75. data/docs/resources/migration.adoc +169 -0
  76. data/docs/resources/omnizip-suite.adoc +152 -0
  77. data/docs/resources/performance.adoc +186 -0
  78. data/docs/resources/quick-reference.adoc +262 -0
  79. data/docs/troubleshooting/common-errors.adoc +223 -0
  80. data/docs/troubleshooting/corrupted-files.adoc +207 -0
  81. data/docs/troubleshooting/index.adoc +74 -0
  82. data/docs/troubleshooting/performance-issues.adoc +247 -0
  83. data/docs/troubleshooting/platform-specific.adoc +235 -0
  84. data/excavate.gemspec +5 -4
  85. data/lib/excavate/archive.rb +6 -0
  86. data/lib/excavate/version.rb +1 -1
  87. metadata +84 -8
  88. data/.github/workflows/post-rake.yml +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7adbf7839cf5917692766601ec8b44ec32794e860a658ef9cdb9594031cc904e
4
- data.tar.gz: 3fa93a928c9fd291f757c740c320e39f9431af5fc718352c5671f5dc7b4c9721
3
+ metadata.gz: d579e821dbcdc3891ec86ccc385b815735aec447f7aaccf6980430002b77e009
4
+ data.tar.gz: 409103ecdac9190c965a2e9414dc507b02e9a0654dcc7c1eeab01eec018ce916
5
5
  SHA512:
6
- metadata.gz: 7e40f307222b934913b71e731e94df4488d2fd668895a3ded5c010c592791666655a44330c74c10f66c2be892f975341afec98c9961bcd6f6a0f4448680b5147
7
- data.tar.gz: d7774a97313fffd8f773f8df098c564edb8bce53c8b96b47b1669504729517c35fb27f7627cd161733068b9c0ce7b1183c6dd23516ee5984089adcabf89c14cc
6
+ metadata.gz: 2431a0910c6d163b790dddcd5745129017848aca78093b935156ef8ef0ff4d0c4cf8ecbc8c6fb1b8eafcc29078556236632b9e0e9884c5c5794b24073829bbe0
7
+ data.tar.gz: 4450fa82f329350881d0ea3f25f2396ec40c3c34af5523753d59f7a3540a3ea5dde9bcdb77bd8873f6ab5064f4d8beeb1b81bb05db41368a16a598a970669de8
@@ -0,0 +1,69 @@
1
+ name: Documentation
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - 'docs/**'
9
+ - '.github/workflows/docs.yml'
10
+ pull_request:
11
+ paths:
12
+ - 'docs/**'
13
+ workflow_dispatch:
14
+
15
+ # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
16
+ permissions:
17
+ contents: read
18
+ pages: write
19
+ id-token: write
20
+
21
+ # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
22
+ # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
23
+ concurrency:
24
+ group: ${{ github.workflow }}-${{ github.ref }}
25
+ cancel-in-progress: false
26
+
27
+ jobs:
28
+ build:
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - name: Checkout
32
+ uses: actions/checkout@v4
33
+
34
+ - name: Setup Ruby
35
+ uses: ruby/setup-ruby@v1
36
+ with:
37
+ ruby-version: '3.4'
38
+ bundler-cache: true
39
+ cache-version: 0
40
+ working-directory: docs
41
+
42
+ - name: Setup Pages
43
+ id: pages
44
+ uses: actions/configure-pages@v5
45
+
46
+ - name: Build with Jekyll
47
+ run: bundle exec jekyll build --verbose --trace --baseurl "${{ steps.pages.outputs.base_path }}"
48
+ working-directory: docs
49
+ env:
50
+ JEKYLL_ENV: production
51
+ JEKYLL_LOG_LEVEL: debug
52
+
53
+ - name: Upload artifact
54
+ uses: actions/upload-pages-artifact@v4
55
+ with:
56
+ path: docs/_site
57
+
58
+ # Deployment job
59
+ deploy:
60
+ environment:
61
+ name: github-pages
62
+ url: ${{ steps.deployment.outputs.page_url }}
63
+ if: ${{ github.ref == 'refs/heads/main' }}
64
+ runs-on: ubuntu-latest
65
+ needs: build
66
+ steps:
67
+ - name: Deploy to GitHub Pages
68
+ id: deployment
69
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,94 @@
1
+ name: Link Checker
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - 'docs/**'
9
+ pull_request:
10
+ paths:
11
+ - 'docs/**'
12
+ schedule:
13
+ # Run weekly on Sunday at 00:00 UTC
14
+ - cron: '0 0 * * 0'
15
+ workflow_dispatch:
16
+
17
+ jobs:
18
+ link_checker:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - name: Setup Ruby
24
+ uses: ruby/setup-ruby@v1
25
+ with:
26
+ ruby-version: '3.4'
27
+ bundler-cache: true
28
+ working-directory: docs
29
+
30
+ - name: Build site
31
+ env:
32
+ JEKYLL_ENV: production
33
+ run: bundle exec jekyll build --trace
34
+ working-directory: docs
35
+
36
+ - name: Restore lychee cache
37
+ uses: actions/cache@v4
38
+ with:
39
+ path: .lycheecache
40
+ key: cache-lychee-${{ github.sha }}
41
+ restore-keys: cache-lychee-
42
+
43
+ - name: Check if site was built
44
+ run: |
45
+ if [ ! -d "_site" ]; then
46
+ echo "Error: _site directory not created"
47
+ exit 1
48
+ fi
49
+ echo "Site built successfully"
50
+ ls -la _site/
51
+ working-directory: docs
52
+
53
+ - name: Link Checker
54
+ uses: lycheeverse/lychee-action@v2
55
+ with:
56
+ args: >-
57
+ --verbose
58
+ --no-progress
59
+ --config docs/lychee.toml
60
+ --root-dir "$(pwd)/docs/_site"
61
+ --base-url file://${{ github.workspace }}/docs/_site
62
+ 'docs/_site/**/*.html'
63
+ fail: true
64
+ output: link-check-results.md
65
+ format: markdown
66
+ workingDirectory: .
67
+
68
+ - name: Upload link check results
69
+ if: always()
70
+ uses: actions/upload-artifact@v4
71
+ with:
72
+ name: link-check-results
73
+ path: link-check-results.md
74
+ retention-days: 30
75
+
76
+ - name: Comment PR with results
77
+ if: failure() && github.event_name == 'pull_request'
78
+ uses: actions/github-script@v7
79
+ with:
80
+ script: |
81
+ const fs = require('fs');
82
+ let comment = '## 🔗 Link Check Failed\n\n';
83
+
84
+ if (fs.existsSync('link-check-results.md')) {
85
+ const results = fs.readFileSync('link-check-results.md', 'utf8');
86
+ comment += '### Results\n\n' + results + '\n\n';
87
+ }
88
+
89
+ github.rest.issues.createComment({
90
+ issue_number: context.issue.number,
91
+ owner: context.repo.owner,
92
+ repo: context.repo.repo,
93
+ body: comment
94
+ });
@@ -13,13 +13,6 @@ concurrency:
13
13
  group: '${{ github.workflow }}-${{ github.job }}-${{ github.head_ref || github.ref_name }}'
14
14
  cancel-in-progress: true
15
15
 
16
- env:
17
- # Forcing bundler version to ensure that it is consistent everywhere and
18
- # does not cause bundler gem reinstalls
19
- # bundler/rubygems 2.3.22 is a minimal requirement to support gnu/musl differentiation
20
- # https://github.com/rubygems/rubygems/pull/4488
21
- BUNDLER_VER: latest
22
-
23
16
  jobs:
24
17
  prepare:
25
18
  uses: metanorma/ci/.github/workflows/prepare-rake.yml@main
@@ -38,11 +31,11 @@ jobs:
38
31
  matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
39
32
 
40
33
  steps:
41
- - uses: actions/checkout@v4
34
+ - uses: actions/checkout@v6
42
35
  with:
43
36
  repository: metanorma/metanorma
44
37
 
45
- - uses: actions/checkout@v4
38
+ - uses: actions/checkout@v6
46
39
  with:
47
40
  path: "excavate"
48
41
 
@@ -52,7 +45,6 @@ jobs:
52
45
  with:
53
46
  ruby-version: ${{ matrix.ruby.version }}
54
47
  rubygems: ${{ matrix.ruby.rubygems }}
55
- bundler: ${{ env.BUNDLER_VER }}
56
48
  bundler-cache: true
57
49
 
58
50
  - uses: metanorma/metanorma-build-scripts/inkscape-setup-action@main
@@ -1,81 +1,15 @@
1
1
  name: rake
2
2
 
3
3
  permissions:
4
- contents: read
4
+ contents: write
5
5
 
6
6
  on:
7
7
  push:
8
8
  branches: [ main ]
9
- tags: [ 'v*' ]
10
- paths-ignore:
11
- - '**.adoc'
9
+ tags: [ v* ]
12
10
  pull_request:
13
- paths-ignore:
14
- - '**.adoc'
15
-
16
- concurrency:
17
- group: '${{ github.workflow }}-${{ github.job }}-${{ github.head_ref || github.ref_name }}'
18
- cancel-in-progress: true
19
-
20
- env:
21
- BUNDLER_VER: latest
22
- # Forcing bundler version to ensure that it is consistent everywhere and
23
- # does not cause bundler gem reinstalls
24
- # bundler/rubygems 2.3.22 is a minimal requirement to support gnu/musl differentiation
25
- # https://github.com/rubygems/rubygems/pull/4488
26
- GOOGLE_FONTS_API_KEY: ${{secrets.FONTIST_CI_GOOGLE_FONTS_API_KEY}}
11
+ workflow_dispatch:
27
12
 
28
13
  jobs:
29
- prepare:
30
- uses: metanorma/ci/.github/workflows/prepare-rake.yml@main
31
-
32
- test:
33
- name: Test on Ruby ${{ matrix.ruby.version }} ${{ matrix.os }}
34
- runs-on: ${{ matrix.os }}
35
-
36
- needs: prepare
37
- if: needs.prepare.outputs.push-for-tag != 'true'
38
-
39
- continue-on-error: ${{ matrix.ruby.experimental }}
40
- strategy:
41
- fail-fast: false
42
- max-parallel: 5
43
- matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
44
-
45
- steps:
46
- - uses: actions/checkout@v4
47
-
48
- - uses: ruby/setup-ruby@v1
49
- with:
50
- ruby-version: ${{ matrix.ruby.version }}
51
- rubygems: ${{ matrix.ruby.rubygems }}
52
- bundler: ${{ env.BUNDLER_VER }}
53
- bundler-cache: true
54
-
55
- - run: bundle exec rake
56
-
57
- archlinux-test:
58
- name: Test on Arch Linux
59
- needs: prepare
60
- runs-on: ubuntu-latest
61
- container:
62
- image: 'archlinux:latest'
63
- env:
64
- CI: true
65
-
66
- steps:
67
- - name: Setup packages
68
- run: pacman -Syu --noconfirm git binutils gcc autoconf make libffi libyaml gmp
69
-
70
- - uses: actions/checkout@v4
71
-
72
- - uses: asdf-vm/actions/install@v3
73
- with:
74
- tool_versions: ruby ${{ needs.prepare.outputs.default-ruby-version }}
75
-
76
- - run: |
77
- gem install bundler
78
- bundle install
79
-
80
- - name: Test
81
- run: bundle exec rake
14
+ rake:
15
+ uses: metanorma/ci/.github/workflows/generic-rake.yml@main
@@ -1,3 +1,5 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
1
3
  name: release
2
4
 
3
5
  permissions:
@@ -10,17 +12,17 @@ on:
10
12
  inputs:
11
13
  next_version:
12
14
  description: |
13
- Next release version. Possible values: x.y.z, major, minor, patch (or pre|rc|etc).
14
- Also, you can pass 'skip' to skip 'git tag' and do 'gem push' for the current version
15
+ Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
15
16
  required: true
16
- default: 'skip'
17
+ default: "skip"
17
18
  repository_dispatch:
18
- types: [ do-release ]
19
+ types: [do-release]
19
20
 
20
21
  jobs:
21
22
  release:
22
- uses: fontist/support/.github/workflows/release.yml@main
23
+ uses: metanorma/ci/.github/workflows/rubygems-release.yml@main
23
24
  with:
24
25
  next_version: ${{ github.event.inputs.next_version }}
25
26
  secrets:
26
- rubygems-api-key: ${{ secrets.FONTIST_CI_RUBYGEMS_API_KEY }}
27
+ rubygems-api-key: ${{ secrets.OMNIZIP_CI_RUBYGEMS_API_KEY }}
28
+ pat_token: ${{ secrets.GITHUB_TOKEN }}
data/.gitignore CHANGED
@@ -1,11 +1,33 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /.vscode
4
3
  /_yardoc/
5
4
  /coverage/
6
5
  /doc/
7
6
  /pkg/
8
7
  /spec/reports/
9
8
  /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ # Ruby temporary files
14
+ *.swp
15
+ *.tmp
16
+ *.log
17
+ .DS_Store
18
+ .rubocop-https*
10
19
  Gemfile.lock
11
- .rubocop-*
20
+
21
+ # IDE files
22
+ .idea/
23
+ .vscode/
24
+ *.iml
25
+
26
+ # Build artifacts
27
+ docs/_site/
28
+ .jekyll-cache
29
+ .kilocode
30
+
31
+ # Temporary development files at root level (patterns)
32
+ TODO*.md
33
+ CLAUDE.md
data/.rubocop_todo.yml CHANGED
@@ -1,29 +1,35 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2025-11-08 05:21:43 UTC using RuboCop version 1.81.7.
3
+ # on 2026-02-25 10:37:11 UTC using RuboCop version 1.84.2.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
9
  # Offense count: 1
10
- # Configuration parameters: Severity.
11
10
  Gemspec/RequiredRubyVersion:
12
11
  Exclude:
13
12
  - 'excavate.gemspec'
14
13
 
15
- # Offense count: 8
14
+ # Offense count: 1
15
+ # This cop supports safe autocorrection (--autocorrect).
16
+ # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
17
+ # SupportedStylesAlignWith: start_of_line, relative_to_receiver
18
+ Layout/IndentationWidth:
19
+ Exclude:
20
+ - 'spec/excavate/archive_spec.rb'
21
+
22
+ # Offense count: 7
16
23
  # This cop supports safe autocorrection (--autocorrect).
17
- # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
24
+ # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
18
25
  # URISchemes: http, https
19
26
  Layout/LineLength:
20
27
  Exclude:
21
28
  - 'bin/rspec'
22
29
  - 'excavate.gemspec'
23
30
  - 'lib/excavate/extractors/rpm_extractor.rb'
24
- - 'lib/excavate/extractors/xz_extractor.rb'
25
31
  - 'lib/excavate/utils.rb'
26
- - 'spec/excavate/extractors/xz_extractor_spec.rb'
32
+ - 'spec/excavate/archive_spec.rb'
27
33
 
28
34
  # Offense count: 1
29
35
  # Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
@@ -32,17 +38,17 @@ Lint/DuplicateBranch:
32
38
  - 'lib/excavate/utils.rb'
33
39
 
34
40
  # Offense count: 1
41
+ # This cop supports safe autocorrection (--autocorrect).
42
+ Lint/ScriptPermission:
43
+ Exclude:
44
+ - 'scripts/create_multi_nested_fixture.rb'
45
+
46
+ # Offense count: 5
35
47
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
36
48
  Metrics/MethodLength:
37
49
  Max: 15
38
50
 
39
- # Offense count: 1
40
- # This cop supports safe autocorrection (--autocorrect).
41
- Performance/RegexpMatch:
42
- Exclude:
43
- - 'lib/excavate/utils.rb'
44
-
45
- # Offense count: 42
51
+ # Offense count: 46
46
52
  # Configuration parameters: Prefixes, AllowedPatterns.
47
53
  # Prefixes: when, with, without
48
54
  RSpec/ContextWording:
@@ -51,18 +57,12 @@ RSpec/ContextWording:
51
57
  - 'spec/excavate/cli_spec.rb'
52
58
  - 'spec/support/fresh_work_dir.rb'
53
59
 
54
- # Offense count: 9
60
+ # Offense count: 11
55
61
  # Configuration parameters: CountAsOne.
56
62
  RSpec/ExampleLength:
57
- Max: 7
58
-
59
- # Offense count: 1
60
- # Configuration parameters: .
61
- # SupportedStyles: have_received, receive
62
- RSpec/MessageSpies:
63
- EnforcedStyle: receive
63
+ Max: 16
64
64
 
65
- # Offense count: 10
65
+ # Offense count: 18
66
66
  RSpec/MultipleExpectations:
67
67
  Max: 2
68
68
 
data/README.adoc CHANGED
@@ -1,8 +1,28 @@
1
1
  = Excavate: Extraction of nested archives
2
2
 
3
3
  image:https://img.shields.io/gem/v/excavate.svg["Gem Version", link="https://rubygems.org/gems/excavate"]
4
- image:https://codeclimate.com/github/fontist/excavate/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/fontist/excavate"]
5
- image:https://github.com/fontist/excavate/workflows/rake/badge.svg["Build Status", link="https://github.com/fontist/excavate/actions?workflow=rake"]
4
+ image:https://img.shields.io/github/license/omnizip/excavate.svg[License]
5
+ image:https://github.com/omnizip/excavate/workflows/rake/badge.svg["Build Status", link="https://github.com/omnizip/excavate/actions?workflow=rake"]
6
+
7
+ **Part of the Omnizip Suite** -- https://omnizip.github.io[Pure Ruby compression libraries]
8
+
9
+ **As of version 0.3.9, Excavate is a 100% pure Ruby gem with no compiled
10
+ dependencies.**
11
+
12
+ This means:
13
+
14
+ * **Cross-platform compatibility**: Works identically on MRI, JRuby, and
15
+ TruffleRuby without any native compilation
16
+ * **Simplified installation**: No need for system libraries, C compilers, or
17
+ development headers
18
+ * **Improved security**: Reduced attack surface with no native code dependencies
19
+ * **Consistent behavior**: Same implementation across all operating systems
20
+ (Linux, macOS, Windows, BSD)
21
+
22
+ The migration to pure Ruby was achieved by replacing native library dependencies
23
+ with the https://github.com/omnizip/omnizip[Omnizip] and
24
+ https://github.com/omnizip/cabriolet[Cabriolet] gems, which provide pure Ruby
25
+ implementations of compression algorithms and archive formats.
6
26
 
7
27
  == Purpose
8
28
 
@@ -509,15 +529,35 @@ the command-line interface.
509
529
 
510
530
  == Dependencies
511
531
 
512
- Excavate depends on the following system libraries through the
513
- https://github.com/fontist/ffi-libarchive-binary[ffi-libarchive-binary] gem:
532
+ Excavate is a pure Ruby gem with no compiled dependencies. It works on all
533
+ major Ruby platforms including MRI, JRuby, and TruffleRuby without requiring
534
+ any native extensions or system libraries.
535
+
536
+ === Pure Ruby benefits
537
+
538
+ The migration to pure Ruby implementations provides several important benefits:
539
+
540
+ * **Cross-platform compatibility**: Works seamlessly across macOS, Linux,
541
+ Windows, and BSD without platform-specific compilation.
542
+ * **Simplified installation**: No need for C compilers, development headers, or
543
+ system libraries. Just `gem install excavate` works everywhere.
544
+ * **Consistent behavior**: Same implementation and behavior across all Ruby
545
+ interpreters (MRI, JRuby, TruffleRuby).
546
+ * **Reduced attack surface**: Fewer native dependencies means fewer potential
547
+ security vulnerabilities from system libraries.
548
+ * **Easier containerization**: Smaller Docker images without build tools and
549
+ development packages.
550
+
551
+ === Ruby dependencies
514
552
 
515
- * zlib
516
- * Expat
517
- * OpenSSL (for Linux only)
553
+ Excavate relies on the following pure Ruby gems:
518
554
 
519
- These dependencies are generally present on all systems and require no special
520
- installation steps.
555
+ * https://github.com/omnizip/omnizip[omnizip]: Pure Ruby implementations of
556
+ ZIP, 7-Zip, TAR, GZIP, XZ, and CPIO formats (based on 7-Zip LZMA SDK).
557
+ * https://github.com/fontist/cabriolet[cabriolet]: Pure Ruby implementation of
558
+ Microsoft CAB format.
559
+ * https://github.com/djberg96/arr-pm[arr-pm]: Pure Ruby RPM package handling.
560
+ * https://github.com/ironbishop/ruby-ole[ruby-ole]: Pure Ruby OLE/MSI handling.
521
561
 
522
562
  == Development
523
563
 
@@ -574,7 +614,7 @@ copyright covering the contribution to use the contribution by all means.
574
614
 
575
615
  Here are a few technical guidelines to follow:
576
616
 
577
- . Open an https://github.com/fontist/excavate/issues[issue] to discuss a new
617
+ . Open an https://github.com/omnizip/excavate/issues[issue] to discuss a new
578
618
  feature.
579
619
  . Write tests to support your new feature.
580
620
  . Make sure the entire test suite passes locally and on CI.
data/docs/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "jekyll", "~> 4.3"
4
+ gem "jekyll-asciidoc", "~> 3.0"
5
+ gem "jekyll-remote-theme", "~> 0.4"
6
+ gem "jekyll-seo-tag", "~> 2.8"
7
+
8
+ group :jekyll_plugins do
9
+ gem "just-the-docs", "~> 0.10"
10
+ end
11
+
12
+ gem "webrick", "~> 1.8"
data/docs/_config.yml ADDED
@@ -0,0 +1,108 @@
1
+ title: "Excavate documentation"
2
+ description: Recursive archive extraction for Ruby - extract nested archives with a single command. Pure Ruby library built on Omnizip and Cabriolet.
3
+ url: https://omnizip.github.io
4
+ baseurl: /excavate
5
+
6
+ theme: just-the-docs
7
+ remote_theme: just-the-docs/just-the-docs
8
+
9
+ # AsciiDoc support
10
+ asciidoc: {}
11
+ asciidoctor:
12
+ attributes:
13
+ - idprefix=_
14
+ - source-highlighter=rouge
15
+ - icons=font
16
+ - experimental=''
17
+
18
+ plugins:
19
+ - jekyll-asciidoc
20
+ - jekyll-seo-tag
21
+
22
+ # Search configuration
23
+ search_enabled: true
24
+ search:
25
+ heading_level: 3
26
+ previews: 3
27
+ preview_words_before: 5
28
+ preview_words_after: 10
29
+ tokenizer_separator: /[\s/]+/
30
+ button: true
31
+
32
+ # Enable copy button for code snippets
33
+ enable_copy_code_button: true
34
+
35
+ # Navigation
36
+ nav_sort: case_insensitive
37
+
38
+ # Footer
39
+ footer_content: 'Copyright © 2025 Ribose Inc.'
40
+
41
+ # Color scheme - supports dark mode toggle
42
+ color_scheme: light
43
+
44
+ # Enable dark mode toggle
45
+ color_schemes:
46
+ light:
47
+ name: Light
48
+ dark:
49
+ name: Dark
50
+
51
+ # Allow users to toggle between themes
52
+ color_scheme_toggle:
53
+ enabled: true
54
+
55
+ # Logo
56
+ logo: "/assets/logo.svg"
57
+
58
+ # Auxiliary links
59
+ aux_links:
60
+ "Excavate on GitHub":
61
+ - "https://github.com/omnizip/excavate"
62
+ "Report Issue":
63
+ - "https://github.com/omnizip/excavate/issues"
64
+
65
+ aux_links_new_tab: true
66
+
67
+ # Heading anchors
68
+ heading_anchors: true
69
+
70
+ # Back to top
71
+ back_to_top: true
72
+ back_to_top_text: "Back to top"
73
+
74
+ # Last modified timestamps
75
+ last_edit_timestamp: true
76
+ last_edit_time_format: "%b %e %Y at %I:%M %p"
77
+
78
+ # Edit on GitHub links
79
+ gh_edit_link: true
80
+ gh_edit_link_text: "Edit this page on GitHub"
81
+ gh_edit_repository: "https://github.com/omnizip/excavate"
82
+ gh_edit_branch: "main"
83
+ gh_edit_source: docs
84
+ gh_edit_view_mode: "edit"
85
+
86
+ # Defaults
87
+ defaults:
88
+ - scope:
89
+ path: ""
90
+ type: "pages"
91
+ values:
92
+ layout: "default"
93
+ nav_exclude: false
94
+
95
+ # Include files
96
+ include:
97
+ - "*.adoc"
98
+ - "_diagrams"
99
+ - "assets"
100
+
101
+ # Exclude files
102
+ exclude:
103
+ - Gemfile
104
+ - Gemfile.lock
105
+ - README.md
106
+
107
+ # Permalink structure
108
+ permalink: pretty
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="UTF-8"?><svg id="uuid-7b7046ac-4320-4058-bfcd-7c7cb3f60760" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2059.26 524.56"><path d="M202.48,303.14c37.2,3.8,86.8,4,124,0l-61,156c-.7.6-.5,2.9-1.5,3-2.1.2-2.5-2.3-3.5-3l-60-156c.6,0,1.3-.1,2,0Z" style="fill:#b7404c;"/><path d="M375.48,195.14c8.6,4.4,15.4,6.2,23,12,.3.2,2.7-.2,3.4,1l42.6,58-83.5-32c4.9,11.2,44.3,45.6,46.5,53,.1.3-.1.7,0,1-26.5,4.4-54.3,12.2-81,15-37.2,4-86.8,3.8-124,0l60-55h3c7.1,6.1,57.5,55.2,61.4,54,3.6-1.1,26.6-62,31.7-69.3l39.9-25.6c-10.7-.4-20.7-3.3-31-6-1.6-6.4,7.5.1,8-6.1Z" style="fill:#c5505c;"/><path d="M199.48,303.14h1l60,156c-4.8-3.6-12.9-13.1-17-18-7.3-8.9-13.6-19.4-21-28.5-33.8-41.3-69.3-81.3-102-123.5,26.3,2.3,52.9,11.1,79,14Z" style="fill:#a6343e;"/><path d="M407.48,288.14c-39.8,50.5-82.3,98.9-123.1,148.5-1.3,1.6.2,2.4.1,2.5-5.7,6.9-12.1,14.4-19,20l61-156c26.7-2.9,54.4-10.6,81-15Z" style="fill:#a6343e;"/><path d="M155.48,193.14c5.1,1.7,5.6,2.4,5,8-10,2.7-23.7,3.3-32,6,.7,3.4,34.8,20.6,39,25.5l32,70.5c-26-2.9-52.7-11.7-79-14,.1-.6-.1-1.4,0-2,1.7-7.5,40.7-42.2,45.5-53l-82.5,32v-1c2.4-5,38.6-55,41.6-57,1.7-1.1,2.3-.6,3.4-1-.5-2.5,23.1-12.1,27-14Z" style="fill:#c5505c;"/><path d="M83.48,266.14c10.4,8.6,24,17.3,37,21-.1.6.1,1.4,0,2,32.7,42.2,68.1,82.2,102,123.5,7.4,9,13.7,19.6,21,28.5l-162-173c-.5-2.4,1.7-2.5,2-3v1h0Z" style="fill:#c44d5a;"/><path d="M443.48,268.14c-5.6,11.7-44.2,49.7-55.5,62-33.9,36.8-68.9,72.8-103.5,109,.1-.1-1.5-.9-.1-2.5,40.8-49.7,83.3-98,123.1-148.5-.1-.3.1-.7,0-1l36-19Z" style="fill:#c44d5a;"/><path d="M444.48,266.14v1c-.1.3-.8.6-1,1l-36,19c-2.2-7.4-41.7-41.8-46.5-53l83.5,32Z" style="fill:#a6343e;"/><path d="M375.48,195.14c-.4,6.3-9.5-.3-8,6-17-4.5-33-10.6-50-15,1-1.9,4.3-8.4,6-9,11.7-3.9,40.9,12.4,52,18Z" style="fill:#c44d5a;"/><path d="M203.48,177.14c.3-.1.7,0,1,0,1.7,3.3,3.4,6.7,5,10-16.9,2.7-32.5,9.6-49,14,.6-5.6.1-6.3-5-8,21.1-10.3,24.4-12.2,48-16Z" style="fill:#c44d5a;"/><path d="M323.48,176.14v1c-1.7.6-5,7.1-6,9-.3.7-.7,1.3-1,2-.3-.1-.7.1-1,0-8.3-1.7-18.6-3.6-27-4,.3-3.7,1.1-7.4,2-11l33,3Z" style="fill:#d6616e;"/><path d="M444.48,267.14v-1c1.9.7,0,.7,0,1Z" style="fill:#c44d5a;"/><path d="M245.48,172.14h-9c.1.3-.1.7,0,1-10.8.2-21.4,2.4-32,4,1.7,3.3,3.4,6.7,5,10,.2.3.8.6,1,1,.3-.1.7.1,1,0,8.9-1.7,18-3.2,27-4h1c2.5-.2,5-.9,7-1l-1-11Z" style="fill:#d6616e;"/><path d="M290.48,172.14h-45l1,11h1c10.9-.6,22.1.4,33,0-.1.3.1.7,0,1h8c.3-3.7,1.1-7.4,2-11,.1-.3-.1-.7,0-1Z" style="fill:#c44d5a;"/><path d="M209.48,187.14c.2.3.8.6,1,1-5.7,1.1-11.9,2.1-17,5-7.6.4-25.9,10.3-29,17.5-8.5,19.2,22,27.1,35,30.5,15.3,4,30.2,6.1,46,7,2.6.1,5.3-.1,8,0,1.7.1,3.3,0,5,0h4l-60,55c-.7-.1-1.3.1-2,0h-1l-32-70.5c-4.2-4.9-38.3-22.1-39-25.5,8.3-2.7,22-3.3,32-6,16.5-4.4,32-11.3,49-14Z" style="fill:#d5616e;"/><path d="M367.48,201.14c10.3,2.7,20.3,5.6,31,6l-39.9,25.6c-5.1,7.4-28.1,68.2-31.7,69.3-3.9,1.2-54.4-47.9-61.4-54h7c3-.1,6,.2,9,0,15.8-.9,30.7-3,46-7,49.9-13.2,47.9-36.1,0-50-3.8-1.1-7.1-2.2-11-3,.3-.7.7-1.3,1-2,16.9,4.5,33,10.6,50,15.1Z" style="fill:#d6616e;"/><path d="M120.48,287.14c-13-3.7-26.6-12.4-37-21l82.5-32c-4.8,10.8-43.9,45.4-45.5,53Z" style="fill:#a6343e;"/><path d="M316.48,188.14c-.3-.1-.7.1-1,0-8.3-1.7-18.6-3.6-27-4h-1l-15,64c3-.1,6,.2,9,0,15.8-.9,30.7-3,46-7v-50c-3.8-1.1-7.1-2.2-11-3Z" style="fill:#381d25;"/><path d="M247.48,183.14h-1c-2,.1-4.5.8-7,1h-1c-9,.8-18.1,2.3-27,4l34,60c2.6.1,5.3-.1,8,0,1.7.1,3.3,0,5,0l-11-65Z" style="fill:#381d25;"/><path d="M280.48,184.14c.1-.3-.1-.7,0-1-10.9.4-22.1-.6-33,0l11,65h14l15-64h-7Z" style="fill:#44202a;"/><path d="M210.48,188.14c.3-.1.7.1,1,0l34,60c-15.8-.9-30.7-3-46-7-.7-6.2,1.3-46-1-48-.2-.2-4.3,0-5,0,5.1-3,11.3-3.9,17-5Z" style="fill:#381d25;"/><path d="M193.48,193.14c.7,0,4.8-.2,5,0,2.3,2,.3,41.8,1,48-13-3.4-43.6-11.4-35-30.5,3.1-7.2,21.4-17.1,29-17.5Z" style="fill:#44202a;"/><path d="M327.48,241.14v-50c47.9,13.9,49.9,36.8,0,50Z" style="fill:#44202a;"/><path d="M281.88,197.44c10.2-38.2,19.4-76.5,29-114.8h-96l29,114.8h1l1,7.3h1l11,43.4h10c3.8-14.3,8.1-28.5,12-42.7.1-.2-.1-.5,0-.7.7-2.4,1.3-4.9,2-7.3Z" style="fill:#f2a764; isolation:isolate; opacity:.74;"/><path d="M328.88,82.64c-11.4,38.5-24.9,76.7-39,114.8-.1.2.1.5,0,.7-.9,2.4-1.7,4.9-2,7.3h-1l-15,42.7c3-.1,6,.1,9,0l34-40h1c.3-.4.7-.9,1-1.3,1-1.3,4.3-5.6,6-6v-.7l106-117.5h-100Z" style="fill:#b274e2; isolation:isolate; opacity:.74;"/><path d="M238.88,205.44h-1c.2-2.5-1.1-4.9-2-7.3-.1-.2.1-.5,0-.7-14.6-38-27.3-76.3-39-114.8h-100l106,118.1h1c1.7,2.2,3.4,4.4,5,6.7.2.2.8.4,1,.7h1l34,40c2.6.1,5.3-.1,8,0l-14-42.7Z" style="fill:#58bab7; isolation:isolate; opacity:.74;"/><g style="isolation:isolate;"><path d="M563.12,244.31c18.62-18.24,41.04-27.36,67.26-27.36s48.64,9.12,67.26,27.36,27.74,40.66,27.74,66.88-9.12,48.64-27.74,67.26c-18.62,18.24-41.04,27.36-67.26,27.36s-48.64-9.12-67.26-27.36c-18.24-18.62-27.36-41.04-27.36-67.26s9.12-49.02,27.36-66.88ZM585.54,265.21c-12.54,12.92-18.62,28.12-18.62,45.98s6.08,33.06,18.24,46.36c12.54,12.92,27.36,19.38,45.22,19.38s33.06-6.46,45.22-19.38c12.54-13.3,18.62-28.5,18.62-46.36s-6.08-33.06-18.62-45.98c-12.16-12.92-27.36-19.38-45.22-19.38s-32.3,6.46-44.84,19.38Z" style="fill:#c5505c;"/><path d="M920.32,268.25v133.76h-33.82v-113.24c0-28.5-9.88-42.56-34.58-42.56-15.2,0-33.44,10.26-42.18,18.24l-6.46,6.46v131.1h-34.2v-181.64h31.92l1.52,19.38c1.9-1.9,4.18-3.8,7.6-6.46,3.42-2.66,10.26-5.7,19.76-9.88,9.5-4.18,19-6.46,27.74-6.46,28.88,0,44.46,15.58,48.64,21.66l1.9,2.66c1.9-1.9,4.94-3.8,8.74-6.46,4.18-2.66,11.78-6.46,22.8-11.02,11.02-4.56,22.04-6.84,32.68-6.84,42.56,0,64.6,29.26,64.6,70.68v114.38h-33.82v-109.44c0-30.78-12.16-46.36-36.48-46.36-15.2,0-32.68,9.12-40.66,16.72l-5.7,5.32Z" style="fill:#c5505c;"/><path d="M1255.09,402.01h-33.82v-108.68c0-30.02-16.72-47.12-41.42-47.12-20.14,0-41.04,10.64-49.02,19.38l-6.46,6.46v129.96h-34.2v-181.64h31.92l1.52,19.76c1.9-1.9,4.18-3.8,7.6-6.46s10.26-6.08,20.9-10.26c11.02-4.18,22.04-6.46,33.44-6.46,21.66,0,38.38,6.84,50.92,20.9,12.54,13.68,18.62,30.78,18.62,50.92v113.24Z" style="fill:#c5505c;"/><path d="M1310.18,185.03v-36.48h36.48v36.48h-36.48ZM1310.94,220.37h34.96v181.64h-34.96v-181.64Z" style="fill:#c5505c;"/><path d="M1544.27,373.13v28.88h-155.8l108.3-152.76h-95.38v-28.88h151.24l-107.54,152.76h99.18Z" style="fill:#c5505c;"/><path d="M1594.42,185.03v-36.48h36.48v36.48h-36.48ZM1595.18,220.37h34.96v181.64h-34.96v-181.64Z" style="fill:#c5505c;"/><path d="M1689.8,478.01V220.37h31.54l1.52,22.8c1.14-1.52,1.9-3.04,9.12-9.12,9.88-7.98,25.46-17.48,49.4-17.48s44.08,9.12,60.42,27.36c16.34,18.24,24.7,40.66,24.7,67.26s-8.36,49.02-24.7,67.26c-16.34,18.24-36.48,27.36-60.42,27.36-31.16,0-50.54-15.96-55.48-22.8l-2.28-2.66v97.66h-33.82ZM1818.24,357.55c11.02-12.54,16.34-28.12,16.34-46.36s-5.32-33.44-16.34-45.98c-10.64-12.92-24.7-19.38-42.18-19.38-21.28,0-40.66,12.16-47.12,22.42l-5.32,7.22v71.44c1.14,1.52,1.9,3.42,8.36,10.64,8.36,8.36,23.56,19,43.7,19,17.48,0,31.54-6.46,42.56-19Z" style="fill:#c5505c;"/></g></svg>