def copy_to_branch(self, name): self.load_config() di = DirectoryInfo() from_commits_path = di.get_commits_path(self.name) to_branch_path = di.get_commits_path(name) if os.path.exists(to_branch_path): shutil.rmtree(to_branch_path) shutil.copytree(from_commits_path, to_branch_path) branch_to = Branch(name) branch_to.init_config() branch_to.set_current_commit(self.get_current_commit())
class TestRepository(unittest.TestCase): def setUp(self) -> None: self.di = DirectoryInfo() path = os.getcwd() self.di.init(path) self.di.add_branch_path('master') self.file_path = os.path.join(self.di.working_path, 'TESTING.txt') with open(self.file_path, "w+") as file: file.write('SOME STRING') self.rep = Repository() self.rep.set_directory_info(self.di) self.rep.init() def tearDown(self) -> None: if os.path.exists(self.di.cvs_path): shutil.rmtree(self.di.cvs_path) if os.path.exists(self.file_path): os.remove(self.file_path) def test_add_commit__should_copy_commit_files(self): index = Index() index.init_config() index.set_directory_info(self.di) index.add_new_file('TESTING.txt') commit = index.make_commit('Testing commit', 'master') self.rep.add_commit(commit) commits_path = self.di.get_commits_path('master') commit_path = os.path.join(commits_path, commit.commit_number) full_path = os.path.join(commit_path, 'TESTING.txt') self.assertTrue(os.path.exists(full_path))
def init_config(self): di = DirectoryInfo() commits = di.get_commits_path(self.branch_name) fullpath = os.path.join(commits, self.commit_number) if not os.path.exists(fullpath): os.makedirs(fullpath) path = os.path.join(fullpath, 'commit.ini') config = configparser.ConfigParser() config['info'] = {} config['info']['branch'] = self.branch_name config['info']['message'] = self.commit_message config['info']['number'] = self.commit_number config['info']['previous'] = self.__previous_commit_number config['info']['time'] = str(datetime.datetime.now()) config['copy'] = {} for file, file_path in self.__files_with_copying_paths.items(): config['copy'][file] = file_path config['hash'] = {} for file, hashcode in self.__files_hashes.items(): config['hash'][file] = hashcode config['versions'] = {} for file, version in self.__files_versions.items(): config['versions'][file] = version open(path, 'a').close() with open(path, 'w') as cfg_file: config.write(cfg_file)
def make_commit_from_config(commit_number, branch_name): di = DirectoryInfo() commits = di.get_commits_path(branch_name) path = os.path.join(commits, commit_number, 'commit.ini') commit = Commit('none') commit.branch_name = branch_name commit.get_data_from_config(path) return commit
def load_config(self): di = DirectoryInfo() commits = di.get_commits_path(self.branch_name) path = os.path.join(commits, self.commit_number, 'commit.ini') config = configparser.ConfigParser() config.optionxform = str config.read(path) self.config = config self.get_data_from_config(path)
def update(self, filename, version): found_number = self.find_commit_file_version_number(filename, version) if found_number == '': return di = DirectoryInfo() branch_path = di.get_commits_path(self.name) commit_path = os.path.join(branch_path, found_number) file_repo = os.path.join(commit_path, filename) file_origin = os.path.join(di.working_path, filename) copyfile(file_repo, file_origin) print(f'File {filename} version is now {version}')
def add_commit(self, commit): """Adds new commit to last branch, copying files""" di = DirectoryInfo() self.load_config() for file in commit.files_with_copying_paths: path = commit.files_with_copying_paths[file] commits_path = di.get_commits_path(self.__current_branch_name) commit_path = os.path.join(commits_path, commit.commit_number) if not os.path.exists(commit_path): os.makedirs(commit_path) copy_path = os.path.join(commit_path, file) copyfile(path, copy_path) file_hash = commit.files_hashes[file] print(f'File {file} saved - {file_hash}') commit.set_previous_commit_number(self.last_commit_number) self.last_commit_number = commit.commit_number self.config['info']['last_commit'] = commit.commit_number branch = Branch.make_branch_from_config(self.__current_branch_name) branch.set_current_commit(commit) self.save_config()
def diff(self, filename, first_version, second_version): di = DirectoryInfo() first_number = self.find_commit_file_version_number(filename, first_version) second_number = self.find_commit_file_version_number(filename, second_version) if first_number == '' or second_number == '': return branch_path = di.get_commits_path(self.name) first_commit_path = os.path.join(branch_path, first_number) second_commit_path = os.path.join(branch_path, second_number) first_file_path = os.path.join(first_commit_path, filename) second_file_path = os.path.join(second_commit_path, filename) first_file = open(first_file_path).readlines() second_file = open(second_file_path).readlines() print('_' * 40) print(f'Diff between {filename}: {first_version} and {second_version}') for line in difflib.unified_diff(first_file, second_file): print(line)
class DirectoryInfoTest(unittest.TestCase): def setUp(self) -> None: self.info = DirectoryInfo() self.info.init(os.getcwd()) def test_init_should_initialize_working_path(self): result = self.info.working_path self.assertIsNotNone(result) def test_init_should_initialize_cvs_path(self): result = self.info.cvs_path self.assertTrue(result.endswith('CVS')) def test_init_should_initialize_index_path(self): result = self.info.index_path self.assertTrue(result.endswith('INDEX')) def test_add_branch_path_should_add_path_to_branch(self): self.info.add_branch_path("master") count = len(self.info.branches_paths) self.assertGreater(count, 0) def test_add_branch_path_should_add_path_to_commits(self): self.info.add_branch_path("master") count = len(self.info.branches_commits_paths) self.assertGreater(count, 0) def test_get_branch_path_should_get_path_to_branch(self): self.info.add_branch_path("master") path = self.info.get_branch_path("master") self.assertTrue(path.endswith("master")) def test_get_commits_path_should_get_commits_path(self): self.info.add_branch_path("master") path = self.info.get_commits_path("master") self.assertTrue(path.endswith("COMMITS"))
def delete_commit(self): di = DirectoryInfo() commits = di.get_commits_path(self.branch_name) fullpath = os.path.join(commits, self.commit_number) if os.path.exists(fullpath): shutil.rmtree(fullpath)
def save_config(self): di = DirectoryInfo() commits = di.get_commits_path(self.branch_name) path = os.path.join(commits, self.commit_number, 'commit.ini') with open(path, 'w') as f: self.config.write(f)
class Index: def __init__(self): self.__indexed_files = set() self.__last_commit = None self.__directory = DirectoryInfo() self.config = configparser.ConfigParser() @property def indexed_files(self): self.load_config() return copy.copy(self.__indexed_files) @property def last_commit(self): self.load_config() return self.__last_commit def set_directory_info(self, directory_info: DirectoryInfo): """Sets current __directory info""" self.__directory = directory_info def add_new_file(self, filename): """Adds new file, copying it to /CVS/INDEX/...""" self.load_config() if not self.__is_file_in_working_directory(filename): path = os.path.join(self.__directory.working_path, filename) raise FileNotFoundError(f"No such file '{filename}' in '{path}'!") self.__indexed_files.add(filename) files = self.config['info']['files'] self.config['info']['files'] = f'{files},{filename}'.strip(',') source_file = os.path.join(self.__directory.working_path, filename) file_copy = os.path.join(self.__directory.index_path, filename) copyfile(source_file, file_copy) print(f'File {source_file} added') self.save_config() def __is_file_in_working_directory(self, filename) -> bool: """Checks if file is in working __directory""" return os.path.exists(os.path.join(self.__directory.working_path, filename)) def make_commit(self, commit_message, branch_name) -> Commit: """ Makes commit, freezing current files state :returns Commit """ self.load_config() commit = Commit(commit_message) commit.branch_name = branch_name commit.init_config() branch = Branch.make_branch_from_config(branch_name) prev_commit = branch.get_current_commit() if prev_commit is not None: commit_number = prev_commit.commit_number commit.set_previous_commit_number(commit_number) commit.freeze_files(self.__indexed_files, self.__directory) self.__last_commit = commit self.config['info']['files'] = '' self.config['info']['last_commit'] = commit.commit_number self.config['info']['last_commit_branch'] = commit.branch_name self.save_config() return commit def reset(self, head: Head): """Resets index to last commit that head is pointing to""" self.load_config() commit = head.current_branch.get_current_commit() print('Index reset') for file in commit.files: branch_name = head.current_branch.name commits_path = self.__directory.get_commits_path(branch_name) commit_path = os.path.join(commits_path, commit.commit_number) source_path = os.path.join(commit_path, file) copy_path = os.path.join(self.__directory.index_path, file) copyfile(source_path, copy_path) print(f'Copied file from {source_path} to {copy_path}') self.__indexed_files = commit.files conf_files = '' for file in commit.files: conf_files += file self.config['info']['files'] = conf_files.strip(',') self.__last_commit = commit self.config['info']['last_commit'] = commit.commit_number self.config['info']['last_commit_branch'] = commit.branch_name self.save_config() def load_config(self): di = DirectoryInfo() config_path = os.path.join(di.index_path, 'index.ini') config = configparser.ConfigParser() config.read(config_path) config.optionxform = str self.config = config self.get_data_from_config(config_path) def get_data_from_config(self, config_path): config = configparser.ConfigParser() config.read(config_path) config.optionxform = str prev_commit_number = self.config['info']['last_commit'] prev_commit_branch = self.config['info']['last_commit_branch'] if prev_commit_number != 'None': commit = Commit.make_commit_from_config(prev_commit_number, prev_commit_branch) else: commit = 'None' self.__last_commit = commit files = config['info']['files'] if files != '': self.__indexed_files = set(files.split(',')) def save_config(self): di = DirectoryInfo() config_path = os.path.join(di.index_path, 'index.ini') with open(config_path, 'w') as f: self.config.write(f) def init_config(self): di = DirectoryInfo() path = os.path.join(di.index_path, 'index.ini') config = configparser.ConfigParser() config['info'] = {} config['info']['last_commit'] = 'None' config['info']['last_commit_branch'] = 'None' config['info']['files'] = '' with open(path, 'w') as cfg_file: config.write(cfg_file)