-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathCloneMenu.cs
293 lines (247 loc) · 12.5 KB
/
CloneMenu.cs
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FileManager
{
public partial class CloneMenu : Form
{
private string path;
Form1 form1;
public CloneMenu(Form1 form)
{
InitializeComponent();
form1 = form;
textBox2.ReadOnly = true;
textBox3.ReadOnly = true;
textBox4.ReadOnly = true;
textBox5.ReadOnly = true;
button1.Enabled = false; // clone button
//button4.Enabled = false; // id-token button
label1.Text = "Input Git repository address to CLONE and click Check button";
label2.Text = "Destination Path";
label3.Text = "ID";
label4.Text = "Access Token";
label5.Text = "Check !";
button1.Text = "Clone";
button2.Text = "Exit";
button3.Text = "Check";
//button4.Text = "Check";
string[] data = { "public", "private" };
comboBox1.Items.AddRange(data);
label6.Text = "Repository property";
comboBox1.Enabled = false;
}
private void label1_Click(object sender, EventArgs e)
{
}
public void SetTextBeforeClone(string path)
{
textBox2.Text = path;
}
private void label2_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
private void button1_Click(object sender, EventArgs e) // clone button click
{
repoClone(textBox2.Text, textBox1.Text); // clone 버튼 클릭하면 clone하기 - private / public, 경로, 주소
}
private void storeIDandToken(string pathtoclone, string dir, string ID, string token) // 만들어진 .git 내에 생성
{
ProcessStartInfo cmd = new ProcessStartInfo();
Process process = new Process();
cmd.FileName = @"cmd";
cmd.WindowStyle = ProcessWindowStyle.Hidden; // cmd창이 숨겨지도록 하기
cmd.CreateNoWindow = true; // cmd창을 띄우지 안도록 하기
cmd.UseShellExecute = false;
cmd.RedirectStandardOutput = true; // cmd창에서 데이터를 가져오기
cmd.RedirectStandardInput = true; // cmd창으로 데이터 보내기
cmd.RedirectStandardError = true; // cmd창에서 오류 내용 가져오기
process.EnableRaisingEvents = false;
process.StartInfo = cmd;
process.Start();
process.StandardInput.Write(@"cd " + pathtoclone + Environment.NewLine);
process.StandardInput.Write(@"cd " + dir + Environment.NewLine);
process.StandardInput.Write(@"cd " + ".git" + Environment.NewLine); // .git 내부로 이동
process.StandardInput.Write(@"echo " + ID + " " + token + ">> new.txt " + Environment.NewLine);
process.StandardInput.Write(@"" + ID + " " + token + Environment.NewLine);
// 명령어를 보낼때는 꼭 마무리를 해줘야 한다. 그래서 마지막에 NewLine가 필요하다
process.StandardInput.Close();
}
private bool cloneCmd(string path, string repoAddress)
{
// repoAddress가 public이면 입력받은 address로 그냥 오고 private이면 변형되어서 올 것임
string[] cloneError;
ProcessStartInfo cmd = new ProcessStartInfo();
Process process = new Process();
cmd.FileName = @"cmd";
cmd.WindowStyle = ProcessWindowStyle.Hidden; // cmd창이 숨겨지도록 하기
cmd.CreateNoWindow = true; // cmd창을 띄우지 안도록 하기
cmd.UseShellExecute = false;
cmd.RedirectStandardOutput = true; // cmd창에서 데이터를 가져오기
cmd.RedirectStandardInput = true; // cmd창으로 데이터 보내기
cmd.RedirectStandardError = true; // cmd창에서 오류 내용 가져오기
process.EnableRaisingEvents = false;
process.StartInfo = cmd;
process.Start();
process.StandardInput.Write(@"cd " + path + Environment.NewLine);
process.StandardInput.Write(@"git clone " + repoAddress + Environment.NewLine);
// 명령어를 보낼때는 꼭 마무리를 해줘야 한다. 그래서 마지막에 NewLine가 필요하다
process.StandardInput.Close();
string errorOutput = process.StandardError.ReadToEnd();
cloneError = errorOutput.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
// git clone 후 error 메시지를 받음
process.WaitForExit();
process.Close();
//this.Close();
bool successClone = true;
foreach(string output in cloneError)
{
if(output.Contains("fatal")) {
successClone = false; // success 하게 clone 실패했다고 출력
}
}
form1.setTextAfterClone(successClone, cloneError);
return successClone;
}
private void repoClone(string path, string address)
{
string repoAddress = address;
//bool publicRepo = true;
if(comboBox1.SelectedItem.ToString() == "private") // private이면 주소에 수정 필요하다
{
//publicRepo = false;
int Index = address.IndexOf("/");
// id, token 입력한 것 확인하기
if (textBox3.Text.Equals("") || textBox4.Text.Equals("")) // 둘 중 하나라도 empty이면 안됨
{
textBox5.Text = "Check your id, access token. Invalid input exists.";
}
else // 둘 다 입력이 되었음
{
// "https://"github.com, id, token 넣기 위해서 잘라서 넣기
repoAddress = "https://" + textBox3.Text + ":" + textBox4.Text + "@" + address.Substring(Index + 2);
//cloneCmd(path, repoAddress); // private repository를 cmd로 clone
string reversedAddress = new String(address.Reverse().ToArray());
// string을 뒤집고 .git을 거꾸로한 것을 자르고 첫번째 /까지 자르면 repo 이름 생성
int reversedIndex = reversedAddress.IndexOf("/"); // 첫번째 /
string cloneDir = new String(reversedAddress.Substring(4, reversedIndex - 4).Reverse().ToArray());
bool cloneSuccessFlag = cloneCmd(path, repoAddress); // private repository를 cmd로 clone, 잠시 확인, 지울 예정
if(cloneSuccessFlag)
{
storeIDandToken(path, cloneDir, textBox3.Text, textBox4.Text); // clone에 성공했을 때만 적어야 함
}
this.Close();
}
}
else // public일 때 그냥 수행
{
cloneCmd(path, repoAddress);
this.Close();
}
}
private void button3_Click(object sender, EventArgs e) // 주소 옆에 있는 check button click
{
textBox5.Text = string.Empty;
if(textBox1.Text == "") // repository input nothing
{
textBox5.Text = "fatal: You must specify a repository to clone.";
}
else
{
string pattern = @"^https:\/\/github\.com\/.+\/.+\.git$"; // valid address check
bool isMatch = System.Text.RegularExpressions.Regex.IsMatch(textBox1.Text, pattern);
if (!isMatch ) { // invalid address
textBox5.Text = "fatal: repository \'" + textBox1.Text + "\'" + " does not exist";
}
else // valid address, check private or public
{
comboBox1.Enabled = true; // valid address니까 public/private check 할 수 있도록 checkbox active
textBox1.ReadOnly = true;
textBox5.Text = "Valid address. Choose your Repository property.";
comboBox1.Focus();
}
}
}
private bool repoPublicCheck(string path, string address) // invitation 받지 않은 private repo 확인용
{
string[] privateRepo;
ProcessStartInfo cmd = new ProcessStartInfo();
Process process = new Process();
cmd.FileName = @"cmd";
cmd.WindowStyle = ProcessWindowStyle.Hidden; // cmd창이 숨겨지도록 하기
cmd.CreateNoWindow = true; // cmd창을 띄우지 안도록 하기
cmd.UseShellExecute = false;
cmd.RedirectStandardOutput = true; // cmd창에서 데이터를 가져오기
cmd.RedirectStandardInput = true; // cmd창으로 데이터 보내기
cmd.RedirectStandardError = true; // cmd창에서 오류 내용 가져오기
process.EnableRaisingEvents = false;
process.StartInfo = cmd;
process.Start();
process.StandardInput.Write(@"cd " + path + Environment.NewLine);
process.StandardInput.Write(@"git ls-remote --exit-code --quiet " + address + Environment.NewLine);
// 명령어를 보낼때는 꼭 마무리를 해줘야 한다. 그래서 마지막에 NewLine가 필요하다 ls-remote --exit-code --quiet
process.StandardInput.Close();
string errorOutput = process.StandardError.ReadToEnd();
privateRepo = errorOutput.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
process.WaitForExit();
process.Close();
bool flag = true;
foreach(string line in privateRepo)
{
if (line.Equals("remote: Repository not found.")) // private이면 error가 출력됨
{
flag = false;
textBox5.Text = "Private Repository: Input your ID and Access Token."; // private을 clone 시도할 때 id, token을 입력해야함
}
}
return flag;
}
private void button4_Click(object sender, EventArgs e)
{
if(textBox3.Text.Equals("") || textBox4.Text.Equals("")) // 둘 중 하나라도 empty이면 안됨
{
textBox5.Text = "Private Repository: Check your id, access token. Invalid input exists.";
}
else // 둘 다 값이 채워져 있을 때
{
textBox5.Text = "You can clone " + "\"" + textBox1.Text + "\"" + " in " + textBox2.Text;
button1.Enabled = true; // clone 버튼 누를 수 있도록 하기
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// combobox의 값이 변경될 때 호출되는 이벤트
if(comboBox1.SelectedItem.ToString() == "public") //public 선택하면 clone 버튼 활성화
{
textBox3.ReadOnly = true;
textBox4.ReadOnly = true; // id, token 활성화
button1.Enabled = true; //clone 버튼 활성화
textBox5.Text = "You can clone " + "\"" + textBox1.Text + "\"" + " in " + textBox2.Text;
button1.Focus();
}
else if(comboBox1.SelectedItem.ToString() == "private") // private 선택하면 id, token 활성화
{
textBox3.ReadOnly = false;
textBox4.ReadOnly = false; // id, token 활성화
//button4.Enabled = true; // check button, 없애
button1.Enabled = true; //clone 버튼 활성화
textBox5.Text = "Input your ID and Access Token to clone private repository.";
textBox3.Focus();
}
}
}
}