@mustafa60x/gitpack 0.0.1 → 1.2.0

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
@@ -1,2 +1,207 @@
1
- # gitpack
2
- Smart project packer that respects `.gitignore`
1
+ # Gitpack šŸ“¦
2
+
3
+ > Pack your project smartly. No more `node_modules` or `.git` folder clutter in your zips!
4
+
5
+ **Gitpack** creates a clean, timestamped archive of your project, respecting your `.gitignore` rules automatically.
6
+
7
+ ## Why Gitpack? šŸš€
8
+
9
+ Have you ever zipped your project to send it to someone, only to realize you included:
10
+ - āŒ The massive `node_modules` folders (100s of MBs)
11
+ - āŒ Sensitive `.env` files with API keys
12
+ - āŒ The huge `.git` history
13
+ - āŒ Temporary build artifacts (`dist`, `build`, etc.)
14
+
15
+ **Gitpack solves this** by intelligently selecting only tracked and non-ignored files, giving you production-ready archives every time.
16
+
17
+ ## Usage Scenarios šŸ’”
18
+
19
+ - **Sharing Code:** Quickly send a clean source code zip to a colleague or friend.
20
+ - **Backups:** Create a "checkpoint" of your work before trying something experimental.
21
+ - **Assignments:** Submit your homework/project without unnecessary file bloat.
22
+ - **Archives:** Manually tag and archive versions of your app.
23
+
24
+ ## Installation šŸ› ļø
25
+
26
+ ### npx (Recommended - No Installation)
27
+
28
+ You can run it directly with `npx`
29
+
30
+ ```bash
31
+ npx @mustafa60x/gitpack
32
+ ```
33
+
34
+ ### Global Installation
35
+
36
+ You can install it globally to use it from anywhere:
37
+
38
+ ```bash
39
+ npm install -g @mustafa60x/gitpack
40
+ ```
41
+
42
+ ### Project Dependency
43
+
44
+ Install it as a development dependency:
45
+
46
+ ```bash
47
+ npm install --save-dev @mustafa60x/gitpack
48
+ ```
49
+
50
+ Then add to your `package.json` scripts:
51
+
52
+ ```json
53
+ {
54
+ "scripts": {
55
+ "pack": "gitpack",
56
+ "pack:tar": "gitpack --format tar --out ./backups",
57
+ "backup": "gitpack --out ./backups"
58
+ }
59
+ }
60
+ ```
61
+
62
+
63
+ Now run with:
64
+ ```bash
65
+ npm run backup
66
+ ```
67
+
68
+ ## Requirements šŸ“‹
69
+
70
+ - **Node.js**: v14 or higher
71
+ - **Git**: Recommended (for smart tracking features), but not required.
72
+
73
+ ## Features ✨
74
+
75
+ - šŸŽÆ **Git-Aware Packing**: Uses git ls-files to include only tracked files
76
+ - šŸ“› **Smart Naming**: Auto-generates names from package.json (e.g., myapp-v1.3.0-2026-02-09_153045.zip)
77
+ - šŸ—œļø **Multiple Formats**: Support for .zip and .tar.gz
78
+ - šŸŽØ **Custom Output**: Control where archives go and what they include
79
+ - ⚔ **Zero Config**: Works out of the box with sensible defaults
80
+
81
+ ## Usage Examples šŸš€
82
+
83
+ ### Basic Usage
84
+
85
+ Create a zip archive of your project:
86
+
87
+ ```bash
88
+ # Create a zip in parent directory
89
+ gitpack
90
+
91
+ # Create a tar.gz archive
92
+ gitpack --format tar
93
+ ```
94
+
95
+ ### Custom Output Directory
96
+
97
+ Specify a different directory for the archive:
98
+
99
+ ```bash
100
+ # Save to specific folder
101
+ gitpack --out ./backups
102
+
103
+ # Save to current directory
104
+ gitpack --out .
105
+ ```
106
+
107
+ ### Different Archive Format
108
+
109
+ Create a tar.gz archive instead of a zip:
110
+
111
+ ```bash
112
+ gitpack --format tar
113
+ ```
114
+
115
+ ### Include .env Files
116
+
117
+ Include .env files in the archive (use with caution!):
118
+
119
+ ```bash
120
+ gitpack --include-env
121
+ ```
122
+
123
+ ### No Git Data
124
+
125
+ Force fallback mode and exclude .git data:
126
+
127
+ ```bash
128
+ gitpack --no-git
129
+ ```
130
+
131
+ ### Advanced Usage
132
+
133
+ Combine multiple options for custom backups:
134
+
135
+ ```bash
136
+ # Create a timestamped backup in a specific directory
137
+ gitpack --out ./backups --format tar
138
+
139
+ # Create a clean archive without .git data
140
+ gitpack --no-git --out ./clean-backup
141
+ ```
142
+
143
+ ## Output Example šŸ“‚
144
+
145
+ Imagine your project structure:
146
+
147
+ ```
148
+ my-app/
149
+ ā”œā”€ā”€ node_modules/ (ignored)
150
+ ā”œā”€ā”€ dist/ (ignored)
151
+ ā”œā”€ā”€ src/
152
+ ā”œā”€ā”€ package.json
153
+ └── README.md
154
+ ```
155
+
156
+ Running `gitpack` produces:
157
+
158
+ ```
159
+ šŸ“¦ my-app-v1.0.0-2024-03-20_140000.zip (Contains only src, package.json, README.md)
160
+ ```
161
+
162
+ ## CLI Options āš™ļø
163
+
164
+ | Flag | Description | Default |
165
+ |------|-------------|---------|
166
+ | `--format <type>` | Archive format (`zip` or `tar`). | `zip` |
167
+ | `--out <path>` | Specify output directory. | `../` (Parent directory) |
168
+ | `--include-env` | Include `.env` files (only in fallback mode). | `false` |
169
+ | `--no-git` | Force fallback mode (ignore `.git` data). | `false` |
170
+
171
+ ## Naming Convention šŸ·ļø
172
+
173
+ | Scenario | package.json | Output Name |
174
+ |----------|--------------|-------------|
175
+ | **Standard zip** | `name: "app", version: "1.3.0"` | `app-v1.3.0-2026-02-09_153045.zip` |
176
+ | **Tar format** | `name: "app", version: "2.0.1"` | `app-v2.0.1-2026-02-09_153045.tar.gz` |
177
+ | **Missing package.json** | `N/A` | `folder-name-2026-02-09_153045.zip` |
178
+ | **Missing version** | `name: "app" only` | `app-2026-02-09_153045.zip` |
179
+
180
+ ## Contributing šŸ¤
181
+
182
+ Contributions are welcome! If you find a bug or want to add a feature:
183
+
184
+ 1. Fork the repository
185
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
186
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
187
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
188
+ 5. Open a Pull Request
189
+
190
+ ## Support 🌟
191
+
192
+ If you find this project useful, please consider giving it a star on GitHub! It helps others discover the project and motivates me to keep improving it.
193
+
194
+ ## Connect šŸ“¬
195
+
196
+ If you have any questions or feedback, feel free to reach out:
197
+
198
+ - **GitHub:** [mustafa60x](https://github.com/mustafa60x)
199
+ - **Issues:** [Report a bug](https://github.com/mustafa60x/gitpack/issues)
200
+
201
+ ## License šŸ“„
202
+
203
+ MIT Ā© [mustafa60x](https://github.com/mustafa60x)
204
+
205
+ <p align="center">
206
+ Made with ā¤ļø by <a href="https://github.com/mustafa60x">mustafa60x</a>
207
+ </p>
package/bin/gitpack.js CHANGED
@@ -1,3 +1,157 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- console.log("Hello World");
3
+ import fs from "fs";
4
+ import path from "path";
5
+ import { execSync } from "child_process";
6
+ import archiver from "archiver";
7
+
8
+ // ----------------------
9
+ // ARG PARSE
10
+ // ----------------------
11
+
12
+ const args = process.argv.slice(2);
13
+
14
+ let format = "zip";
15
+ let outDir = path.dirname(process.cwd());
16
+ let includeEnv = false;
17
+ let noGit = false;
18
+
19
+ for (let i = 0; i < args.length; i++) {
20
+ if (args[i] === "--format" && args[i + 1]) {
21
+ format = args[i + 1];
22
+ i++;
23
+ } else if (args[i] === "--out" && args[i + 1]) {
24
+ outDir = path.resolve(args[i + 1]);
25
+ i++;
26
+ } else if (args[i] === "--include-env") {
27
+ includeEnv = true;
28
+ } else if (args[i] === "--no-git") {
29
+ noGit = true;
30
+ }
31
+ }
32
+
33
+ // ----------------------
34
+ // PROJECT INFO
35
+ // ----------------------
36
+
37
+ const now = new Date();
38
+ const pad = (n) => String(n).padStart(2, "0");
39
+ const dateStr = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
40
+ const timeStr = `${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
41
+ const timestamp = `${dateStr}_${timeStr}`;
42
+
43
+ const cwd = process.cwd();
44
+ let projectName = path.basename(cwd);
45
+ let version = "";
46
+
47
+ const pkgPath = path.join(cwd, "package.json");
48
+
49
+ if (fs.existsSync(pkgPath)) {
50
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
51
+ if (pkg.name) projectName = pkg.name;
52
+ if (pkg.version) version = `-v${pkg.version.replace(/^v/, "")}`;
53
+ }
54
+
55
+ if (!fs.existsSync(outDir)) {
56
+ fs.mkdirSync(outDir, { recursive: true });
57
+ }
58
+
59
+ const extension = format === "tar" ? "tar.gz" : "zip";
60
+ const safeProjectName = projectName.replace(/^@/, "").replace(/\//g, "-");
61
+ const outputName = `${safeProjectName}${version}-${timestamp}.${extension}`;
62
+ const outputPath = path.join(outDir, outputName);
63
+
64
+ // ----------------------
65
+ // ARCHIVER SETUP
66
+ // ----------------------
67
+
68
+ const output = fs.createWriteStream(outputPath);
69
+
70
+ const archive =
71
+ format === "tar"
72
+ ? archiver("tar", { gzip: true, gzipOptions: { level: 9 } })
73
+ : archiver("zip", { zlib: { level: 9 } });
74
+
75
+ archive.pipe(output);
76
+
77
+ // ----------------------
78
+ // FILE STRATEGY
79
+ // ----------------------
80
+
81
+ const gitAvailable = fs.existsSync(path.join(cwd, ".git")) && !noGit;
82
+
83
+ // Calculate relative path of output to CWD for exclusion
84
+ const relativeOutputPath = path.relative(cwd, outputPath);
85
+ const isOutputInside = !relativeOutputPath.startsWith("..") && !path.isAbsolute(relativeOutputPath);
86
+
87
+ if (gitAvailable) {
88
+ let gitCommand = "git ls-files --cached --others --exclude-standard";
89
+
90
+ // If output is inside, exclude it from git listing
91
+ if (isOutputInside) {
92
+ gitCommand += ` -- ":(exclude)${relativeOutputPath}"`;
93
+ }
94
+
95
+ const files = execSync(gitCommand)
96
+ .toString()
97
+ .split("\n")
98
+ .filter(Boolean);
99
+
100
+ files.forEach((file) => {
101
+ archive.file(path.join(cwd, file), { name: file });
102
+ });
103
+ } else {
104
+ const ignoreList = [
105
+ "node_modules/**",
106
+ ".git/**",
107
+ ".nuxt/**",
108
+ "dist/**",
109
+ "build/**",
110
+ ".next/**",
111
+ "coverage/**"
112
+ ];
113
+
114
+ if (isOutputInside) {
115
+ ignoreList.push(relativeOutputPath);
116
+ // Also ignore the folder if specific outDir was used
117
+ const relativeOutDir = path.relative(cwd, outDir);
118
+ if (!relativeOutDir.startsWith("..") && relativeOutDir !== "") {
119
+ ignoreList.push(`${relativeOutDir}/**`);
120
+ }
121
+ }
122
+
123
+ if (!includeEnv) {
124
+ ignoreList.push(".env", ".env.*");
125
+ }
126
+
127
+ archive.glob("**/*", {
128
+ cwd,
129
+ ignore: ignoreList
130
+ });
131
+ }
132
+
133
+ // ----------------------
134
+
135
+ function formatBytes(bytes) {
136
+ if (bytes === 0) return "0 Bytes";
137
+ const k = 1024;
138
+ const sizes = ["Bytes", "KB", "MB", "GB"];
139
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
140
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
141
+ }
142
+
143
+ archive.finalize();
144
+
145
+ output.on("close", () => {
146
+ const stats = fs.statSync(outputPath);
147
+ const size = formatBytes(stats.size);
148
+
149
+ console.log("\n──────────────────────────────────────────");
150
+ console.log(` šŸŽ Project: ${projectName}`);
151
+ if (version) console.log(` šŸ·ļø Version: ${version.slice(1)}`);
152
+ console.log(` šŸ“¦ Format: ${format === "tar" ? "tar.gz" : "zip"}`);
153
+ console.log(` šŸ“ Size: ${size}`);
154
+ console.log(` šŸš€ Path: ${outputPath}`);
155
+ console.log("──────────────────────────────────────────");
156
+ console.log(` āœ” Archive successfully created!\n`);
157
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mustafa60x/gitpack",
3
- "version": "0.0.1",
3
+ "version": "1.2.0",
4
4
  "overrides": {
5
5
  "glob": "^11.0.0"
6
6
  },
@@ -8,6 +8,12 @@
8
8
  "bin": {
9
9
  "gitpack": "bin/gitpack.js"
10
10
  },
11
+ "scripts": {
12
+ "release": "./scripts/publish.sh",
13
+ "release:patch": "./scripts/publish.sh patch",
14
+ "release:minor": "./scripts/publish.sh minor",
15
+ "release:major": "./scripts/publish.sh major"
16
+ },
11
17
  "type": "module",
12
18
  "repository": {
13
19
  "type": "git",
@@ -30,4 +36,4 @@
30
36
  "dependencies": {
31
37
  "archiver": "^7.0.1"
32
38
  }
33
- }
39
+ }
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+
3
+ # Colors
4
+ GREEN='\033[0;32m'
5
+ BLUE='\033[0;34m'
6
+ YELLOW='\033[1;33m'
7
+ NC='\033[0m' # No Color
8
+
9
+ echo -e "${BLUE}šŸš€ Starting Gitpack Release...${NC}"
10
+
11
+ # Stop on error
12
+ set -e
13
+
14
+ # Version type (patch, minor, major) default: patch
15
+ TYPE=${1:-patch}
16
+
17
+ # 1. Check current git status
18
+ if [ -n "$(git status --porcelain)" ]; then
19
+ echo -e "${YELLOW}āš ļø Uncommitted changes found. Please clean or commit your changes first.${NC}"
20
+ exit 1
21
+ fi
22
+
23
+ # 2. Run tests (if any)
24
+ # npm test
25
+
26
+ # 3. Update version
27
+ echo -e "${BLUE}šŸ”¢ Updating version ($TYPE)...${NC}"
28
+ NEW_VERSION=$(npm version $TYPE --no-git-tag-version)
29
+
30
+ # 4. Commit changes and create tag
31
+ git add package.json package-lock.json
32
+ git commit -m "chore: release $NEW_VERSION"
33
+ git tag -a $NEW_VERSION -m "Release $NEW_VERSION"
34
+
35
+ # 5. Push to Git
36
+ echo -e "${BLUE}šŸ“¤ Pushing to Git...${NC}"
37
+ CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
38
+ git push origin "$CURRENT_BRANCH" --follow-tags
39
+
40
+ # 6. Publish to NPM
41
+ echo -e "${BLUE}šŸ“¦ Publishing to NPM...${NC}"
42
+ npm publish --access public
43
+
44
+ echo -e "${GREEN}šŸŽ‰ Successfully published version $NEW_VERSION!${NC}"