jvcs 1.0.2 → 1.0.3
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/.env +4 -4
- package/.jvcs/HEAD +1 -0
- package/.jvcs/commits/3a1169c8-ec67-4ce5-8024-ab4f08d7b609/index.js +146 -0
- package/.jvcs/commits/3a1169c8-ec67-4ce5-8024-ab4f08d7b609/jvcs_hashcode.json +6 -0
- package/.jvcs/commits/3a1169c8-ec67-4ce5-8024-ab4f08d7b609/meta.json +7 -0
- package/.jvcs/commits/c362f97f-997b-499a-bb45-9e67f298f61e/index.js +146 -0
- package/.jvcs/commits/c362f97f-997b-499a-bb45-9e67f298f61e/jvcs_hashcode.json +6 -0
- package/.jvcs/commits/c362f97f-997b-499a-bb45-9e67f298f61e/meta.json +7 -0
- package/.jvcs/config.json +9 -0
- package/.jvcs/staging/index.js +146 -0
- package/.jvcs/staging/jvcs_hashcode.json +6 -0
- package/controllers/driveUtility.js +56 -0
- package/controllers/push.js +121 -111
- package/index.js +17 -2
- package/package.json +1 -1
- package/controllers/pull.js +0 -98
- package/controllers/revert.js +0 -110
package/.env
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
CLIENT_ID=
|
|
2
|
-
CLIENT_SECRET=
|
|
3
|
-
REDIRECT_URI=
|
|
4
|
-
REFRESH_TOKEN=
|
|
1
|
+
CLIENT_ID=835069827989-3spob55ioa2ocudi3mo8u2ni2ecqohh7.apps.googleusercontent.com
|
|
2
|
+
CLIENT_SECRET=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
|
|
3
|
+
REDIRECT_URI=https://developers.google.com/oauthplayground
|
|
4
|
+
REFRESH_TOKEN=1//04wJgrjHWoDOZCgYIARAAGAQSNwF-L9Iryvz_RHMDkqyYlK2wv9TiVMsvq1eghHFnbS868U-zraLb44f8dEPvpNjJEmex_IcMxUE
|
package/.jvcs/HEAD
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3a1169c8-ec67-4ce5-8024-ab4f08d7b609
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const yargs = require("yargs");
|
|
4
|
+
const { hideBin } = require("yargs/helpers");
|
|
5
|
+
const chalk = require("chalk");
|
|
6
|
+
const dotenv = require("dotenv")
|
|
7
|
+
dotenv.config()
|
|
8
|
+
|
|
9
|
+
const beginCmd = require("./controllers/begin")
|
|
10
|
+
const initCmd = require("./controllers/init")
|
|
11
|
+
const addCmd = require("./controllers/add")
|
|
12
|
+
const commitCmd = require("./controllers/commit")
|
|
13
|
+
const unstageCmd = require("./controllers/unstage")
|
|
14
|
+
const logCmd = require("./controllers/log");
|
|
15
|
+
const pushCmd = require("./controllers/push");
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
yargs(hideBin(process.argv))
|
|
19
|
+
.scriptName("jvcs")
|
|
20
|
+
.command(
|
|
21
|
+
"begin",
|
|
22
|
+
chalk.blue("Initialize the Version Control System (login/signup).\n"),
|
|
23
|
+
{},
|
|
24
|
+
async () => {
|
|
25
|
+
try {
|
|
26
|
+
await beginCmd()
|
|
27
|
+
}
|
|
28
|
+
catch(error) {
|
|
29
|
+
console.log(chalk.red(error))
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
.command(
|
|
34
|
+
"init",
|
|
35
|
+
chalk.blue("Create an empty repository.\n"),
|
|
36
|
+
{},
|
|
37
|
+
async () => {
|
|
38
|
+
try {
|
|
39
|
+
await initCmd()
|
|
40
|
+
}
|
|
41
|
+
catch(error) {
|
|
42
|
+
console.log(chalk.red(error))
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
.command(
|
|
47
|
+
"add <paths...>",
|
|
48
|
+
chalk.blue(
|
|
49
|
+
`Add files or folders to the staging area.
|
|
50
|
+
|
|
51
|
+
Command | Description
|
|
52
|
+
---------------------------------|-------------------
|
|
53
|
+
jvcs add . | all files/folders
|
|
54
|
+
jvcs add <file1> <file2> | multiple files
|
|
55
|
+
jvcs add <folder1> <folder2> | multiple folders
|
|
56
|
+
jvcs add <file> <folder> | files and folders\n`
|
|
57
|
+
),
|
|
58
|
+
(yargs)=> {
|
|
59
|
+
return yargs.positional("paths", {
|
|
60
|
+
type: 'string',
|
|
61
|
+
describe: 'Files and folders to stage'
|
|
62
|
+
})
|
|
63
|
+
},
|
|
64
|
+
async (argv) => {
|
|
65
|
+
try {
|
|
66
|
+
await addCmd(argv.paths)
|
|
67
|
+
}
|
|
68
|
+
catch(error) {
|
|
69
|
+
console.log(chalk.red(error))
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
.command(
|
|
74
|
+
"commit <message>",
|
|
75
|
+
chalk.blue("Commit all the files/folders inside staging area\n"),
|
|
76
|
+
(yargs)=> {
|
|
77
|
+
return yargs.positional("message", {
|
|
78
|
+
type: 'string',
|
|
79
|
+
describe: 'Some message with your commit'
|
|
80
|
+
})
|
|
81
|
+
},
|
|
82
|
+
async (argv)=> {
|
|
83
|
+
try {
|
|
84
|
+
await commitCmd(argv.message)
|
|
85
|
+
}
|
|
86
|
+
catch(error) {
|
|
87
|
+
console.log(chalk.red(error))
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
.command(
|
|
92
|
+
"unstage <paths...>",
|
|
93
|
+
chalk.blue(`
|
|
94
|
+
Remove files and folders from staging area
|
|
95
|
+
|
|
96
|
+
Command | Description
|
|
97
|
+
---------------------------------|-------------------
|
|
98
|
+
jvcs unstage . | all files/folders
|
|
99
|
+
jvcs unstage <file1> <file2> | multiple files
|
|
100
|
+
jvcs unstage <folder1> <folder2> | multiple folders
|
|
101
|
+
jvcs unstage <file> <folder> | files and folders\n
|
|
102
|
+
`),
|
|
103
|
+
(yargs)=> {
|
|
104
|
+
return yargs.positional("paths", {
|
|
105
|
+
type: 'string',
|
|
106
|
+
describe: 'Files and folders to unstage'
|
|
107
|
+
})
|
|
108
|
+
},
|
|
109
|
+
async (argv)=> {
|
|
110
|
+
try {
|
|
111
|
+
await unstageCmd(argv.paths)
|
|
112
|
+
}
|
|
113
|
+
catch(error) {
|
|
114
|
+
console.log(chalk.red(error))
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
.command(
|
|
119
|
+
"log",
|
|
120
|
+
"show details of all commits",
|
|
121
|
+
{},
|
|
122
|
+
async ()=> {
|
|
123
|
+
try {
|
|
124
|
+
await logCmd()
|
|
125
|
+
}
|
|
126
|
+
catch(error) {
|
|
127
|
+
console.log(chalk.red(error))
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
.command(
|
|
132
|
+
"push",
|
|
133
|
+
"Push all the commits to remote",
|
|
134
|
+
{},
|
|
135
|
+
async ()=> {
|
|
136
|
+
try {
|
|
137
|
+
await pushCmd()
|
|
138
|
+
}
|
|
139
|
+
catch(error) {
|
|
140
|
+
console.log(chalk.red(error))
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
.demandCommand(1, chalk.yellow("You need at least one command"))
|
|
145
|
+
.help()
|
|
146
|
+
.parse();
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const yargs = require("yargs");
|
|
4
|
+
const { hideBin } = require("yargs/helpers");
|
|
5
|
+
const chalk = require("chalk");
|
|
6
|
+
const dotenv = require("dotenv")
|
|
7
|
+
dotenv.config()
|
|
8
|
+
|
|
9
|
+
const beginCmd = require("./controllers/begin")
|
|
10
|
+
const initCmd = require("./controllers/init")
|
|
11
|
+
const addCmd = require("./controllers/add")
|
|
12
|
+
const commitCmd = require("./controllers/commit")
|
|
13
|
+
const unstageCmd = require("./controllers/unstage")
|
|
14
|
+
const logCmd = require("./controllers/log");
|
|
15
|
+
const pushCmd = require("./controllers/push");
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
yargs(hideBin(process.argv))
|
|
19
|
+
.scriptName("jvcs")
|
|
20
|
+
.command(
|
|
21
|
+
"begin",
|
|
22
|
+
chalk.blue("Initialize the Version Control System (login/signup).\n"),
|
|
23
|
+
{},
|
|
24
|
+
async () => {
|
|
25
|
+
try {
|
|
26
|
+
await beginCmd()
|
|
27
|
+
}
|
|
28
|
+
catch(error) {
|
|
29
|
+
console.log(chalk.red(error))
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
.command(
|
|
34
|
+
"init",
|
|
35
|
+
chalk.blue("Create an empty repository.\n"),
|
|
36
|
+
{},
|
|
37
|
+
async () => {
|
|
38
|
+
try {
|
|
39
|
+
await initCmd()
|
|
40
|
+
}
|
|
41
|
+
catch(error) {
|
|
42
|
+
console.log(chalk.red(error))
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
.command(
|
|
47
|
+
"add <paths...>",
|
|
48
|
+
chalk.blue(
|
|
49
|
+
`Add files or folders to the staging area.
|
|
50
|
+
|
|
51
|
+
Command | Description
|
|
52
|
+
---------------------------------|-------------------
|
|
53
|
+
jvcs add . | all files/folders
|
|
54
|
+
jvcs add <file1> <file2> | multiple files
|
|
55
|
+
jvcs add <folder1> <folder2> | multiple folders
|
|
56
|
+
jvcs add <file> <folder> | files and folders\n`
|
|
57
|
+
),
|
|
58
|
+
(yargs)=> {
|
|
59
|
+
return yargs.positional("paths", {
|
|
60
|
+
type: 'string',
|
|
61
|
+
describe: 'Files and folders to stage'
|
|
62
|
+
})
|
|
63
|
+
},
|
|
64
|
+
async (argv) => {
|
|
65
|
+
try {
|
|
66
|
+
await addCmd(argv.paths)
|
|
67
|
+
}
|
|
68
|
+
catch(error) {
|
|
69
|
+
console.log(chalk.red(error))
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
.command(
|
|
74
|
+
"commit <message>",
|
|
75
|
+
chalk.blue("Commit all the files/folders inside staging area\n"),
|
|
76
|
+
(yargs)=> {
|
|
77
|
+
return yargs.positional("message", {
|
|
78
|
+
type: 'string',
|
|
79
|
+
describe: 'Some message with your commit'
|
|
80
|
+
})
|
|
81
|
+
},
|
|
82
|
+
async (argv)=> {
|
|
83
|
+
try {
|
|
84
|
+
await commitCmd(argv.message)
|
|
85
|
+
}
|
|
86
|
+
catch(error) {
|
|
87
|
+
console.log(chalk.red(error))
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
.command(
|
|
92
|
+
"unstage <paths...>",
|
|
93
|
+
chalk.blue(`
|
|
94
|
+
Remove files and folders from staging area
|
|
95
|
+
|
|
96
|
+
Command | Description
|
|
97
|
+
---------------------------------|-------------------
|
|
98
|
+
jvcs unstage . | all files/folders
|
|
99
|
+
jvcs unstage <file1> <file2> | multiple files
|
|
100
|
+
jvcs unstage <folder1> <folder2> | multiple folders
|
|
101
|
+
jvcs unstage <file> <folder> | files and folders\n
|
|
102
|
+
`),
|
|
103
|
+
(yargs)=> {
|
|
104
|
+
return yargs.positional("paths", {
|
|
105
|
+
type: 'string',
|
|
106
|
+
describe: 'Files and folders to unstage'
|
|
107
|
+
})
|
|
108
|
+
},
|
|
109
|
+
async (argv)=> {
|
|
110
|
+
try {
|
|
111
|
+
await unstageCmd(argv.paths)
|
|
112
|
+
}
|
|
113
|
+
catch(error) {
|
|
114
|
+
console.log(chalk.red(error))
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
.command(
|
|
119
|
+
"log",
|
|
120
|
+
"show details of all commits",
|
|
121
|
+
{},
|
|
122
|
+
async ()=> {
|
|
123
|
+
try {
|
|
124
|
+
await logCmd()
|
|
125
|
+
}
|
|
126
|
+
catch(error) {
|
|
127
|
+
console.log(chalk.red(error))
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
.command(
|
|
132
|
+
"push",
|
|
133
|
+
"Push all the commits to remote",
|
|
134
|
+
{},
|
|
135
|
+
async ()=> {
|
|
136
|
+
try {
|
|
137
|
+
await pushCmd()
|
|
138
|
+
}
|
|
139
|
+
catch(error) {
|
|
140
|
+
console.log(chalk.red(error))
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
.demandCommand(1, chalk.yellow("You need at least one command"))
|
|
145
|
+
.help()
|
|
146
|
+
.parse();
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const yargs = require("yargs");
|
|
4
|
+
const { hideBin } = require("yargs/helpers");
|
|
5
|
+
const chalk = require("chalk");
|
|
6
|
+
const dotenv = require("dotenv")
|
|
7
|
+
dotenv.config()
|
|
8
|
+
|
|
9
|
+
const beginCmd = require("./controllers/begin")
|
|
10
|
+
const initCmd = require("./controllers/init")
|
|
11
|
+
const addCmd = require("./controllers/add")
|
|
12
|
+
const commitCmd = require("./controllers/commit")
|
|
13
|
+
const unstageCmd = require("./controllers/unstage")
|
|
14
|
+
const logCmd = require("./controllers/log");
|
|
15
|
+
const pushCmd = require("./controllers/push");
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
yargs(hideBin(process.argv))
|
|
19
|
+
.scriptName("jvcs")
|
|
20
|
+
.command(
|
|
21
|
+
"begin",
|
|
22
|
+
chalk.blue("Initialize the Version Control System (login/signup).\n"),
|
|
23
|
+
{},
|
|
24
|
+
async () => {
|
|
25
|
+
try {
|
|
26
|
+
await beginCmd()
|
|
27
|
+
}
|
|
28
|
+
catch(error) {
|
|
29
|
+
console.log(chalk.red(error))
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
.command(
|
|
34
|
+
"init",
|
|
35
|
+
chalk.blue("Create an empty repository.\n"),
|
|
36
|
+
{},
|
|
37
|
+
async () => {
|
|
38
|
+
try {
|
|
39
|
+
await initCmd()
|
|
40
|
+
}
|
|
41
|
+
catch(error) {
|
|
42
|
+
console.log(chalk.red(error))
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
.command(
|
|
47
|
+
"add <paths...>",
|
|
48
|
+
chalk.blue(
|
|
49
|
+
`Add files or folders to the staging area.
|
|
50
|
+
|
|
51
|
+
Command | Description
|
|
52
|
+
---------------------------------|-------------------
|
|
53
|
+
jvcs add . | all files/folders
|
|
54
|
+
jvcs add <file1> <file2> | multiple files
|
|
55
|
+
jvcs add <folder1> <folder2> | multiple folders
|
|
56
|
+
jvcs add <file> <folder> | files and folders\n`
|
|
57
|
+
),
|
|
58
|
+
(yargs)=> {
|
|
59
|
+
return yargs.positional("paths", {
|
|
60
|
+
type: 'string',
|
|
61
|
+
describe: 'Files and folders to stage'
|
|
62
|
+
})
|
|
63
|
+
},
|
|
64
|
+
async (argv) => {
|
|
65
|
+
try {
|
|
66
|
+
await addCmd(argv.paths)
|
|
67
|
+
}
|
|
68
|
+
catch(error) {
|
|
69
|
+
console.log(chalk.red(error))
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
.command(
|
|
74
|
+
"commit <message>",
|
|
75
|
+
chalk.blue("Commit all the files/folders inside staging area\n"),
|
|
76
|
+
(yargs)=> {
|
|
77
|
+
return yargs.positional("message", {
|
|
78
|
+
type: 'string',
|
|
79
|
+
describe: 'Some message with your commit'
|
|
80
|
+
})
|
|
81
|
+
},
|
|
82
|
+
async (argv)=> {
|
|
83
|
+
try {
|
|
84
|
+
await commitCmd(argv.message)
|
|
85
|
+
}
|
|
86
|
+
catch(error) {
|
|
87
|
+
console.log(chalk.red(error))
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
.command(
|
|
92
|
+
"unstage <paths...>",
|
|
93
|
+
chalk.blue(`
|
|
94
|
+
Remove files and folders from staging area
|
|
95
|
+
|
|
96
|
+
Command | Description
|
|
97
|
+
---------------------------------|-------------------
|
|
98
|
+
jvcs unstage . | all files/folders
|
|
99
|
+
jvcs unstage <file1> <file2> | multiple files
|
|
100
|
+
jvcs unstage <folder1> <folder2> | multiple folders
|
|
101
|
+
jvcs unstage <file> <folder> | files and folders\n
|
|
102
|
+
`),
|
|
103
|
+
(yargs)=> {
|
|
104
|
+
return yargs.positional("paths", {
|
|
105
|
+
type: 'string',
|
|
106
|
+
describe: 'Files and folders to unstage'
|
|
107
|
+
})
|
|
108
|
+
},
|
|
109
|
+
async (argv)=> {
|
|
110
|
+
try {
|
|
111
|
+
await unstageCmd(argv.paths)
|
|
112
|
+
}
|
|
113
|
+
catch(error) {
|
|
114
|
+
console.log(chalk.red(error))
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
.command(
|
|
119
|
+
"log",
|
|
120
|
+
"show details of all commits",
|
|
121
|
+
{},
|
|
122
|
+
async ()=> {
|
|
123
|
+
try {
|
|
124
|
+
await logCmd()
|
|
125
|
+
}
|
|
126
|
+
catch(error) {
|
|
127
|
+
console.log(chalk.red(error))
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
.command(
|
|
132
|
+
"push",
|
|
133
|
+
"Push all the commits to remote",
|
|
134
|
+
{},
|
|
135
|
+
async ()=> {
|
|
136
|
+
try {
|
|
137
|
+
await pushCmd()
|
|
138
|
+
}
|
|
139
|
+
catch(error) {
|
|
140
|
+
console.log(chalk.red(error))
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
.demandCommand(1, chalk.yellow("You need at least one command"))
|
|
145
|
+
.help()
|
|
146
|
+
.parse();
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const { drive } = require("../config/drive-config");
|
|
2
|
+
|
|
3
|
+
async function getDirectoryStructure(username,reponame,commitId) {
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async function findOrCreateFolder(name,parentId=null) {
|
|
7
|
+
|
|
8
|
+
const query = [
|
|
9
|
+
`name='${name}'`,
|
|
10
|
+
"mimeType='application/vnd.google-apps.folder'",
|
|
11
|
+
"trashed=false"
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
if(parentId) {
|
|
15
|
+
query.push(`'${parentId}' in parents`)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const res = await drive.files.list({
|
|
19
|
+
q: query.join(" and "),
|
|
20
|
+
fields: "files(id,name)"
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
if (res.data.files.length > 0)
|
|
24
|
+
return { id: res.data.files[0].id, alreadyExists: true };
|
|
25
|
+
|
|
26
|
+
const folderMetaData = {
|
|
27
|
+
name,
|
|
28
|
+
mimeType: "application/vnd.google-apps.folder",
|
|
29
|
+
}
|
|
30
|
+
if(parentId) folderMetaData.parents = [parentId];
|
|
31
|
+
|
|
32
|
+
const folder = await drive.files.create({
|
|
33
|
+
resource: folderMetaData,
|
|
34
|
+
fields: "id"
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
return { id: folder.data.id, alreadyExists: false };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Build folder hierarchy in drive
|
|
41
|
+
const githubClone = await findOrCreateFolder("GithubClone");
|
|
42
|
+
const userFolder = await findOrCreateFolder(username,githubClone.id)
|
|
43
|
+
const repoFolder = await findOrCreateFolder(reponame,userFolder.id)
|
|
44
|
+
const commitFolderName = `commit_${commitId}`
|
|
45
|
+
const commitFolder = await findOrCreateFolder(commitFolderName,repoFolder.id)
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
githubClone: githubClone.id,
|
|
49
|
+
userFolder: userFolder.id,
|
|
50
|
+
repoFolder: repoFolder.id,
|
|
51
|
+
commitFolder: commitFolder.id,
|
|
52
|
+
commitAlreadyExists: commitFolder.alreadyExists
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = getDirectoryStructure
|
package/controllers/push.js
CHANGED
|
@@ -1,135 +1,145 @@
|
|
|
1
|
-
const fs = require("fs")
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
6
|
-
const
|
|
7
|
-
const { checkInitialization, checkRepoExists, getCLIConfig } = require("./utils");
|
|
8
|
-
|
|
9
|
-
async function pushCmd(reponame) {
|
|
10
|
-
try {
|
|
11
|
-
if (!checkInitialization()) return;
|
|
12
|
-
if (!checkRepoExists(reponame)) return;
|
|
1
|
+
const fs = require("fs")
|
|
2
|
+
const path = require("path")
|
|
3
|
+
const chalk = require("chalk")
|
|
4
|
+
const { drive } = require("../config/drive-config")
|
|
5
|
+
const { getGlobalConfig, checkGlobalConfig, checkforjvcs } = require("./utility")
|
|
6
|
+
const getDirectoryStructure = require("./driveUtility")
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
const commitFolder = path.join(repoPath, "commits");
|
|
8
|
+
async function uploadFile(localFile, parentId) {
|
|
16
9
|
|
|
17
|
-
|
|
18
|
-
if (!config) return console.log(chalk.red("Could not read CLI configuration."));
|
|
10
|
+
try {
|
|
19
11
|
|
|
20
|
-
|
|
12
|
+
const fileName = path.basename(localFile)
|
|
13
|
+
const fileMetaData = {
|
|
14
|
+
name: fileName,
|
|
15
|
+
parents: [parentId]
|
|
16
|
+
}
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
console.log(chalk.yellow("⚠ No commits to push."));
|
|
26
|
-
return;
|
|
18
|
+
const media = {
|
|
19
|
+
mimeType: "application/octet-stream",
|
|
20
|
+
body: fs.createReadStream(localFile),
|
|
27
21
|
}
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
const res = await drive.files.create({
|
|
24
|
+
resource: fileMetaData,
|
|
25
|
+
media,
|
|
26
|
+
fields: "id"
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
console.log(chalk.gray(` ↳ Uploaded: ${fileName}`));
|
|
30
|
+
return res.data.id;
|
|
31
|
+
}
|
|
32
|
+
catch(error) {
|
|
33
|
+
console.log(chalk.red(`Failed to upload ${filePath}: ${err.message}`));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function uploadDirectory(localDir, parentId) {
|
|
38
|
+
|
|
39
|
+
const entries = fs.readdirSync(localDir, {withFileTypes: true})
|
|
40
|
+
|
|
41
|
+
for(const entry of entries) {
|
|
42
|
+
|
|
43
|
+
const entryPath = path.join(localDir,entry.name)
|
|
44
|
+
|
|
45
|
+
if(entry.isDirectory()) {
|
|
46
|
+
const folderMeta = {
|
|
47
|
+
name: entry.name,
|
|
48
|
+
mimeType: "application/vnd.google-apps.folder",
|
|
49
|
+
parents: [parentId],
|
|
50
|
+
}
|
|
35
51
|
|
|
36
|
-
if (userFolderRes.data.files.length) {
|
|
37
|
-
userFolderId = userFolderRes.data.files[0].id;
|
|
38
|
-
} else {
|
|
39
52
|
const folder = await drive.files.create({
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
console.log(chalk.green(`Created user folder in Drive.`));
|
|
53
|
+
resource: folderMeta,
|
|
54
|
+
fields: "id"
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
await uploadDirectory(entryPath,folder.data.id)
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
await uploadFile(entryPath,parentId)
|
|
49
61
|
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
50
64
|
|
|
51
|
-
|
|
52
|
-
let repoFolderId;
|
|
53
|
-
const repoFolderRes = await drive.files.list({
|
|
54
|
-
q: `name='${reponame}' and '${userFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
55
|
-
fields: "files(id, name)"
|
|
56
|
-
});
|
|
65
|
+
async function pushCmd() {
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
console.log(chalk.green(
|
|
67
|
+
try {
|
|
68
|
+
|
|
69
|
+
if(!checkGlobalConfig()) {
|
|
70
|
+
console.log(chalk.red("No existing session found. Please login or signup."))
|
|
71
|
+
console.log(chalk.green("jvcs --help for help"))
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let configData = getGlobalConfig()
|
|
76
|
+
|
|
77
|
+
if(!configData) {
|
|
78
|
+
console.log(chalk.red("No existing session found. Please login or signup."))
|
|
79
|
+
console.log(chalk.green("jvcs --help for help"))
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if(!checkforjvcs()) {
|
|
84
|
+
console.log(chalk.red("Repository is not initialized or is deleted. Please create it."))
|
|
85
|
+
return
|
|
71
86
|
}
|
|
87
|
+
|
|
88
|
+
const cwd = process.cwd()
|
|
89
|
+
const jvcsDir = path.join(cwd,".jvcs")
|
|
90
|
+
const commitDir = path.join(jvcsDir,"commits")
|
|
91
|
+
const reponame = path.basename(process.cwd())
|
|
92
|
+
|
|
93
|
+
if(!fs.existsSync(commitDir)) {
|
|
94
|
+
console.log(chalk.yellow("No commits to push"))
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// storing the name of commit folders
|
|
99
|
+
const commitFolders = fs.readdirSync(commitDir, {withFileTypes: true}).filter((e)=> e.isDirectory()).map((e)=> e.name)
|
|
100
|
+
if(commitFolders.length === 0) {
|
|
101
|
+
console.log(chalk.yellow('No commits to push'))
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
console.log(chalk.blue("Pushing commits of ",reponame," to cloud storage..."))
|
|
72
106
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// Upload commits
|
|
81
|
-
for (const commitDir of commitDirs) {
|
|
82
|
-
if (driveCommitNames.includes(commitDir)) {
|
|
83
|
-
console.log(chalk.yellow(`Commit '${commitDir}' already exists on Drive, skipping.`));
|
|
107
|
+
for(const commitId of commitFolders) {
|
|
108
|
+
|
|
109
|
+
const commitFolder = path.join(commitDir,commitId)
|
|
110
|
+
const metaPath = path.join(commitFolder,"meta.json")
|
|
111
|
+
|
|
112
|
+
if(!fs.existsSync(metaPath)) {
|
|
113
|
+
console.log(chalk.yellow(`Skipping ${commitId} (no meta.json found)`));
|
|
84
114
|
continue;
|
|
85
115
|
}
|
|
86
116
|
|
|
87
|
-
const
|
|
117
|
+
const metaData = JSON.parse(fs.readFileSync(metaPath,"utf-8"))
|
|
118
|
+
const { author, message, timeStamp } = metaData;
|
|
88
119
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
},
|
|
95
|
-
fields: "id, name"
|
|
96
|
-
});
|
|
97
|
-
const commitFolderId = commitFolderRes.data.id;
|
|
120
|
+
console.log(chalk.green(`\n Uploading commit:`));
|
|
121
|
+
console.log(chalk.gray(` id: ${commitId}`));
|
|
122
|
+
console.log(chalk.gray(` message: ${message}`));
|
|
123
|
+
console.log(chalk.gray(` author: ${author}`));
|
|
124
|
+
console.log(chalk.gray(` time: ${timeStamp}`));
|
|
98
125
|
|
|
99
|
-
await
|
|
126
|
+
const { commitFolderId : driveCommitId , commitAlreadyExists } = await getDirectoryStructure(configData.username,reponame,commitId)
|
|
127
|
+
|
|
128
|
+
if (commitAlreadyExists) {
|
|
129
|
+
console.log(chalk.yellow(`Skipping ${commitId} (already uploaded)`));
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
100
132
|
|
|
101
|
-
|
|
133
|
+
await uploadDirectory(commitFolder,driveCommitId)
|
|
134
|
+
console.log(chalk.green(`Commit ${commitId} uploaded successfully!`));
|
|
102
135
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
console.log(chalk.red("Error in pushCmd:"), error.message);
|
|
136
|
+
|
|
137
|
+
console.log(chalk.bold.green("\nAll commits pushed successfully!"));
|
|
106
138
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
async function uploadFolder(folderPath, parentId) {
|
|
111
|
-
const items = await fsPromises.readdir(folderPath);
|
|
112
|
-
for (const item of items) {
|
|
113
|
-
const fullPath = path.join(folderPath, item);
|
|
114
|
-
const stats = await fsPromises.stat(fullPath);
|
|
115
|
-
if (stats.isDirectory()) {
|
|
116
|
-
const folder = await drive.files.create({
|
|
117
|
-
requestBody: {
|
|
118
|
-
name: item,
|
|
119
|
-
mimeType: "application/vnd.google-apps.folder",
|
|
120
|
-
parents: [parentId]
|
|
121
|
-
},
|
|
122
|
-
fields: "id, name"
|
|
123
|
-
});
|
|
124
|
-
await uploadFolder(fullPath, folder.data.id);
|
|
125
|
-
} else {
|
|
126
|
-
await drive.files.create({
|
|
127
|
-
requestBody: { name: item, parents: [parentId] },
|
|
128
|
-
media: { body: fs.createReadStream(fullPath) },
|
|
129
|
-
fields: "id, name"
|
|
130
|
-
});
|
|
131
|
-
}
|
|
139
|
+
catch(error) {
|
|
140
|
+
console.log(chalk.red.bold("\nPush Failed"));
|
|
141
|
+
console.error(chalk.red(error.stack || error.message || error));
|
|
132
142
|
}
|
|
133
143
|
}
|
|
134
144
|
|
|
135
|
-
module.exports = pushCmd
|
|
145
|
+
module.exports = pushCmd
|
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const yargs = require("yargs");
|
|
4
4
|
const { hideBin } = require("yargs/helpers");
|
|
@@ -11,7 +11,9 @@ const initCmd = require("./controllers/init")
|
|
|
11
11
|
const addCmd = require("./controllers/add")
|
|
12
12
|
const commitCmd = require("./controllers/commit")
|
|
13
13
|
const unstageCmd = require("./controllers/unstage")
|
|
14
|
-
const logCmd = require("./controllers/log")
|
|
14
|
+
const logCmd = require("./controllers/log");
|
|
15
|
+
const pushCmd = require("./controllers/push");
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
yargs(hideBin(process.argv))
|
|
17
19
|
.scriptName("jvcs")
|
|
@@ -126,6 +128,19 @@ yargs(hideBin(process.argv))
|
|
|
126
128
|
}
|
|
127
129
|
}
|
|
128
130
|
)
|
|
131
|
+
.command(
|
|
132
|
+
"push",
|
|
133
|
+
"Push all the commits to remote",
|
|
134
|
+
{},
|
|
135
|
+
async ()=> {
|
|
136
|
+
try {
|
|
137
|
+
await pushCmd()
|
|
138
|
+
}
|
|
139
|
+
catch(error) {
|
|
140
|
+
console.log(chalk.red(error))
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
)
|
|
129
144
|
.demandCommand(1, chalk.yellow("You need at least one command"))
|
|
130
145
|
.help()
|
|
131
146
|
.parse();
|
package/package.json
CHANGED
package/controllers/pull.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const fsPromises = require("fs").promises;
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const chalk = require("chalk");
|
|
5
|
-
const { drive } = require("../config/drive-config");
|
|
6
|
-
const { checkInitialization, checkRepoExists, getCLIConfig } = require("./utils");
|
|
7
|
-
|
|
8
|
-
async function pullCmd(reponame) {
|
|
9
|
-
try {
|
|
10
|
-
if (!checkInitialization()) return;
|
|
11
|
-
if (!checkRepoExists(reponame)) return;
|
|
12
|
-
|
|
13
|
-
const repoPath = path.join(process.cwd(), `.${reponame}`);
|
|
14
|
-
const commitFolder = path.join(repoPath, "commits");
|
|
15
|
-
if (!fs.existsSync(commitFolder)) fs.mkdirSync(commitFolder, { recursive: true });
|
|
16
|
-
|
|
17
|
-
const config = await getCLIConfig();
|
|
18
|
-
if (!config) return console.log(chalk.red("Could not read CLI configuration."));
|
|
19
|
-
|
|
20
|
-
console.log(chalk.blue("Pulling commits for user:"), chalk.green(config.username));
|
|
21
|
-
|
|
22
|
-
// 1️⃣ Find user folder in Drive
|
|
23
|
-
const userFolderRes = await drive.files.list({
|
|
24
|
-
q: `name='${config.username}' and '1ahuoMCN_Ls5kGF2KPUGLbRZb9kGVMe0V' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
25
|
-
fields: "files(id, name)"
|
|
26
|
-
});
|
|
27
|
-
if (!userFolderRes.data.files.length) {
|
|
28
|
-
console.log(chalk.yellow("⚠ No user folder found on Drive."));
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
const userFolderId = userFolderRes.data.files[0].id;
|
|
32
|
-
|
|
33
|
-
// 2️⃣ Find repo folder in Drive
|
|
34
|
-
const repoFolderRes = await drive.files.list({
|
|
35
|
-
q: `name='${reponame}' and '${userFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
36
|
-
fields: "files(id, name)"
|
|
37
|
-
});
|
|
38
|
-
if (!repoFolderRes.data.files.length) {
|
|
39
|
-
console.log(chalk.yellow(`⚠ Repository '${reponame}' not found on Drive.`));
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const repoFolderId = repoFolderRes.data.files[0].id;
|
|
43
|
-
|
|
44
|
-
// 3️⃣ Get commit folders in Drive
|
|
45
|
-
const driveCommitsRes = await drive.files.list({
|
|
46
|
-
q: `'${repoFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
47
|
-
fields: "files(name, id)"
|
|
48
|
-
});
|
|
49
|
-
const driveCommits = driveCommitsRes.data.files;
|
|
50
|
-
if (!driveCommits.length) {
|
|
51
|
-
console.log(chalk.yellow("⚠ No commits found on Drive."));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// 4️⃣ Get local commit folders
|
|
56
|
-
const localCommits = await fsPromises.readdir(commitFolder);
|
|
57
|
-
|
|
58
|
-
// 5️⃣ Download only missing commits
|
|
59
|
-
for (const commit of driveCommits) {
|
|
60
|
-
if (localCommits.includes(commit.name)) {
|
|
61
|
-
console.log(chalk.gray(`✔ Commit '${commit.name}' already exists locally.`));
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
const localCommitPath = path.join(commitFolder, commit.name);
|
|
65
|
-
await fsPromises.mkdir(localCommitPath, { recursive: true });
|
|
66
|
-
await downloadFolder(commit.id, localCommitPath);
|
|
67
|
-
console.log(chalk.green(`⬇ Pulled new commit '${commit.name}' successfully.`));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
console.log(chalk.blue("Pull complete! Local repo is now up to date."));
|
|
71
|
-
|
|
72
|
-
} catch (error) {
|
|
73
|
-
console.log(chalk.red("Error in pullCmd:"), error.message);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Recursive folder download helper
|
|
78
|
-
async function downloadFolder(folderId, destPath) {
|
|
79
|
-
const res = await drive.files.list({
|
|
80
|
-
q: `'${folderId}' in parents and trashed=false`,
|
|
81
|
-
fields: "files(id, name, mimeType)"
|
|
82
|
-
});
|
|
83
|
-
for (const file of res.data.files) {
|
|
84
|
-
const localPath = path.join(destPath, file.name);
|
|
85
|
-
if (file.mimeType === "application/vnd.google-apps.folder") {
|
|
86
|
-
await fsPromises.mkdir(localPath, { recursive: true });
|
|
87
|
-
await downloadFolder(file.id, localPath);
|
|
88
|
-
} else {
|
|
89
|
-
const dest = fs.createWriteStream(localPath);
|
|
90
|
-
await drive.files.get({ fileId: file.id, alt: "media" }, { responseType: "stream" })
|
|
91
|
-
.then(res => new Promise((resolve, reject) => {
|
|
92
|
-
res.data.on("end", resolve).on("error", reject).pipe(dest);
|
|
93
|
-
}));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
module.exports = pullCmd;
|
package/controllers/revert.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const fsPromises = require("fs").promises;
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const { v4: uuidv4 } = require("uuid");
|
|
5
|
-
const chalk = require("chalk");
|
|
6
|
-
const { drive } = require("../config/drive-config");
|
|
7
|
-
const { checkInitialization, checkRepoExists, getCLIConfig } = require("./utils");
|
|
8
|
-
|
|
9
|
-
async function revertCmd(commitId, reponame) {
|
|
10
|
-
try {
|
|
11
|
-
if (!checkInitialization()) return;
|
|
12
|
-
if (!checkRepoExists(reponame)) return;
|
|
13
|
-
|
|
14
|
-
const repoPath = path.join(process.cwd(), `.${reponame}`);
|
|
15
|
-
const commitFolder = path.join(repoPath, "commits");
|
|
16
|
-
if (!fs.existsSync(commitFolder)) fs.mkdirSync(commitFolder, { recursive: true });
|
|
17
|
-
|
|
18
|
-
const config = await getCLIConfig();
|
|
19
|
-
if (!config) return console.log(chalk.red("Could not read CLI configuration."));
|
|
20
|
-
|
|
21
|
-
// 1️⃣ Get user folder
|
|
22
|
-
const userFolderRes = await drive.files.list({
|
|
23
|
-
q: `name='${config.username}' and '1ahuoMCN_Ls5kGF2KPUGLbRZb9kGVMe0V' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
24
|
-
fields: "files(id, name)"
|
|
25
|
-
});
|
|
26
|
-
if (!userFolderRes.data.files.length) return console.log(chalk.red("User folder not found on Drive."));
|
|
27
|
-
const userFolderId = userFolderRes.data.files[0].id;
|
|
28
|
-
|
|
29
|
-
// 2️⃣ Get repo folder
|
|
30
|
-
const repoFolderRes = await drive.files.list({
|
|
31
|
-
q: `name='${reponame}' and '${userFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
32
|
-
fields: "files(id, name)"
|
|
33
|
-
});
|
|
34
|
-
if (!repoFolderRes.data.files.length) return console.log(chalk.red("Repo folder not found on Drive."));
|
|
35
|
-
const repoFolderId = repoFolderRes.data.files[0].id;
|
|
36
|
-
|
|
37
|
-
// 3️⃣ Get commit folder
|
|
38
|
-
const commitRes = await drive.files.list({
|
|
39
|
-
q: `name='${commitId}' and '${repoFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
40
|
-
fields: "files(id, name)"
|
|
41
|
-
});
|
|
42
|
-
if (!commitRes.data.files.length) return console.log(chalk.red(`Commit '${commitId}' not found on Drive.`));
|
|
43
|
-
const driveCommitId = commitRes.data.files[0].id;
|
|
44
|
-
|
|
45
|
-
// 4️⃣ Create new revert commit folder locally
|
|
46
|
-
const newCommitId = `revert_${commitId}_${uuidv4()}`;
|
|
47
|
-
const newCommitPath = path.join(commitFolder, newCommitId);
|
|
48
|
-
await fsPromises.mkdir(newCommitPath, { recursive: true });
|
|
49
|
-
|
|
50
|
-
// 5️⃣ Recursively download commit files from Drive
|
|
51
|
-
await downloadFolderFromDrive(driveCommitId, newCommitPath);
|
|
52
|
-
|
|
53
|
-
// 6️⃣ Clean working directory (except hidden files)
|
|
54
|
-
const cwd = process.cwd();
|
|
55
|
-
const entries = await fsPromises.readdir(cwd);
|
|
56
|
-
for (const entry of entries) {
|
|
57
|
-
if (entry.startsWith(".")) continue;
|
|
58
|
-
await fsPromises.rm(path.join(cwd, entry), { recursive: true, force: true });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// 7️⃣ Copy new revert commit into working directory
|
|
62
|
-
await copyFolderRecursive(newCommitPath, cwd);
|
|
63
|
-
|
|
64
|
-
console.log(chalk.green(`Reverted to commit '${commitId}'. New revert commit: '${newCommitId}'`));
|
|
65
|
-
|
|
66
|
-
} catch (err) {
|
|
67
|
-
console.log(chalk.red("Error in revertCmd:"), err.message);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Recursive download helper
|
|
72
|
-
async function downloadFolderFromDrive(folderId, localPath) {
|
|
73
|
-
const res = await drive.files.list({
|
|
74
|
-
q: `'${folderId}' in parents and trashed=false`,
|
|
75
|
-
fields: "files(id, name, mimeType)"
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
for (const file of res.data.files) {
|
|
79
|
-
const filePath = path.join(localPath, file.name);
|
|
80
|
-
if (file.mimeType === "application/vnd.google-apps.folder") {
|
|
81
|
-
await fsPromises.mkdir(filePath, { recursive: true });
|
|
82
|
-
await downloadFolderFromDrive(file.id, filePath);
|
|
83
|
-
} else {
|
|
84
|
-
const destStream = fs.createWriteStream(filePath);
|
|
85
|
-
await new Promise((resolve, reject) => {
|
|
86
|
-
drive.files.get({ fileId: file.id, alt: "media" }, { responseType: "stream" }, (err, response) => {
|
|
87
|
-
if (err) return reject(err);
|
|
88
|
-
response.data.pipe(destStream).on("finish", resolve).on("error", reject);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Recursive copy helper
|
|
96
|
-
async function copyFolderRecursive(src, dest) {
|
|
97
|
-
const entries = await fsPromises.readdir(src, { withFileTypes: true });
|
|
98
|
-
for (const entry of entries) {
|
|
99
|
-
const srcPath = path.join(src, entry.name);
|
|
100
|
-
const destPath = path.join(dest, entry.name);
|
|
101
|
-
if (entry.isDirectory()) {
|
|
102
|
-
await fsPromises.mkdir(destPath, { recursive: true });
|
|
103
|
-
await copyFolderRecursive(srcPath, destPath);
|
|
104
|
-
} else {
|
|
105
|
-
await fsPromises.copyFile(srcPath, destPath);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
module.exports = revertCmd;
|