Добавлена команда импорта 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("status", "Checking the status of tracked files"))
 | 
			
		||||
		.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 Argument("path", "Output directory path for the archive").required)
 | 
			
		||||
			.add(new Option("s", "snapshot", "Specify snapshot hash")
 | 
			
		||||
| 
						 | 
				
			
			@ -123,6 +147,14 @@ int main(string[] args)
 | 
			
		|||
					e.arg("path"),
 | 
			
		||||
					e.option("snapshot", ""),
 | 
			
		||||
				)
 | 
			
		||||
			)
 | 
			
		||||
			.on("import", i =>
 | 
			
		||||
				snag.importSnapshot(
 | 
			
		||||
					i.arg("archive"),
 | 
			
		||||
					i.option("comment", ""),
 | 
			
		||||
					i.option("author", ""),
 | 
			
		||||
					i.option("email", "")
 | 
			
		||||
				)
 | 
			
		||||
			);
 | 
			
		||||
	} catch (SnagException e) {
 | 
			
		||||
		e.print();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -290,4 +290,99 @@ class Snag {
 | 
			
		|||
		);
 | 
			
		||||
		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