git-ripper 1.4.1 → 1.4.2

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.
package/README.md CHANGED
@@ -5,8 +5,12 @@
5
5
  [![NPM version](https://img.shields.io/npm/v/git-ripper.svg)](https://www.npmjs.com/package/git-ripper)
6
6
  [![License](https://img.shields.io/npm/l/git-ripper.svg)](https://github.com/sairajB/git-ripper/blob/main/LICENSE)
7
7
  [![Downloads](https://img.shields.io/npm/dt/git-ripper.svg?style=flat&label=total%20downloads)](https://www.npmjs.com/package/git-ripper)
8
+ [![Weekly Downloads](https://img.shields.io/npm/dw/git-ripper.svg)](https://www.npmjs.com/package/git-ripper)
9
+ [![Bundle Size](https://img.shields.io/bundlephobia/min/git-ripper.svg)](https://bundlephobia.com/package/git-ripper)
8
10
  [![GitHub issues](https://img.shields.io/github/issues/sairajB/git-ripper.svg)](https://github.com/sairajB/git-ripper/issues)
9
11
  [![GitHub stars](https://img.shields.io/github/stars/sairajB/git-ripper.svg)](https://github.com/sairajB/git-ripper/stargazers)
12
+ [![GitHub forks](https://img.shields.io/github/forks/sairajB/git-ripper.svg)](https://github.com/sairajB/git-ripper/network)
13
+ [![Maintenance](https://img.shields.io/maintenance/yes/2025.svg)](https://github.com/sairajB/git-ripper/commits/master)
10
14
 
11
15
  **Download specific folders from GitHub repositories without cloning the entire codebase**
12
16
 
@@ -25,19 +29,34 @@
25
29
 
26
30
  Have you ever needed just a single component from a massive repository? Or wanted to reference a specific configuration directory without downloading gigabytes of code? Git-ripper solves this problem by letting you extract and download only the folders you need, saving bandwidth, time, and disk space.
27
31
 
32
+ ## Project Stats
33
+
34
+ Git-ripper has grown to become a trusted tool in the developer ecosystem:
35
+
36
+ - **Total Downloads**: Thousands of developers worldwide have downloaded Git-ripper to optimize their workflow and save time when working with large repositories.
37
+ - **Weekly Active Users**: Our weekly download statistics show consistent adoption and usage among developers, indicating the tool's reliability and usefulness.
38
+ - **Minimal Bundle Size**: Git-ripper is designed to be lightweight and efficient, with a minimal bundle size that ensures quick installation and minimal impact on your system resources.
39
+ - **Active Maintenance**: The project is actively maintained with regular updates and improvements, ensuring compatibility with the latest GitHub API changes and addressing user feedback.
40
+ - **Community Support**: With growing stars and forks on GitHub, Git-ripper has built a supportive community of users who contribute to its ongoing development and share their success stories.
41
+ - **Enterprise Adoption**: Used by teams in various organizations, from startups to large enterprises, Git-ripper helps development teams streamline their workflows when working with modular components from large codebases.
42
+
28
43
  ## Features
29
44
 
30
45
  - **Selective Downloads**: Fetch specific folders instead of entire repositories
31
46
  - **Directory Structure**: Preserves complete folder structure
32
47
  - **Custom Output**: Specify your preferred output directory
33
48
  - **Branch Support**: Works with any branch, not just the default one
34
- - **Archive Export**: Create ZIP or TAR archives of downloaded content
49
+ - **Archive Export**: Create ZIP archives of downloaded content
35
50
  - **Simple Interface**: Clean, intuitive command-line experience
36
51
  - **Lightweight**: Minimal dependencies and fast execution
37
52
  - **No Authentication**: Works with public repositories without requiring credentials
38
53
 
39
54
  ## Installation
40
55
 
56
+ ### Requirements
57
+
58
+ Git-ripper requires Node.js >=16.0.0 due to its use of modern JavaScript features and built-in Node.js modules.
59
+
41
60
  ### Global Installation (Recommended)
42
61
 
43
62
  ```bash
@@ -74,22 +93,20 @@ git-ripper https://github.com/username/repository/tree/branch/folder -o ./my-out
74
93
  git-ripper https://github.com/username/repository/tree/branch/folder --zip
75
94
  ```
76
95
 
77
- ### Creating TAR Archive with Custom Name
96
+ ### Creating ZIP Archive with Custom Name
78
97
 
79
98
  ```bash
80
- git-ripper https://github.com/username/repository/tree/branch/folder --tar="my-archive.tar"
99
+ git-ripper https://github.com/username/repository/tree/branch/folder --zip="my-archive.zip"
81
100
  ```
82
101
 
83
102
  ### Command Line Options
84
103
 
85
- | Option | Description | Default |
86
- |--------|-------------|---------|
87
- | `-o, --output <directory>` | Specify output directory | Current directory |
88
- | `--zip [filename]` | Create ZIP archive of downloaded content | - |
89
- | `--tar [filename]` | Create TAR archive of downloaded content | - |
90
- | `--compression-level <level>` | Set compression level (1-9) | 6 |
91
- | `-V, --version` | Show version number | - |
92
- | `-h, --help` | Show help | - |
104
+ | Option | Description | Default |
105
+ | -------------------------- | ---------------------------------------- | ----------------- |
106
+ | `-o, --output <directory>` | Specify output directory | Current directory |
107
+ | `--zip [filename]` | Create ZIP archive of downloaded content | - |
108
+ | `-V, --version` | Show version number | - |
109
+ | `-h, --help` | Show help | - |
93
110
 
94
111
  ## Examples
95
112
 
@@ -127,8 +144,8 @@ git-ripper https://github.com/tailwindlabs/tailwindcss/tree/master/src/component
127
144
  # Download React DOM package and create a ZIP archive
128
145
  git-ripper https://github.com/facebook/react/tree/main/packages/react-dom --zip
129
146
 
130
- # Extract VS Code build configuration with maximum compression
131
- git-ripper https://github.com/microsoft/vscode/tree/main/build --tar --compression-level=9
147
+ # Extract VS Code build configuration with custom archive name
148
+ git-ripper https://github.com/microsoft/vscode/tree/main/build --zip="vscode-build.zip"
132
149
  ```
133
150
 
134
151
  ## How It Works
@@ -184,16 +201,6 @@ Contributions make the open-source community an amazing place to learn, inspire,
184
201
 
185
202
  See the [open issues](https://github.com/sairajB/git-ripper/issues) for a list of proposed features and known issues.
186
203
 
187
- ## Roadmap
188
-
189
- - [x] Add archive export options (ZIP/TAR)
190
- - [ ] Add GitHub token authentication
191
- - [ ] Support for GitLab and Bitbucket repositories
192
- - [ ] Download from specific commits or tags
193
- - [ ] Dry run mode
194
- - [ ] File filtering options
195
- - [ ] CLI interactive mode
196
-
197
204
  ## License
198
205
 
199
206
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
package/package.json CHANGED
@@ -1,60 +1,62 @@
1
1
  {
2
- "name": "git-ripper",
3
- "version": "1.4.1",
4
- "description": "CLI tool that lets you download specific folders from GitHub repositories without cloning the entire repo.",
5
- "main": "src/index.js",
6
- "type": "module",
7
- "bin": {
8
- "git-ripper": "bin/git-ripper.js"
9
- },
10
- "scripts": {
11
- "test": "echo \"Error: no test specified\" && exit 1",
12
- "dev": "node bin/git-ripper.js",
13
- "lint": "eslint ."
14
- },
15
- "keywords": [
16
- "git",
17
- "clone",
18
- "github",
19
- "subfolder",
20
- "repository",
21
- "download",
22
- "partial-clone",
23
- "directory-download",
24
- "folder-download",
25
- "git-utilities",
26
- "github-api",
27
- "monorepo-tools",
28
- "sparse-checkout"
29
- ],
30
- "author": "sairajb",
31
- "license": "MIT",
32
- "dependencies": {
33
- "archiver": "^6.0.1",
34
- "axios": "^1.6.7",
35
- "chalk": "^5.3.0",
36
- "cli-progress": "^3.12.0",
37
- "commander": "^12.0.0",
38
- "p-limit": "^6.2.0",
39
- "pretty-bytes": "^6.1.1"
40
- },
41
- "repository": {
42
- "type": "git",
43
- "url": "git+https://github.com/sairajB/git-ripper.git"
44
- },
45
- "bugs": {
46
- "url": "https://github.com/sairajB/git-ripper/issues"
47
- },
48
- "homepage": "https://github.com/sairajB/git-ripper",
49
- "engines": {
50
- "node": ">=14.0.0"
51
- },
52
- "files": [
53
- "bin/",
54
- "src/",
55
- "LICENSE"
56
- ],
57
- "publishConfig": {
58
- "access": "public"
59
- }
2
+ "name": "git-ripper",
3
+ "version": "1.4.2",
4
+ "description": "CLI tool that lets you download specific folders from GitHub repositories without cloning the entire repo.",
5
+ "main": "src/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "git-ripper": "bin/git-ripper.js"
9
+ },
10
+ "scripts": {
11
+ "test": "echo \"Error: no test specified\" && exit 1",
12
+ "dev": "node bin/git-ripper.js",
13
+ "lint": "eslint ."
14
+ },
15
+ "keywords": [
16
+ "git",
17
+ "clone",
18
+ "github",
19
+ "subfolder",
20
+ "repository",
21
+ "download",
22
+ "partial-clone",
23
+ "directory-download",
24
+ "folder-download",
25
+ "git-utilities",
26
+ "github-api",
27
+ "monorepo-tools",
28
+ "sparse-checkout"
29
+ ],
30
+ "author": "sairajb",
31
+ "license": "MIT",
32
+ "dependencies": {
33
+ "ansi-styles": "^6.2.1",
34
+ "archiver": "^6.0.1",
35
+ "axios": "^1.6.7",
36
+ "chalk": "^5.3.0",
37
+ "cli-progress": "^3.12.0",
38
+ "commander": "^12.0.0",
39
+ "p-limit": "^6.2.0",
40
+ "pretty-bytes": "^6.1.1",
41
+ "supports-color": "^9.3.1"
42
+ },
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/sairajB/git-ripper.git"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/sairajB/git-ripper/issues"
49
+ },
50
+ "homepage": "https://github.com/sairajB/git-ripper",
51
+ "engines": {
52
+ "node": ">=16.0.0"
53
+ },
54
+ "files": [
55
+ "bin/",
56
+ "src/",
57
+ "LICENSE"
58
+ ],
59
+ "publishConfig": {
60
+ "access": "public"
61
+ }
60
62
  }
package/src/archiver.js CHANGED
@@ -46,19 +46,17 @@ const validateArchivePath = (outputPath) => {
46
46
  };
47
47
 
48
48
  /**
49
- * Creates an archive (zip or tar) from a directory
49
+ * Creates a ZIP archive from a directory with standard compression
50
50
  *
51
51
  * @param {string} sourceDir - Source directory to archive
52
52
  * @param {string} outputPath - Path where the archive should be saved
53
- * @param {object} options - Archive options
54
- * @param {string} options.format - Archive format ('zip' or 'tar')
55
- * @param {number} options.compressionLevel - Compression level (0-9, default: 6)
56
53
  * @returns {Promise<string>} - Path to the created archive
57
54
  */
58
- export const createArchive = (sourceDir, outputPath, options = {}) => {
55
+ export const createArchive = (sourceDir, outputPath) => {
59
56
  return new Promise((resolve, reject) => {
60
57
  try {
61
- const { format = "zip", compressionLevel = 6 } = options;
58
+ // Fixed compression level of 5 (balanced between speed and size)
59
+ const compressionLevel = 5;
62
60
 
63
61
  // Validate source directory
64
62
  if (!fs.existsSync(sourceDir)) {
@@ -79,27 +77,11 @@ export const createArchive = (sourceDir, outputPath, options = {}) => {
79
77
 
80
78
  // Create output stream
81
79
  const output = fs.createWriteStream(outputPath);
82
- let archive;
83
-
84
- // Create the appropriate archive type
85
- if (format === "zip") {
86
- archive = archiver("zip", {
87
- zlib: { level: compressionLevel },
88
- });
89
- } else if (format === "tar") {
90
- // Use gzip compression for tar if compressionLevel > 0
91
- if (compressionLevel > 0) {
92
- archive = archiver("tar", {
93
- gzip: true,
94
- gzipOptions: { level: compressionLevel },
95
- });
96
- } else {
97
- // Create a tar archive without gzip compression
98
- archive = archiver("tar");
99
- }
100
- } else {
101
- return reject(new Error(`Unsupported archive format: ${format}`));
102
- }
80
+
81
+ // Create ZIP archive with standard compression
82
+ const archive = archiver("zip", {
83
+ zlib: { level: compressionLevel },
84
+ });
103
85
 
104
86
  // Listen for archive events
105
87
  output.on("close", () => {
@@ -141,28 +123,22 @@ export const createArchive = (sourceDir, outputPath, options = {}) => {
141
123
  };
142
124
 
143
125
  /**
144
- * Downloads folder contents and creates an archive
126
+ * Downloads folder contents and creates a ZIP archive
145
127
  *
146
128
  * @param {object} repoInfo - Repository information object
147
129
  * @param {string} outputDir - Directory where files should be downloaded
148
- * @param {string} archiveFormat - Archive format ('zip' or 'tar')
149
- * @param {string} archiveName - Custom name for the archive file
150
- * @param {number} compressionLevel - Compression level (0-9)
130
+ * @param {string} archiveName - Custom name for the archive file (optional)
151
131
  * @returns {Promise<string>} - Path to the created archive
152
132
  */
153
133
  export const downloadAndArchive = async (
154
134
  repoInfo,
155
135
  outputDir,
156
- archiveFormat = "zip",
157
- archiveName = null,
158
- compressionLevel = 6
136
+ archiveName = null
159
137
  ) => {
160
138
  const { downloadFolder } = await import("./downloader.js");
161
139
 
162
140
  console.log(
163
- chalk.cyan(
164
- `Downloading folder and preparing to create ${archiveFormat.toUpperCase()} archive...`
165
- )
141
+ chalk.cyan(`Downloading folder and preparing to create ZIP archive...`)
166
142
  );
167
143
 
168
144
  // Create a temporary directory for the download
@@ -182,20 +158,15 @@ export const downloadAndArchive = async (
182
158
  }
183
159
 
184
160
  // Add extension if not present
185
- if (!archiveFileName.endsWith(`.${archiveFormat}`)) {
186
- archiveFileName += `.${archiveFormat}`;
161
+ if (!archiveFileName.endsWith(`.zip`)) {
162
+ archiveFileName += `.zip`;
187
163
  }
188
164
 
189
165
  const archivePath = path.join(outputDir, archiveFileName);
190
166
 
191
167
  // Create the archive
192
- console.log(
193
- chalk.cyan(`Creating ${archiveFormat.toUpperCase()} archive...`)
194
- );
195
- await createArchive(tempDir, archivePath, {
196
- format: archiveFormat,
197
- compressionLevel,
198
- });
168
+ console.log(chalk.cyan(`Creating ZIP archive...`));
169
+ await createArchive(tempDir, archivePath);
199
170
 
200
171
  return archivePath;
201
172
  } catch (error) {
package/src/index.js CHANGED
@@ -59,30 +59,11 @@ const initializeCLI = () => {
59
59
  .argument("<url>", "GitHub URL of the folder to clone")
60
60
  .option("-o, --output <directory>", "Output directory", process.cwd())
61
61
  .option("--zip [filename]", "Create ZIP archive of downloaded files")
62
- .option("--tar [filename]", "Create TAR archive of downloaded files")
63
- .option("--compression-level <level>", "Compression level (1-9)", "6")
64
62
  .action(async (url, options) => {
65
63
  try {
66
64
  console.log(`Parsing URL: ${url}`);
67
65
  const parsedUrl = parseGitHubUrl(url);
68
66
 
69
- // Validate options
70
- if (options.compressionLevel) {
71
- const level = parseInt(options.compressionLevel, 10);
72
- if (isNaN(level) || level < 0 || level > 9) {
73
- // Allow 0 for no compression
74
- throw new Error(
75
- "Compression level must be a number between 0 and 9"
76
- );
77
- }
78
- }
79
-
80
- if (options.zip && options.tar) {
81
- throw new Error(
82
- "Cannot specify both --zip and --tar options at the same time"
83
- );
84
- }
85
-
86
67
  // Validate output directory
87
68
  try {
88
69
  options.output = validateOutputDirectory(options.output);
@@ -90,25 +71,14 @@ const initializeCLI = () => {
90
71
  throw new Error(`Output directory error: ${dirError.message}`);
91
72
  }
92
73
 
93
- // Handle archive options
94
- const archiveFormat = options.zip ? "zip" : options.tar ? "tar" : null;
74
+ // Handle archive option
75
+ const createArchive = options.zip !== undefined;
95
76
  const archiveName =
96
- typeof options.zip === "string"
97
- ? options.zip
98
- : typeof options.tar === "string"
99
- ? options.tar
100
- : null;
101
- const compressionLevel = parseInt(options.compressionLevel, 10) || 6;
77
+ typeof options.zip === "string" ? options.zip : null;
102
78
 
103
- if (archiveFormat) {
104
- console.log(`Creating ${archiveFormat.toUpperCase()} archive...`);
105
- await downloadAndArchive(
106
- parsedUrl,
107
- options.output,
108
- archiveFormat,
109
- archiveName,
110
- compressionLevel
111
- );
79
+ if (createArchive) {
80
+ console.log(`Creating ZIP archive...`);
81
+ await downloadAndArchive(parsedUrl, options.output, archiveName);
112
82
  } else {
113
83
  console.log(`Downloading folder to: ${options.output}`);
114
84
  await downloadFolder(parsedUrl, options.output);