def test_apply_command_failed_to_execute_verbose(self, mock_ensure_object): params = { 'commands': [ 'rm test', ], 'actual_repositories': ['gameta', 'GitPython', 'gitdb'], } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.apply, ['--command', params['commands'][0], '-e', '-v']) self.assertEqual(result.exit_code, 1) self.assertTrue( "rm: cannot remove 'test': No such file or directory\n" in result.output)
def test_sync_repo_already_exists(self, mock_ensure_object): with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.sync) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f'Syncing all child repositories in metarepo {f}\n' 'Successfully synced GitPython to GitPython\n' "An error occurred Cmd('git') failed due to: exit code(128)\n" " cmdline: git clone -v https://github.com/gitpython-developers/gitdb.git core/gitdb\n" " stderr: 'fatal: destination path 'core/gitdb' already exists and is not an empty directory.\n" "', skipping repo\n") self.assertCountEqual(listdir(f), ['GitPython', 'core', '.git', '.meta']) self.assertTrue( all(i in listdir(join(f, 'GitPython')) for i in ['git', 'doc', 'test'])) self.assertCountEqual(listdir(join(f, 'core')), ['gitdb']) self.assertTrue( all(i in listdir(join(f, 'core', 'gitdb')) for i in ['gitdb', 'doc', 'setup.py']))
def test_apply_raise_errors(self, mock_ensure_object): params = { 'commands': [ 'git fetch --all --tags --prune', ] } with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.apply, ['--command', params['commands'][0], '-e']) self.assertTrue(result.exit_code in [128, 1])
def test_apply_command_failed_to_execute(self, mock_ensure_object): params = { 'commands': [ 'rm test', ], 'actual_repositories': ['gameta', 'GitPython', 'gitdb'], } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.apply, ['--command', params['commands'][0], '-e']) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Applying {params['commands']} to repos {params['actual_repositories']}\n" f"Executing rm test in {params['actual_repositories'][0]}\n" f"Error: CalledProcessError.Command '['rm', 'test']' returned non-zero exit status 1. " f"occurred when executing command ['rm', 'test'] in gameta\n")
def test_tags_add_empty_meta_file(self, mock_ensure_object): params = { 'name': 'GitPython', 'tags': ['a', 'b', 'c'] } with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) with open(join(f, '.meta'), 'w+') as m: json.dump({ 'projects': {} }, m) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.add, ['--name', params['name'], '-t', params['tags'][0], '-t', params['tags'][1], '-t', params['tags'][2]] ) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Adding tags {params['tags']} to {params['name']}\n" f"Error: Repository {params['name']} does not exist in .meta file\n" )
def test_init_with_default_values_folder_is_a_metarepo( self, mock_ensure_object): with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) copyfile(join(dirname(__file__), 'data', '.meta'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.init) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f'Initialising metarepo in {f}\n' f"{f} is a metarepo, ignoring\n") with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'gameta': { 'path': '.', 'tags': ['metarepo'], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True } } })
def test_apply_command_to_all_repositories(self, mock_ensure_object): params = { 'commands': ['git fetch --all --tags --prune'], 'actual_repositories': ['gameta', 'GitPython', 'gitdb'] } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.apply, ['--command', params['commands'][0]]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f"Applying {params['commands']} to repos {params['actual_repositories']}\n" f"Executing git fetch --all --tags --prune in {params['actual_repositories'][0]}\n" f"Executing git fetch --all --tags --prune in {params['actual_repositories'][1]}\n" f"Executing git fetch --all --tags --prune in {params['actual_repositories'][2]}\n" )
def test_params_delete_parameters_all_parameters_deleted( self, mock_ensure_object): params = {'parameter': 'test'} with self.runner.isolated_filesystem() as f: with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output['projects']['gameta'].update( {"test": { 'a': [1, 2, 3] }}) output['projects']['GitPython'].update( {'test': { 'a': [4, 5, 6] }}) output['projects']['gitdb'].update( {'test': { 'a': [1, 6, 7], 'c': [4, 2, 8] }}) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.delete, ['-p', params['parameter']]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f"Deleting parameter {params['parameter']}\n" f"Successfully deleted parameter {params['parameter']} from .meta file\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'GitPython': { 'path': 'GitPython', 'tags': ['a', 'b', 'c'], 'url': 'https://github.com/gitpython-developers/GitPython.git', '__metarepo__': False }, 'gameta': { 'path': '.', 'tags': ['metarepo'], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True }, 'gitdb': { 'path': 'core/gitdb', 'tags': ['a', 'c', 'd'], 'url': 'https://github.com/gitpython-developers/gitdb.git', '__metarepo__': False } } })
def test_sync_all_repos(self, mock_ensure_object): with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.sync) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f'Syncing all child repositories in metarepo {f}\n' 'Successfully synced GitPython to GitPython\n' 'Successfully synced gitdb to core/gitdb\n') self.assertCountEqual(listdir(f), ['GitPython', 'core', '.git', '.meta']) self.assertTrue( all(i in listdir(join(f, 'GitPython')) for i in ['git', 'doc', 'test'])) self.assertCountEqual(listdir(join(f, 'core')), ['gitdb']) self.assertTrue( all(i in listdir(join(f, 'core', 'gitdb')) for i in ['gitdb', 'doc', 'setup.py']))
def test_apply_command_with_python_interpreter_invalid_python_script( self, mock_ensure_object): params = { 'commands': [ 'from random import choice\n' 'from string import ascii_lowercase, ascii_uppercase, digits, punctuation\n' 'with open("{ENCRYPTION_FILE_NAME}", "w") as f:\n' ' f.write(".join([choice(ascii_lowercase + ascii_uppercase + digits + punctuation) ' # Missing one " 'for _ in range({KEY_LEN})]))', 'from os import getcwd\n' 'from os.path import join, exists\n' 'from shutil import copyfile\n' 'for repo, details in {__repos__}.items():\n' ' if not exists(join(getcwd(), details["path"], "{ENCRYPTION_FILE_NAME}")):\n' ' copyfile("{ENCRYPTION_FILE_NAME}", join(getcwd(), details["path"], "{ENCRYPTION_FILE_NAME}"))' ], 'tags': ['metarepo'], 'actual_repositories': ['gameta'], 'encryption_file_name': 'encryption.txt', 'key_len': 16 } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output.update({ 'constants': { 'ENCRYPTION_FILE_NAME': params['encryption_file_name'], 'KEY_LEN': params['key_len'] } }) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.apply, [ '--command', params['commands'][0], '--command', params['commands'][1], '--tags', params['tags'][0], '-p', '-v' ]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Error: One of the commands in {params['commands']} is not a valid Python script\n" )
def test_cli_printing_version(self, mock_ensure_object): with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.cli, ["-v"]) self.assertEqual(result.exit_code, 0) self.assertEqual(result.output, f"Gameta version: {__version__}\n")
def test_init_with_default_values_folder_is_not_a_git_repo( self, mock_ensure_object): with self.runner.isolated_filesystem() as f: context = GametaContext() context.project_dir = f mock_ensure_object.return_value = context result = self.runner.invoke(self.init) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f'Initialising metarepo in {f}\n' f"Error: {f} is not a valid git repo, initialise it with -g flag\n" )
def test_tags_delete_duplicate_tags(self, mock_ensure_object): params = { 'name': 'GitPython', 'tags': ['a', 'b', 'c'] } with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) with open(join(dirname(__file__), 'data', '.meta'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output['projects']['GitPython'] = { "url": 'https://github.com/gitpython-developers/GitPython.git', 'path': 'GitPython', 'tags': ['c', 'b', 'f'], '__metarepo__': False } json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.delete, ['--name', params['name'], '-t', params['tags'][0], '-t', params['tags'][1], '-t', params['tags'][2]] ) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f"Deleting tags {params['tags']} from {params['name']}\n" f"Successfully deleted tags from repository {params['name']}\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { "projects": { "gameta": { "path": ".", "tags": ["metarepo"], "url": "[email protected]:genius-systems/gameta.git", '__metarepo__': True }, 'GitPython': { "url": 'https://github.com/gitpython-developers/GitPython.git', 'path': 'GitPython', 'tags': ['f'], '__metarepo__': False } } } )
def test_params_add_parameters_skip_user_prompt_user_provided_default_value( self, mock_ensure_object): params = {'parameter': 'test', 'value': 'hello_world'} with self.runner.isolated_filesystem() as f: copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.add, ['-p', params['parameter'], '-y', '-v', params['value']]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f"Adding parameter {params['parameter']}\n" f"Adding {params['parameter']} value {params['value']} for gameta\n" f"Adding {params['parameter']} value {params['value']} for GitPython\n" f"Adding {params['parameter']} value {params['value']} for gitdb\n" f"Successfully added parameter {params['parameter']} to .meta file\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'GitPython': { 'path': 'GitPython', 'tags': ['a', 'b', 'c'], params['parameter']: params['value'], 'url': 'https://github.com/gitpython-developers/GitPython.git', '__metarepo__': False }, 'gameta': { 'path': '.', 'tags': ['metarepo'], params['parameter']: params['value'], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True }, 'gitdb': { 'path': 'core/gitdb', 'tags': ['a', 'c', 'd'], params['parameter']: params['value'], 'url': 'https://github.com/gitpython-developers/gitdb.git', '__metarepo__': False } } })
def test_constants_delete_an_non_existent_constant(self, mock_ensure_object): params = {'name': 'hello'} with self.runner.isolated_filesystem() as f: with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output.update({'constants': {'TEST': "hello_world"}}) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.delete, ['-n', params['name']]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Deleting constant {params['name']}\n" f"Error: Constant {params['name']} does not exist in .meta file\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'GitPython': { 'path': 'GitPython', 'tags': ['a', 'b', 'c'], 'url': 'https://github.com/gitpython-developers/GitPython.git', '__metarepo__': False }, 'gameta': { 'path': '.', 'tags': ['metarepo'], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True }, 'gitdb': { 'path': 'core/gitdb', 'tags': ['a', 'c', 'd'], 'url': 'https://github.com/gitpython-developers/gitdb.git', '__metarepo__': False } }, "constants": { "TEST": "hello_world" } })
def test_constants_add_valid_constant(self, mock_ensure_object): params = {'name': 'test', 'type': 'int', 'value': 1} with self.runner.isolated_filesystem() as f: copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.add, [ '-n', params['name'], '-t', params['type'], '-v', params['value'] ]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f"Adding constant {params['name']}\n" f"Successfully added constant {params['name'].upper()}: {params['value']} (type: {params['type']}) " f"to .meta file\n") with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'GitPython': { 'path': 'GitPython', 'tags': ['a', 'b', 'c'], 'url': 'https://github.com/gitpython-developers/GitPython.git', '__metarepo__': False }, 'gameta': { 'path': '.', 'tags': ['metarepo'], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True }, 'gitdb': { 'path': 'core/gitdb', 'tags': ['a', 'c', 'd'], 'url': 'https://github.com/gitpython-developers/gitdb.git', '__metarepo__': False } }, "constants": { "TEST": 1 } })
def test_params_delete_parameters_missing_key_parameters( self, mock_ensure_object): with self.runner.isolated_filesystem() as f: copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.delete) self.assertEqual(result.exit_code, 2) self.assertEqual( result.output, "Usage: delete [OPTIONS]\n" "Try 'delete --help' for help.\n" "\n" "Error: Missing option '--param' / '-p'.\n")
def test_sync_empty_meta_file(self, mock_ensure_object): with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) with open(join(f, '.meta'), 'w') as m: json.dump({'projects': {}, "commands": {}}, m) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.sync) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f'Syncing all child repositories in metarepo {f}\n')
def test_constants_add_constant_with_invalid_type_bool( self, mock_ensure_object): params = {'name': 'test', 'type': 'bool', 'value': 'hello_world'} with self.runner.isolated_filesystem() as f: copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.add, [ '-n', params['name'], '-t', params['type'], '-v', params['value'] ]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Adding constant {params['name']}\n" f"Error: BadParameter.{params['value']} is not a valid boolean\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'GitPython': { 'path': 'GitPython', 'tags': ['a', 'b', 'c'], 'url': 'https://github.com/gitpython-developers/GitPython.git', '__metarepo__': False }, 'gameta': { 'path': '.', 'tags': ['metarepo'], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True }, 'gitdb': { 'path': 'core/gitdb', 'tags': ['a', 'c', 'd'], 'url': 'https://github.com/gitpython-developers/gitdb.git', '__metarepo__': False } } })
def test_apply_command_with_python_interpreter_shell_command_passed( self, mock_ensure_object): params = { 'commands': [ 'git fetch --all --tags --prune', ], 'tags': ['metarepo'], 'actual_repositories': ['gameta'], 'encryption_file_name': 'encryption.txt', 'key_len': 16 } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output.update({ 'constants': { 'ENCRYPTION_FILE_NAME': params['encryption_file_name'], 'KEY_LEN': params['key_len'] } }) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.apply, [ '--command', params['commands'][0], '--tags', params['tags'][0], '-p', '-v' ]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Error: One of the commands in {params['commands']} is not a valid Python script\n" )
def test_constants_delete_constant_from_empty_meta_file( self, mock_ensure_object): params = {'name': 'hello'} with self.runner.isolated_filesystem() as f: with open(join(f, '.meta'), 'w+') as m: json.dump({}, m) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.delete, ['-n', params['name']]) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Deleting constant {params['name']}\n" f"Error: Constant {params['name']} does not exist in .meta file\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual(json.load(m), {})
def test_tags_delete_key_parameters_not_provided(self, mock_ensure_object): with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke(self.delete) self.assertEqual(result.exit_code, 2) self.assertEqual( result.output, "Usage: delete [OPTIONS]\n" "Try 'delete --help' for help.\n" "\n" "Error: Missing option '--name' / '-n'.\n" )
def test_tags_delete_attempt_to_delete_metarepo_tag(self, mock_ensure_object): params = { 'name': 'gameta', 'tags': ['metarepo', 'b', 'c'] } with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) with open(join(dirname(__file__), 'data', '.meta'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output['projects']['gameta'].update({ 'tags': ['metarepo', 'a', 'b', 'c'] }) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.delete, ['--name', params['name'], '-t', params['tags'][0], '-t', params['tags'][1], '-t', params['tags'][2]] ) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f"Deleting tags {params['tags']} from {params['name']}\n" "Unable to delete the metarepo tag from metarepo, removing it before deleting other tags\n" f"Successfully deleted tags from repository {params['name']}\n" ) with open(join(f, '.meta'), 'r') as m: self.assertCountEqual( json.load(m), { "projects": { "gameta": { "path": ".", "tags": ["metarepo", "a"], "url": "[email protected]:genius-systems/gameta.git", '__metarepo__': True } } } )
def test_params_add_parameters_skip_user_prompt_default_type_not_in_choice( self, mock_ensure_object): params = {'parameter': 'test', 'type': 'test'} with self.runner.isolated_filesystem() as f: copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.add, ['-p', params['parameter'], '-y', '-t', params['type']]) self.assertEqual(result.exit_code, 2) self.assertEqual( result.output, "Usage: add [OPTIONS]\n" "Try 'add --help' for help.\n" "\n" "Error: Invalid value for '--type' / '-t': invalid choice: test. " "(choose from int, float, str, bool, dict, list)\n")
def test_tags_delete_tags_from_nonexistent_repository(self, mock_ensure_object): params = { 'name': 'GitPython', 'tags': ['a', 'b', 'c'] } with self.runner.isolated_filesystem() as f: with zipfile.ZipFile(join(dirname(__file__), 'data', 'git.zip'), 'r') as template: template.extractall(f) copyfile(join(dirname(__file__), 'data', '.meta'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.delete, ['--name', params['name'], '-t', params['tags'][0], '-t', params['tags'][1], '-t', params['tags'][2]] ) self.assertEqual(result.exit_code, 1) self.assertEqual( result.output, f"Deleting tags {params['tags']} from {params['name']}\n" f"Error: Repository {params['name']} does not exist in .meta file\n" )
def test_init_with_git_folder_is_not_a_git_repo(self, mock_ensure_object): with self.runner.isolated_filesystem() as f: context = GametaContext() context.project_dir = f mock_ensure_object.return_value = context result = self.runner.invoke(self.init, ['--git']) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f'Initialising metarepo in {f}\n' f'Initialising {f} as a git repository\n' f'Successfully initialised {basename(f)} as a metarepo\n') with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { basename(f): { 'path': '.', 'tags': ['metarepo'], 'url': None, '__metarepo__': True } } })
def test_params_add_parameters_user_prompt_user_input_does_not_match_required_type( self, mock_ensure_object): params = { 'parameter': 'test', 'value': 'hello_world', 'type': 'dict', 'user_prompt': [{ 'a': [1, 2, 3] }, ['a', [4, 5, 6]], { 'a': [1, 6, 7], 'c': [4, 2, 8] }] } with self.runner.isolated_filesystem() as f: copyfile(join(dirname(__file__), 'data', '.meta_other_repos'), join(f, '.meta')) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context result = self.runner.invoke( self.add, [ '-p', params['parameter'], '-v', params['value'], '--type', params['type'] ], input='\n'.join([json.dumps(p) for p in params['user_prompt']])) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, f"Adding parameter {params['parameter']}\n" f"Please enter the parameter value for repository gameta or >* to skip [hello_world]: " f"{json.dumps(params['user_prompt'][0])}\n" f"Adding {params['parameter']} value {params['user_prompt'][0]} for gameta\n" f"Please enter the parameter value for repository GitPython or >* to skip [hello_world]: " f"{json.dumps(params['user_prompt'][1])}\n" f"Value {params['user_prompt'][1]} (type: {type(params['user_prompt'][1])}) entered is not the " f"required type {dict}, defaulting to default value {params['value']}\n" f"Adding {params['parameter']} value {params['value']} for GitPython\n" f"Please enter the parameter value for repository gitdb or >* to skip [hello_world]: " f"{json.dumps(params['user_prompt'][2])}\n" f"Adding {params['parameter']} value {params['user_prompt'][2]} for gitdb\n" f"Successfully added parameter {params['parameter']} to .meta file\n" ) with open(join(f, '.meta'), 'r') as m: self.assertEqual( json.load(m), { 'projects': { 'GitPython': { 'path': 'GitPython', 'tags': ['a', 'b', 'c'], params['parameter']: params['value'], 'url': 'https://github.com/gitpython-developers/GitPython.git', '__metarepo__': False }, 'gameta': { 'path': '.', 'tags': ['metarepo'], params['parameter']: params['user_prompt'][0], 'url': '[email protected]:genius-systems/gameta.git', '__metarepo__': True }, 'gitdb': { 'path': 'core/gitdb', 'tags': ['a', 'c', 'd'], params['parameter']: params['user_prompt'][2], 'url': 'https://github.com/gitpython-developers/gitdb.git', '__metarepo__': False } } })
def test_apply_command_with_python_interpreter(self, mock_ensure_object): params = { 'commands': [ 'from random import choice\n' 'from string import ascii_lowercase, ascii_uppercase, digits, punctuation\n' 'with open("{ENCRYPTION_FILE_NAME}", "w") as f:\n' ' f.write("".join([choice(ascii_lowercase + ascii_uppercase + digits + punctuation) ' 'for _ in range({KEY_LEN})]))', 'from os import getcwd\n' 'from os.path import join, exists\n' 'from shutil import copyfile\n' 'for repo, details in {__repos__}.items():\n' ' if not exists(join(getcwd(), details["path"], "{ENCRYPTION_FILE_NAME}")):\n' ' copyfile("{ENCRYPTION_FILE_NAME}", join(getcwd(), details["path"], "{ENCRYPTION_FILE_NAME}"))' ], 'tags': ['metarepo'], 'actual_repositories': ['gameta'], 'encryption_file_name': 'encryption.txt', 'key_len': 16 } with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output.update({ 'constants': { 'ENCRYPTION_FILE_NAME': params['encryption_file_name'], 'KEY_LEN': params['key_len'] } }) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() mock_ensure_object.return_value = context output = [ c for c in context.apply(params['commands'], python=True) ] result = self.runner.invoke(self.apply, [ '--command', params['commands'][0], '--command', params['commands'][1], '--tags', params['tags'][0], '-p', '-v' ]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, "Multiple commands detected, executing in a separate shell\n" f"Applying {params['commands']} to repos {params['actual_repositories']} in a separate shell\n" f"Executing {output[0][1][0]} {output[0][1][1]} {output[0][1][2]} in " f"{params['actual_repositories'][0]}\n") for path in [f, join(f, 'GitPython'), join(f, 'core', 'gitdb')]: self.assertTrue( exists(join(path, params['encryption_file_name']))) with open(join(path, params['encryption_file_name'])) as e: self.assertEqual(len(e.read()), params['key_len'])
def test_apply_multiple_commands_to_all_repositories_with_parameter_substitution( self, mock_ensure_object): params = { 'commands': [ 'git fetch --all --tags --prune', 'git checkout {BRANCH}', 'mkdir {$TMP}/{test_dir}', 'cp -r . {$TMP}/{test_dir}' ], 'actual_repositories': ['gameta', 'GitPython', 'gitdb'] } tempdir = mkdtemp() with self.runner.isolated_filesystem() as f: copytree(join(dirname(dirname(__file__)), '.git'), join(f, '.git')) with zipfile.ZipFile( join(dirname(__file__), 'data', 'gitpython.zip'), 'r') as template: template.extractall(f) with zipfile.ZipFile(join(dirname(__file__), 'data', 'gitdb.zip'), 'r') as template: template.extractall(join(f, 'core')) with open(join(dirname(__file__), 'data', '.meta_other_repos'), 'r') as m1: output = json.load(m1) with open(join(f, '.meta'), 'w+') as m2: output['projects']['gameta'].update( {'test_dir': 'test_gameta'}) output['projects']['gitdb'].update( {'test_dir': 'test_gitdb'}) output['projects']['GitPython'].update( {'test_dir': 'test_gitpython'}) output.update({'constants': {'BRANCH': 'master'}}) json.dump(output, m2) context = GametaContext() context.project_dir = f context.load() context.env_vars['$TMP'] = tempdir mock_ensure_object.return_value = context output = [ c for repo, c in context.apply(list(params['commands']), shell=True) ] result = self.runner.invoke(self.apply, [ '--command', params['commands'][0], '--command', params['commands'][1], '--command', params['commands'][2], '--command', params['commands'][3], ]) self.assertEqual(result.exit_code, 0) self.assertEqual( result.output, "Multiple commands detected, executing in a separate shell\n" f"Applying {params['commands']} to repos {params['actual_repositories']} in a separate shell\n" f"Executing {' '.join(output[0])} in {params['actual_repositories'][0]}\n" f"Executing {' '.join(output[1])} in {params['actual_repositories'][1]}\n" f"Executing {' '.join(output[2])} in {params['actual_repositories'][2]}\n" ) self.assertCountEqual( listdir(tempdir), ['test_gitdb', 'test_gitpython', 'test_gameta']) self.assertTrue( all(i in listdir(join(tempdir, 'test_gameta')) for i in ['.git', '.meta', 'GitPython', 'core'])) self.assertTrue( all(i in listdir(join(tempdir, 'test_gitpython')) for i in ['git', 'doc', 'test'])) self.assertTrue( all(i in listdir(join(tempdir, 'test_gitdb')) for i in ['gitdb', 'doc', 'setup.py'])) rmtree(tempdir)