aboutsummaryrefslogtreecommitdiffstats
path: root/cmso-service/extra/src/main/java/org/onap/optf/utilities/OnapInitialCommit.java
blob: 0abf9634fd420a316fcbb3c5dc24f220afb2391c (plain)
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
294
295
296
297
/*******************************************************************************
 * Copyright 2019 AT&T Intellectual Property.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.  You may obtain a copy
 * of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations under
 * the License.
 ******************************************************************************/
package org.onap.optf.utilities;
/**
 * Utility to split a single set of changes into multiple 'micro-commits'. Helpful for initial commits of new components
 * into the repo
 * 
 * This will 
 *  - determine how many commits are necessary
 *  - create working folders and clone the repo 'N' times
 *  - do git remote add gerrit 
 *  - copy each subset of files to the respective working clones
 *  - git add the new (updated?) files
 *  - git commit -m 
 *  
 *  Since this is a work in progess the git commit -as and git review are still manual to double check the results  
 *  
 *   
 *  
 * 
 * This code currently assumes a repos structure that containes ONLY the files to be committed. There is no attempt 
 * to identify new/changed files to commit. Preparation of the list of files is manual.
 * 
 * This does not make any attempt to determine if this will break the build. 
 *  
 * Caution. This code was developed and tested in Windows. WIndows paths to GIT bash, etc. are hard coded.     
 *  
 */

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FilenameUtils;




public class OnapInitialCommit 
{
	CommandLine cmdline = null;
	Long lpc = 1000l;
	
	Map<String, Long> fileMap = new TreeMap<String, Long>();
	List<List<String>> commitLists = new ArrayList<>();
	public static void main(String []argv)
	{
		Options options = new Options();
		options.addRequiredOption("r", "repoFolder", true, "Folder containing all of the files to commit.");
		options.addRequiredOption("f", "filesFolder", true, "Folder containing all files to commit - relative to repo folder");
		options.addRequiredOption("w", "commitReposFolder", true, "Folder where all of the commit repos are created");
		options.addRequiredOption("c", "cloneCommand", true, "Clone with commit hooks command - with credentials");
		options.addRequiredOption("g", "remoteAddGerrit", true, "git remote add gerrit command");
		options.addRequiredOption("i", "issue", true, "Issue ID");
		options.addRequiredOption("m", "message", true, "Commit message");
		options.addRequiredOption("p", "clonePath", true, "Path created in commitRepoFolder by the clone command");
		
		options.addOption("l", "linesPerCommit", true, "lines to commit");
		CommandLineParser parser = new DefaultParser();
		try {
			CommandLine cmd = parser.parse( options, argv);
			OnapInitialCommit oic = new OnapInitialCommit(cmd);
			oic.execute();
		} catch (ParseException e) {
			System.out.println(e.getMessage());
			HelpFormatter formatter = new HelpFormatter();
			formatter.printHelp( "OnapIntialCommit", options );
			
		}
	}


	public OnapInitialCommit(CommandLine cmd) 
	{
		cmdline = cmd;
	}
	private void execute() 
	{
		buildCommitLists();

		int i = 0;
		for (List<String> list : commitLists)
		{
			i++;
			commit(list, i);
		}
		
	}


	private void commit(List<String> list, int i) 
	{
		if (list.size() == 0)
			return;
		System.out.println("\n\n");
		for (String name : list)
		{
			System.out.println(name + ":" + fileMap.get(name));
		}
		File cloneFolder = new File(cmdline.getOptionValue("w") + File.separator + "commit" + i);
		cloneFolder.mkdirs();
		cloneCode(cloneFolder, i);
		System.out.println("\n\n");
		File fromFolder = new File(cmdline.getOptionValue("r"));
		List<String> filesToAdd = new ArrayList<>();
		for (String fromFile : list)
		{
			String toPath = fromFile.replace(fromFolder.getAbsolutePath(), "");
			
			Path toFile = Paths.get(cloneFolder + File.separator + "cmso" +  toPath); 
			System.out.println(fromFile  + ":" + toFile);
			try {
				toFile.toFile().mkdirs();
				Files.copy(Paths.get(fromFile), toFile, StandardCopyOption.REPLACE_EXISTING);
				filesToAdd.add(toPath);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		commitFiles(cloneFolder, filesToAdd, i);
	}


	private void cloneCode(File cloneFolder, int i) 
	{
		String unixCloneFolder = FilenameUtils.separatorsToUnix(cloneFolder.getAbsolutePath());
		unixCloneFolder = unixCloneFolder.replace("c:", "/c");
		StringBuilder shell = new StringBuilder();
		shell.append("cd \"").append(unixCloneFolder).append("\"\n");
		shell.append("export PATH=$PATH:\"/C/Program Files/Git/mingw64/bin\"").append("\n");
		shell.append(cmdline.getOptionValue("c")).append("\n");
		shell.append("cd ").append(cmdline.getOptionValue("p")).append("\n");
		shell.append(cmdline.getOptionValue("g")).append("\n");
		File shellFile = new File("oic.sh");
		File shellFileOut = new File("oic.log." + i);
		try {
			Files.write(Paths.get(shellFile.getAbsolutePath()), shell.toString().getBytes());
			String command = "\"C:\\Program Files\\Git\\bin\\bash.exe\" -x " + shellFile.getAbsolutePath(); 
			
			ProcessBuilder builder = new ProcessBuilder("C:\\Program Files\\Git\\bin\\bash.exe", "-x", shellFile.getAbsolutePath());
			builder.redirectOutput(shellFileOut);
			builder.redirectError(shellFileOut);
			Process p = builder.start(); // may throw IOException
			p.waitFor();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	private void commitFiles(File cloneFolder, List<String> list, int i) 
	{
		String unixCloneFolder = FilenameUtils.separatorsToUnix(cloneFolder.getAbsolutePath());
		unixCloneFolder = unixCloneFolder.replace("c:", "/c");
		StringBuilder shell = new StringBuilder();
		shell.append("cd \"").append(unixCloneFolder).append("\"\n");
		shell.append("export PATH=$PATH:\"/C/Program Files/Git/mingw64/bin\"").append("\n");
		shell.append("cd ").append(cmdline.getOptionValue("p")).append("\n");
		for (String name : list)
		{
			name = FilenameUtils.separatorsToUnix(name);
			name = name.replaceAll("^/", "");
			shell.append("git add ").append(name).append("\n");
		}
		shell.append("git commit -m \"Commit ").append(i).append(" for ").append(cmdline.getOptionValue("m"));
		shell.append("\" -m \"Multiple commits required due to commit size limitation.\" -m \"");
		shell.append("Issue-ID: ").append(cmdline.getOptionValue("i")).append("\"\n");
		
		File shellFile = new File("addFiles" + i + ".sh");
		File shellFileOut = new File("addFiles" + i + ".log");
		try {
			Files.write(Paths.get(shellFile.getAbsolutePath()), shell.toString().getBytes());
			String command = "\"C:\\Program Files\\Git\\bin\\bash.exe\" -x " + shellFile.getAbsolutePath(); 
			
			ProcessBuilder builder = new ProcessBuilder("C:\\Program Files\\Git\\bin\\bash.exe", "-x", shellFile.getAbsolutePath());
			builder.redirectOutput(shellFileOut);
			builder.redirectError(shellFileOut);
			Process p = builder.start(); // may throw IOException
			p.waitFor();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}


	private void buildCommitLists() 
	{
		File files = new File(cmdline.getOptionValue("r") + File.separator + cmdline.getOptionValue("f"));
		if (files.isDirectory())
		{
			buildCommitMap(files);
			List<String> l = new ArrayList<>();
			long size = 0;
			for (String name : fileMap.keySet())
			{
				Long thisSize = fileMap.get(name);
				System.out.println(thisSize + " : " + name);
				if ((size +  thisSize) > lpc )
				{
					commitLists.add(l);
					l = new ArrayList<>();
					size = 0;
				}
				size+=thisSize;
				l.add(name);
			}
			commitLists.add(l);
		}
	}


	private void buildCommitMap(File files) 
	{
		for (File thisOne : files.listFiles())
		{
			if (thisOne.isDirectory())
				buildCommitMap(thisOne);
			else
				updateMap(thisOne);
		}
		
	}


	private void updateMap(File thisOne) 
	{
		//System.out.println(thisOne.getAbsolutePath());
		Path path = Paths.get(thisOne.getAbsolutePath());
		long lineCount = -1;
		Charset[] csList = {
				StandardCharsets.UTF_8,
				StandardCharsets.ISO_8859_1,
				StandardCharsets.US_ASCII,
				StandardCharsets.UTF_16,
		};
		for (Charset cs : csList)
		{
			try {
				lineCount = Files.lines(path, cs).count();
				if (lineCount > 1)
					break;
			} catch (Exception e) {
				//System.out.println(thisOne.getAbsolutePath());
			}
		}
		if (lineCount > -1)
		{
			fileMap.put(thisOne.getAbsolutePath(), lineCount);
		}
		else
		{
			System.out.println("Skipping " +  thisOne.getAbsolutePath());
		}
	}
	
	
}