forked from desktop/desktop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate-tutorial-repository.ts
146 lines (126 loc) · 4.11 KB
/
create-tutorial-repository.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import * as Path from 'path'
import { Account } from '../../../models/account'
import { writeFile, pathExists, ensureDir } from 'fs-extra'
import { API } from '../../api'
import { APIError } from '../../http'
import {
executionOptionsWithProgress,
PushProgressParser,
} from '../../progress'
import { git } from '../../git'
import { friendlyEndpointName } from '../../friendly-endpoint-name'
import { IRemote } from '../../../models/remote'
import { envForRemoteOperation } from '../../git/environment'
const nl = __WIN32__ ? '\r\n' : '\n'
const InititalReadmeContents =
`# Welcome to GitHub Desktop!${nl}${nl}` +
`This is your README. READMEs are where you can communicate ` +
`what your project is and how to use it.${nl}${nl}` +
`Write your name on line 6, save it, and then head ` +
`back to GitHub Desktop.${nl}`
async function createAPIRepository(account: Account, name: string) {
const api = new API(account.endpoint, account.token)
try {
return await api.createRepository(
null,
name,
'GitHub Desktop tutorial repository',
true
)
} catch (err) {
if (
err instanceof APIError &&
err.responseStatus === 422 &&
err.apiError !== null
) {
if (err.apiError.message === 'Repository creation failed.') {
if (
err.apiError.errors &&
err.apiError.errors.some(
x => x.message === 'name already exists on this account'
)
) {
throw new Error(
'You already have a repository named ' +
`"${name}" on your account at ${friendlyEndpointName(
account
)}.\n\n` +
'Please delete the repository and try again.'
)
}
}
}
throw err
}
}
async function pushRepo(
path: string,
account: Account,
remote: IRemote,
progressCb: (title: string, value: number, description?: string) => void
) {
const pushTitle = `Pushing repository to ${friendlyEndpointName(account)}`
progressCb(pushTitle, 0)
const pushOpts = await executionOptionsWithProgress(
{
env: await envForRemoteOperation(account, remote.url),
},
new PushProgressParser(),
progress => {
if (progress.kind === 'progress') {
progressCb(pushTitle, progress.percent, progress.details.text)
}
}
)
const args = ['push', '-u', remote.name, 'master']
await git(args, path, 'tutorial:push', pushOpts)
}
/**
* Creates a repository on the remote (as specified by the Account
* parameter), initializes an empty repository at the given path,
* sets up the expected tutorial contents, and pushes the repository
* to the remote.
*
* @param path The path on the local machine where the tutorial
* repository is to be created
*
* @param account The account (and thereby the GitHub host) under
* which the repository is to be created created
*/
export async function createTutorialRepository(
account: Account,
name: string,
path: string,
progressCb: (title: string, value: number, description?: string) => void
) {
const endpointName = friendlyEndpointName(account)
progressCb(`Creating repository on ${endpointName}`, 0)
if (await pathExists(path)) {
throw new Error(
`The path '${path}' already exists. Please move it ` +
'out of the way, or remove it, and then try again.'
)
}
const repo = await createAPIRepository(account, name)
progressCb('Initializing local repository', 0.2)
await ensureDir(path)
await git(['init'], path, 'tutorial:init')
await writeFile(Path.join(path, 'README.md'), InititalReadmeContents)
await git(['add', '--', 'README.md'], path, 'tutorial:add')
await git(
['commit', '-m', 'Initial commit', '--', 'README.md'],
path,
'tutorial:commit'
)
const remote: IRemote = { name: 'origin', url: repo.clone_url }
await git(
['remote', 'add', remote.name, remote.url],
path,
'tutorial:add-remote'
)
await pushRepo(path, account, remote, (title, value, description) => {
progressCb(title, 0.3 + value * 0.6, description)
})
progressCb('Finalizing tutorial repository', 0.9)
return repo
}