Добавлена команда импорта import из архива tar.gz
This commit is contained in:
		
							parent
							
								
									cc85cdec78
								
							
						
					
					
						commit
						9c4c2c9d05
					
				
					 2 changed files with 127 additions and 0 deletions
				
			
		
							
								
								
									
										32
									
								
								source/app.d
									
										
									
									
									
								
							
							
						
						
									
										32
									
								
								source/app.d
									
										
									
									
									
								
							| 
						 | 
					@ -18,6 +18,30 @@ int main(string[] args)
 | 
				
			||||||
		.add(new Command("init", "Initializing the repository for storing snapshots"))
 | 
							.add(new Command("init", "Initializing the repository for storing snapshots"))
 | 
				
			||||||
		.add(new Command("status", "Checking the status of tracked files"))
 | 
							.add(new Command("status", "Checking the status of tracked files"))
 | 
				
			||||||
		.add(new Command("diff", "Show changed data"))
 | 
							.add(new Command("diff", "Show changed data"))
 | 
				
			||||||
 | 
							.add(new Command("import", "Import snapshot from a tar.gz archive")
 | 
				
			||||||
 | 
								.add(new Argument("archive", "The path to the tar.gz archive file").required)
 | 
				
			||||||
 | 
								.add(new Option("c", "comment", "Specify comment")
 | 
				
			||||||
 | 
									.optional
 | 
				
			||||||
 | 
									.validateEachWith(
 | 
				
			||||||
 | 
										opt => opt.length > 0,
 | 
				
			||||||
 | 
										"cannot be empty"
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
								.add(new Option("a", "author", "Specify author")
 | 
				
			||||||
 | 
									.optional
 | 
				
			||||||
 | 
									.validateEachWith(
 | 
				
			||||||
 | 
										opt => opt.length > 0,
 | 
				
			||||||
 | 
										"cannot be empty"
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
								.add(new Option("e", "email", "Specify email")
 | 
				
			||||||
 | 
									.optional
 | 
				
			||||||
 | 
									.validateEachWith(
 | 
				
			||||||
 | 
										opt => opt.isValidEmail,
 | 
				
			||||||
 | 
										"must contain an email address"
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
		.add(new Command("export", "Export snapshot to a tar.gz archive")
 | 
							.add(new Command("export", "Export snapshot to a tar.gz archive")
 | 
				
			||||||
			.add(new Argument("path", "Output directory path for the archive").required)
 | 
								.add(new Argument("path", "Output directory path for the archive").required)
 | 
				
			||||||
			.add(new Option("s", "snapshot", "Specify snapshot hash")
 | 
								.add(new Option("s", "snapshot", "Specify snapshot hash")
 | 
				
			||||||
| 
						 | 
					@ -123,6 +147,14 @@ int main(string[] args)
 | 
				
			||||||
					e.arg("path"),
 | 
										e.arg("path"),
 | 
				
			||||||
					e.option("snapshot", ""),
 | 
										e.option("snapshot", ""),
 | 
				
			||||||
				)
 | 
									)
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
								.on("import", i =>
 | 
				
			||||||
 | 
									snag.importSnapshot(
 | 
				
			||||||
 | 
										i.arg("archive"),
 | 
				
			||||||
 | 
										i.option("comment", ""),
 | 
				
			||||||
 | 
										i.option("author", ""),
 | 
				
			||||||
 | 
										i.option("email", "")
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
	} catch (SnagException e) {
 | 
						} catch (SnagException e) {
 | 
				
			||||||
		e.print();
 | 
							e.print();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -290,4 +290,99 @@ class Snag {
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
		writeln("Export to archive completed successfully: ", file);
 | 
							writeln("Export to archive completed successfully: ", file);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void importSnapshot(string path, string comment, string author, string email) {
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								(!path.isFile || !path.endsWith("tar.gz")) &&
 | 
				
			||||||
 | 
									throw new SnagException(
 | 
				
			||||||
 | 
											"Path is not an archive file"
 | 
				
			||||||
 | 
										);
 | 
				
			||||||
 | 
							} catch (Exception e) {
 | 
				
			||||||
 | 
								throw new SnagException(
 | 
				
			||||||
 | 
										"Failed to verify the archive file:\n\t"
 | 
				
			||||||
 | 
										~ e.msg
 | 
				
			||||||
 | 
									);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							string newBranch = _date ~ "-import";
 | 
				
			||||||
 | 
							string tempDirectory = tempDir().buildPath(newBranch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mkdir(tempDirectory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							scope(exit) tempDirectory.exists
 | 
				
			||||||
 | 
									&& tempDirectory.isDir
 | 
				
			||||||
 | 
									&& tempDirectory.rmdirRecurse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto result = execute([
 | 
				
			||||||
 | 
								"tar", "xf", path, "-C", tempDirectory
 | 
				
			||||||
 | 
							]);
 | 
				
			||||||
 | 
							result.status &&
 | 
				
			||||||
 | 
								throw new SnagException(
 | 
				
			||||||
 | 
									"The error occurred during decompression (or unpacking) of the archive:\n\t"
 | 
				
			||||||
 | 
									~ result.output.split('\n')[0]
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Выполнение git команд относительно распакованного архива
 | 
				
			||||||
 | 
							string[] customCommand = format(
 | 
				
			||||||
 | 
								"git --git-dir=%s --work-tree=%s",
 | 
				
			||||||
 | 
								_config.git, tempDirectory
 | 
				
			||||||
 | 
							).split();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Необходимо проверить, что текущее состояние файлов не идентично файлам распакованного архива
 | 
				
			||||||
 | 
							result = execute(customCommand ~ ["status", "--porcelain"]);
 | 
				
			||||||
 | 
							result.status &&
 | 
				
			||||||
 | 
								throw new SnagException(
 | 
				
			||||||
 | 
									"An error occurred while checking the file tracking status:\n"
 | 
				
			||||||
 | 
									~ result.output.split('\n')[0]
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Если текущее состояние файлов идентично файлам распакованного архива
 | 
				
			||||||
 | 
							!result.output.length &&
 | 
				
			||||||
 | 
								throw new SnagException(
 | 
				
			||||||
 | 
									"Import aborted:\n\t"
 | 
				
			||||||
 | 
									~ "The new state of the files is up to date as of the current snapshot"
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							git(
 | 
				
			||||||
 | 
								["checkout", "--orphan", newBranch ],
 | 
				
			||||||
 | 
								"Failed to create a branch from the new state"
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Создание нового снимка на основе состояния файлов из распакованного архива
 | 
				
			||||||
 | 
							result = execute(customCommand ~ ["add", "."]);
 | 
				
			||||||
 | 
							result.status &&
 | 
				
			||||||
 | 
								throw new SnagException(
 | 
				
			||||||
 | 
									"Failed to prepare files for archiving:\n"
 | 
				
			||||||
 | 
									~ result.output.split('\n')[0]
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							author.length && (environment["GIT_AUTHOR_NAME"] = author);
 | 
				
			||||||
 | 
							email.length && (environment["GIT_AUTHOR_EMAIL"] = email);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							string message = comment.length ? comment : "Creating a snapshot from import";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							result = execute(customCommand ~ ["commit", "-m"] ~ message);
 | 
				
			||||||
 | 
							result.status &&
 | 
				
			||||||
 | 
								throw new SnagException(
 | 
				
			||||||
 | 
									"Failed to create a snapshot:\n"
 | 
				
			||||||
 | 
									~ result.output.split('\n')[0]
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Сброс состояния файлов
 | 
				
			||||||
 | 
							git(
 | 
				
			||||||
 | 
								["restore", "."],
 | 
				
			||||||
 | 
								"Failed to reset file changes state"
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
							git(
 | 
				
			||||||
 | 
								["clean", "-fd"],
 | 
				
			||||||
 | 
								"Failed to clean untracked files"
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							string newSnapshot = git(
 | 
				
			||||||
 | 
								["rev-parse", "--short", "HEAD"],
 | 
				
			||||||
 | 
								"Failed to retrieve current snapshot information"
 | 
				
			||||||
 | 
							).output.strip('\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							writeln("Import completed successfully: ", newSnapshot);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue