gitbasher 3.8.0 → 3.8.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.
Files changed (2) hide show
  1. package/download-release.js +97 -26
  2. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  const https = require('https');
2
+ const http = require('http');
2
3
  const fs = require('fs');
3
4
  const path = require('path');
4
5
 
@@ -18,31 +19,101 @@ if (!fs.existsSync(BIN_DIR)) {
18
19
  fs.mkdirSync(BIN_DIR, { recursive: true });
19
20
  }
20
21
 
21
- // Download the release asset
22
- console.log(`Downloading gitbasher v${VERSION} from GitHub releases...`);
23
- const file = fs.createWriteStream(BIN_PATH);
24
-
25
- https.get(RELEASE_URL, (response) => {
26
- if (response.statusCode === 302 || response.statusCode === 301) {
27
- // Follow redirect
28
- https.get(response.headers.location, (redirectResponse) => {
29
- redirectResponse.pipe(file);
30
- file.on('finish', () => {
31
- file.close();
32
- fs.chmodSync(BIN_PATH, 0o755);
33
- console.log('Download complete!');
22
+ // Download function with redirect handling
23
+ function download(url, outputPath, maxRedirects = 5) {
24
+ return new Promise((resolve, reject) => {
25
+ if (maxRedirects === 0) {
26
+ reject(new Error('Too many redirects'));
27
+ return;
28
+ }
29
+
30
+ const client = url.startsWith('https') ? https : http;
31
+ const file = fs.createWriteStream(outputPath);
32
+ let downloadedBytes = 0;
33
+ let totalBytes = 0;
34
+
35
+ // Add timeout (30 seconds)
36
+ const timeout = setTimeout(() => {
37
+ file.close();
38
+ if (fs.existsSync(outputPath)) {
39
+ fs.unlinkSync(outputPath);
40
+ }
41
+ reject(new Error('Download timeout after 30s'));
42
+ }, 30000);
43
+
44
+ client.get(url, (response) => {
45
+ // Handle redirects
46
+ if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 307 || response.statusCode === 308) {
47
+ clearTimeout(timeout);
48
+ file.close();
49
+ fs.unlinkSync(outputPath);
50
+ const redirectUrl = response.headers.location;
51
+ if (!redirectUrl) {
52
+ reject(new Error('Redirect location not found'));
53
+ return;
54
+ }
55
+ // Resolve relative redirects
56
+ const redirectUrlFull = redirectUrl.startsWith('http')
57
+ ? redirectUrl
58
+ : new URL(redirectUrl, url).href;
59
+ return download(redirectUrlFull, outputPath, maxRedirects - 1)
60
+ .then(resolve)
61
+ .catch(reject);
62
+ }
63
+
64
+ // Handle errors
65
+ if (response.statusCode !== 200) {
66
+ file.close();
67
+ fs.unlinkSync(outputPath);
68
+ reject(new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`));
69
+ return;
70
+ }
71
+
72
+ // Track download progress
73
+ totalBytes = parseInt(response.headers['content-length'] || '0', 10);
74
+ if (totalBytes > 0) {
75
+ response.on('data', (chunk) => {
76
+ downloadedBytes += chunk.length;
77
+ });
78
+ }
79
+
80
+ // Pipe response to file
81
+ response.pipe(file);
82
+
83
+ file.on('finish', () => {
84
+ clearTimeout(timeout);
85
+ file.close();
86
+ fs.chmodSync(outputPath, 0o755);
87
+ if (totalBytes > 0) {
88
+ const sizeKB = (downloadedBytes / 1024).toFixed(1);
89
+ process.stderr.write(`✓ Downloaded ${sizeKB}KB\n`);
90
+ } else {
91
+ process.stderr.write('✓ Download complete\n');
92
+ }
93
+ resolve();
94
+ });
95
+ }).on('error', (err) => {
96
+ clearTimeout(timeout);
97
+ file.close();
98
+ if (fs.existsSync(outputPath)) {
99
+ fs.unlinkSync(outputPath);
100
+ }
101
+ reject(err);
34
102
  });
35
103
  });
36
- } else {
37
- response.pipe(file);
38
- file.on('finish', () => {
39
- file.close();
40
- fs.chmodSync(BIN_PATH, 0o755);
41
- console.log('Download complete!');
42
- });
43
- }
44
- }).on('error', (err) => {
45
- fs.unlinkSync(BIN_PATH);
46
- console.error(`Error downloading release: ${err.message}`);
47
- process.exit(1);
48
- });
104
+ }
105
+
106
+ // Download the release asset
107
+ // Use stderr for progress so it's visible during npm install
108
+ process.stderr.write(`Downloading gitbasher v${VERSION}...\n`);
109
+ const startTime = Date.now();
110
+
111
+ download(RELEASE_URL, BIN_PATH)
112
+ .then(() => {
113
+ const duration = ((Date.now() - startTime) / 1000).toFixed(1);
114
+ process.stderr.write(`✓ Installed in ${duration}s\n`);
115
+ })
116
+ .catch((err) => {
117
+ process.stderr.write(`✗ Error downloading release: ${err.message}\n`);
118
+ process.exit(1);
119
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitbasher",
3
- "version": "3.8.0",
3
+ "version": "3.8.2",
4
4
  "description": "Simple bash utility that makes git easy to use",
5
5
  "keywords": [
6
6
  "git",