)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":28208,"name":"Roman Gorshunov","email":"roman.gorshunov@att.com","username":"gorshunovr"},"change_message_id":"e07d5950dfd1c11e7f8f2eff838c11ac52239fe1","unresolved":false,"context_lines":[{"line_number":12,"context_line":"window where the permissions on a file are overly permissive."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"This patchset:"},{"line_number":15,"context_line":"1. Sets default permissions of 0640 on files created by Pegleg."},{"line_number":16,"context_line":"2. Sets permissions on files and directories  at time of creation."},{"line_number":17,"context_line":"3. Explicitly adds the open flag (\u0027r\u0027, \u0027w\u0027 etc.) to all open() calls."},{"line_number":18,"context_line":"4. Replaces sys.stdout.write calls with click.echo() calls to be more"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":34,"id":"9fb8cfa7_65bdca00","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":63},"updated":"2019-06-27 16:03:53.000000000","message":"Why would we want to explicitly set permissions from the Pegleg, if we could just set system\u0027s (user\u0027s) umask setting?\n\nIf we would still want to enforce certain permissions to be set onto newly created files and directories, then why not to set umask in the code once on program start, instead of setting permissions like 0775 \u0026 0640 in the code in multiple places?\n\nIf umask setting would be set once somewhere in the code, then it would potentially allow users to easily adjust it to their needs. E.g. 0775 could be too wide and users would want to use 0750 for directories.","commit_id":"c355a8d96d885d7da6126dfcdd627b9b5a888f13"},{"author":{"_account_id":28208,"name":"Roman Gorshunov","email":"roman.gorshunov@att.com","username":"gorshunovr"},"change_message_id":"9b393f867ed0e10472ae22eb3a6ebe7dfd5e8344","unresolved":false,"context_lines":[{"line_number":12,"context_line":"window where the permissions on a file are overly permissive."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"This patchset:"},{"line_number":15,"context_line":"1. Sets default permissions of 0640 on files created by Pegleg."},{"line_number":16,"context_line":"2. Sets permissions on files and directories  at time of creation."},{"line_number":17,"context_line":"3. Explicitly adds the open flag (\u0027r\u0027, \u0027w\u0027 etc.) to all open() calls."},{"line_number":18,"context_line":"4. Replaces sys.stdout.write calls with click.echo() calls to be more"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":35,"id":"9fb8cfa7_ee0bd779","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":63},"updated":"2019-06-27 18:28:46.000000000","message":"Why would we want to explicitly set permissions from the Pegleg, if we could just set system\u0027s (user\u0027s) umask setting?\n\nIf we would still want to enforce certain permissions to be set onto newly created files and directories, then why not to set umask in the code once on program start, instead of setting permissions like 0775 \u0026 0640 in the code in multiple places?\n\nIf umask setting would be set once somewhere in the code, then it would potentially allow users to easily adjust it to their needs. E.g. 0775 could be too wide and users would want to use 0750 for directories.","commit_id":"46204ec346c57cd6aff32de01a01e2f2da3e986f"},{"author":{"_account_id":28208,"name":"Roman Gorshunov","email":"roman.gorshunov@att.com","username":"gorshunovr"},"change_message_id":"b72218eb99b6dacbd1154f1a3214cc2da88b2e5e","unresolved":false,"context_lines":[{"line_number":12,"context_line":"window where the permissions on a file are overly permissive."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"This patchset:"},{"line_number":15,"context_line":"1. Sets default permissions of 0640 on files created by Pegleg."},{"line_number":16,"context_line":"2. Sets permissions on files and directories  at time of creation."},{"line_number":17,"context_line":"3. Explicitly adds the open flag (\u0027r\u0027, \u0027w\u0027 etc.) to all open() calls."},{"line_number":18,"context_line":"4. Replaces sys.stdout.write calls with click.echo() calls to be more"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":35,"id":"9fb8cfa7_74fb2c78","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":63},"in_reply_to":"9fb8cfa7_0b5898f7","updated":"2019-06-28 11:32:59.000000000","message":"Cool. Looks much cleaner.","commit_id":"46204ec346c57cd6aff32de01a01e2f2da3e986f"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"4a08cdccbba119ee07b806b1d5e8c8821d5055b7","unresolved":false,"context_lines":[{"line_number":12,"context_line":"window where the permissions on a file are overly permissive."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"This patchset:"},{"line_number":15,"context_line":"1. Sets default permissions of 0640 on files created by Pegleg."},{"line_number":16,"context_line":"2. Sets permissions on files and directories  at time of creation."},{"line_number":17,"context_line":"3. Explicitly adds the open flag (\u0027r\u0027, \u0027w\u0027 etc.) to all open() calls."},{"line_number":18,"context_line":"4. Replaces sys.stdout.write calls with click.echo() calls to be more"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":35,"id":"9fb8cfa7_0b5898f7","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":63},"in_reply_to":"9fb8cfa7_14843ad2","updated":"2019-06-27 22:04:51.000000000","message":"Done.  Implementing umask of 0o027, which corresponds to file permissions 640.  This is handled in config.py and passed into the CLI site and lint commands.","commit_id":"46204ec346c57cd6aff32de01a01e2f2da3e986f"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"2c64ccb53189fdc43da486fc0301999e81775a1c","unresolved":false,"context_lines":[{"line_number":12,"context_line":"window where the permissions on a file are overly permissive."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"This patchset:"},{"line_number":15,"context_line":"1. Sets default permissions of 0640 on files created by Pegleg."},{"line_number":16,"context_line":"2. Sets permissions on files and directories  at time of creation."},{"line_number":17,"context_line":"3. Explicitly adds the open flag (\u0027r\u0027, \u0027w\u0027 etc.) to all open() calls."},{"line_number":18,"context_line":"4. Replaces sys.stdout.write calls with click.echo() calls to be more"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":35,"id":"9fb8cfa7_14843ad2","line":15,"range":{"start_line":15,"start_character":0,"end_line":15,"end_character":63},"in_reply_to":"9fb8cfa7_ee0bd779","updated":"2019-06-27 20:27:06.000000000","message":"Looking at implementation, setting a umask of 0o027 in config.py.GLOBAL_CONTEXT[\u0027default_umask\u0027]\n\na setter method in config.py to set the umask to the default_umask, and then calling the setter method when files/directories are created to ensure they get the umask.\n\nI\u0027ll test locally and respond with my results/possible update to the patch","commit_id":"46204ec346c57cd6aff32de01a01e2f2da3e986f"}],"pegleg/cli.py":[{"author":{"_account_id":30173,"name":"Ian Pittwood","email":"pittwoodian@gmail.com","username":"ianp"},"change_message_id":"099f6ece07e6e5e272614ec7c0195363930659ff","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":33,"id":"9fb8cfa7_a3953589","updated":"2019-06-25 02:09:20.000000000","message":"What\u0027s the reasoning for removing the option types here?","commit_id":"fb3a05822a1fc978177627525d5325fef84c9028"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"4a04077b69625ef76088f847358c5f055acf8833","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":33,"id":"9fb8cfa7_83c6f199","in_reply_to":"9fb8cfa7_a3953589","updated":"2019-06-25 02:14:10.000000000","message":"End goal is to support either print to stdout or writing to a file with 640 permissions. To write to a file I needed both a path declared and to use the engine.util.files.write() method.\n\nIf I leave in type I need to import sys to check if the output_streams were sys.stdout then write to it, but we don\u0027t really use sys.stdout.write anywhere else in Pegleg. Removing it makes the logic clean where it\u0027s used - \neither write to a file if a path is given, or click.echo() if not, and with a default of None it basically turns into a case of was -o used or not, if it was write to file if not click.echo","commit_id":"fb3a05822a1fc978177627525d5325fef84c9028"}],"pegleg/config.py":[{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"3e58bed0488ade0a0efaaf2bd2ee56f2ec675f85","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    }"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"def set_umask():"},{"line_number":43,"context_line":"    \"\"\"Set the umask for Pegleg to use when creating files/folders.\"\"\""},{"line_number":44,"context_line":"    os.umask(GLOBAL_CONTEXT[\u0027default_umask\u0027])"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"def get_site_repo():"}],"source_content_type":"text/x-python","patch_set":47,"id":"9fb8cfa7_41297ae3","line":44,"range":{"start_line":42,"start_character":0,"end_line":44,"end_character":45},"updated":"2019-06-30 17:30:54.000000000","message":"If this will never be overridden via the CLI this could just be called globally once, so then it becomes a call and forget sort of thing that no one ever has to worry about again.","commit_id":"a8620cfd8d1fd32db546c3e4abbb26a215369649"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"dfa981982632003d3324e15afb21f71eabb0a46b","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    }"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"def set_umask():"},{"line_number":43,"context_line":"    \"\"\"Set the umask for Pegleg to use when creating files/folders.\"\"\""},{"line_number":44,"context_line":"    os.umask(GLOBAL_CONTEXT[\u0027default_umask\u0027])"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"def get_site_repo():"}],"source_content_type":"text/x-python","patch_set":47,"id":"9fb8cfa7_443d08c2","line":44,"range":{"start_line":42,"start_character":0,"end_line":44,"end_character":45},"in_reply_to":"9fb8cfa7_41297ae3","updated":"2019-06-30 20:43:22.000000000","message":"This is called once per command if that commands falls under the \"site\" or \"lint\" groups.\n\nThere is potential for overriding later, with the addition of a --umask flag in site/lint groups.  If specified and valid use it, if not use this.  For now though the goal is to tighten down permissions, if it\u0027s requested later this would be the entry point to add it.","commit_id":"a8620cfd8d1fd32db546c3e4abbb26a215369649"}],"pegleg/engine/bundle.py":[{"author":{"_account_id":28208,"name":"Roman Gorshunov","email":"roman.gorshunov@att.com","username":"gorshunovr"},"change_message_id":"e07d5950dfd1c11e7f8f2eff838c11ac52239fe1","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    LOG.info(\u0027\u003d\u003d\u003d Building bootstrap scripts \u003d\u003d\u003d\u0027)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    # Copy the site config, and site secrets to build directory"},{"line_number":65,"context_line":"    os.mkdir(build_path, 0o640)"},{"line_number":66,"context_line":"    documents \u003d util.definition.documents_for_site(site_name)"},{"line_number":67,"context_line":"    secret_manager \u003d PeglegSecretManagement(docs\u003ddocuments)"},{"line_number":68,"context_line":"    documents \u003d secret_manager.get_decrypted_secrets()"}],"source_content_type":"text/x-python","patch_set":34,"id":"9fb8cfa7_0542ce0f","line":65,"range":{"start_line":65,"start_character":25,"end_line":65,"end_character":30},"updated":"2019-06-27 16:03:53.000000000","message":"750?","commit_id":"c355a8d96d885d7da6126dfcdd627b9b5a888f13"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"c6ef64524aba980e5d3b16e504c9b255c2971cdd","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    LOG.info(\u0027\u003d\u003d\u003d Building bootstrap scripts \u003d\u003d\u003d\u0027)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    # Copy the site config, and site secrets to build directory"},{"line_number":65,"context_line":"    os.mkdir(build_path, 0o640)"},{"line_number":66,"context_line":"    documents \u003d util.definition.documents_for_site(site_name)"},{"line_number":67,"context_line":"    secret_manager \u003d PeglegSecretManagement(docs\u003ddocuments)"},{"line_number":68,"context_line":"    documents \u003d secret_manager.get_decrypted_secrets()"}],"source_content_type":"text/x-python","patch_set":34,"id":"9fb8cfa7_c8d92b83","line":65,"range":{"start_line":65,"start_character":25,"end_line":65,"end_character":30},"in_reply_to":"9fb8cfa7_0542ce0f","updated":"2019-06-27 20:24:02.000000000","message":"Done","commit_id":"c355a8d96d885d7da6126dfcdd627b9b5a888f13"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"e56d7aa360c708920e7a65b412f5df618a8c6bea","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    LOG.info(\u0027\u003d\u003d\u003d Building bootstrap scripts \u003d\u003d\u003d\u0027)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    # Copy the site config, and site secrets to build directory"},{"line_number":65,"context_line":"    os.mkdir(build_path, 0o640)"},{"line_number":66,"context_line":"    documents \u003d util.definition.documents_for_site(site_name)"},{"line_number":67,"context_line":"    secret_manager \u003d PeglegSecretManagement(docs\u003ddocuments)"},{"line_number":68,"context_line":"    documents \u003d secret_manager.get_decrypted_secrets()"}],"source_content_type":"text/x-python","patch_set":34,"id":"9fb8cfa7_9fab4cd4","line":65,"range":{"start_line":65,"start_character":25,"end_line":65,"end_character":30},"in_reply_to":"9fb8cfa7_2951d236","updated":"2019-06-29 13:09:13.000000000","message":"We no longer specify permissions on this in patch 39.  The umask is set when the CLI secrets or lint groups are run, and this directory then uses that umask.  This directory should then be created with 750.","commit_id":"c355a8d96d885d7da6126dfcdd627b9b5a888f13"},{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"b8dce8965c126997988eac7a8bc1fa89265c551e","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    LOG.info(\u0027\u003d\u003d\u003d Building bootstrap scripts \u003d\u003d\u003d\u0027)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    # Copy the site config, and site secrets to build directory"},{"line_number":65,"context_line":"    os.mkdir(build_path, 0o640)"},{"line_number":66,"context_line":"    documents \u003d util.definition.documents_for_site(site_name)"},{"line_number":67,"context_line":"    secret_manager \u003d PeglegSecretManagement(docs\u003ddocuments)"},{"line_number":68,"context_line":"    documents \u003d secret_manager.get_decrypted_secrets()"}],"source_content_type":"text/x-python","patch_set":34,"id":"9fb8cfa7_2951d236","line":65,"range":{"start_line":65,"start_character":25,"end_line":65,"end_character":30},"in_reply_to":"9fb8cfa7_c8d92b83","updated":"2019-06-29 03:24:24.000000000","message":"It would be easier to maintain this if this were made into a constant somewhere.","commit_id":"c355a8d96d885d7da6126dfcdd627b9b5a888f13"},{"author":{"_account_id":28208,"name":"Roman Gorshunov","email":"roman.gorshunov@att.com","username":"gorshunovr"},"change_message_id":"44cc8389325ff5cabf089a46b8c354441ef60352","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    LOG.info(\u0027\u003d\u003d\u003d Building bootstrap scripts \u003d\u003d\u003d\u0027)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    # Copy the site config, and site secrets to build directory"},{"line_number":65,"context_line":"    os.mkdir(build_path, 0o750)"},{"line_number":66,"context_line":"    documents \u003d util.definition.documents_for_site(site_name)"},{"line_number":67,"context_line":"    secret_manager \u003d PeglegSecretManagement(docs\u003ddocuments)"},{"line_number":68,"context_line":"    documents \u003d secret_manager.get_decrypted_secrets()"}],"source_content_type":"text/x-python","patch_set":35,"id":"9fb8cfa7_6ee287a2","line":65,"range":{"start_line":65,"start_character":25,"end_line":65,"end_character":30},"updated":"2019-06-27 18:33:44.000000000","message":"Please, hit \"Done\" button when you change something addressing comment from a reviewer. It helps a lot to track what has been addresses and what is not yet addressed. Thanks!","commit_id":"46204ec346c57cd6aff32de01a01e2f2da3e986f"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"c6ef64524aba980e5d3b16e504c9b255c2971cdd","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    LOG.info(\u0027\u003d\u003d\u003d Building bootstrap scripts \u003d\u003d\u003d\u0027)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    # Copy the site config, and site secrets to build directory"},{"line_number":65,"context_line":"    os.mkdir(build_path, 0o750)"},{"line_number":66,"context_line":"    documents \u003d util.definition.documents_for_site(site_name)"},{"line_number":67,"context_line":"    secret_manager \u003d PeglegSecretManagement(docs\u003ddocuments)"},{"line_number":68,"context_line":"    documents \u003d secret_manager.get_decrypted_secrets()"}],"source_content_type":"text/x-python","patch_set":35,"id":"9fb8cfa7_7446d6c2","line":65,"range":{"start_line":65,"start_character":25,"end_line":65,"end_character":30},"in_reply_to":"9fb8cfa7_6ee287a2","updated":"2019-06-27 20:24:02.000000000","message":"Sorry made this change and was considering your suggestion on umask.","commit_id":"46204ec346c57cd6aff32de01a01e2f2da3e986f"}],"pegleg/engine/site.py":[{"author":{"_account_id":28235,"name":"Aaron Sheffield","email":"ajs@sheffieldfamily.net","username":"aaronsheffield"},"change_message_id":"0f11d2fa7c099ed5d4efd5e5b0f8aeb3e7a3ae84","unresolved":false,"context_lines":[{"line_number":151,"context_line":"    if output_stream:"},{"line_number":152,"context_line":"        files.write(output_stream, msg)"},{"line_number":153,"context_line":"    else:"},{"line_number":154,"context_line":"        click.echo(msg)"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"def show(site_name, output_stream):"}],"source_content_type":"text/x-python","patch_set":33,"id":"9fb8cfa7_025ba4f5","line":154,"range":{"start_line":154,"start_character":8,"end_line":154,"end_character":23},"updated":"2019-06-27 15:28:39.000000000","message":"How does click.echo handle \"\\n\"?  Does it add an extra blank line?  If it does add an extra blank line then maybe the \"\\n\" should only be part of the files.write?","commit_id":"fb3a05822a1fc978177627525d5325fef84c9028"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"7743281b5bce19853dc0b74bdc434b7d7af7b1c5","unresolved":false,"context_lines":[{"line_number":151,"context_line":"    if output_stream:"},{"line_number":152,"context_line":"        files.write(output_stream, msg)"},{"line_number":153,"context_line":"    else:"},{"line_number":154,"context_line":"        click.echo(msg)"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"def show(site_name, output_stream):"}],"source_content_type":"text/x-python","patch_set":33,"id":"9fb8cfa7_a24098a6","line":154,"range":{"start_line":154,"start_character":8,"end_line":154,"end_character":23},"in_reply_to":"9fb8cfa7_025ba4f5","updated":"2019-06-27 15:36:53.000000000","message":"sys.stdout.write did not add new lines by default, where click does.  the \"\\n\" is click would add an extra blank line that was not present before this change when writing to stdout.  fixed occurences of this in patchset 34","commit_id":"fb3a05822a1fc978177627525d5325fef84c9028"},{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"b8dce8965c126997988eac7a8bc1fa89265c551e","unresolved":false,"context_lines":[{"line_number":79,"context_line":"            save_file \u003d os.path.join(save_location, repo_name + \u0027.yaml\u0027)"},{"line_number":80,"context_line":"            if repo_name not in save_files:"},{"line_number":81,"context_line":"                save_files[repo_name] \u003d os.fdopen("},{"line_number":82,"context_line":"                    os.open(save_file, os.O_WRONLY | os.O_CREAT, 0o640), \u0027w\u0027)"},{"line_number":83,"context_line":"            LOG.debug(\"Collecting file %s to file %s\", filename, save_file)"},{"line_number":84,"context_line":"            save_files[repo_name].writelines(_read_and_format_yaml(filename))"},{"line_number":85,"context_line":"        save_files[curr_site_repo].writelines(yaml.safe_dump("}],"source_content_type":"text/x-python","patch_set":34,"id":"9fb8cfa7_094e4e96","line":82,"range":{"start_line":82,"start_character":20,"end_line":82,"end_character":77},"updated":"2019-06-29 03:24:24.000000000","message":"It is better to use context manager before this (that is, the with keyword).\n\nIt would be easier to maintain 0o640 if this were made into a constant somewhere.","commit_id":"c355a8d96d885d7da6126dfcdd627b9b5a888f13"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"e56d7aa360c708920e7a65b412f5df618a8c6bea","unresolved":false,"context_lines":[{"line_number":79,"context_line":"            save_file \u003d os.path.join(save_location, repo_name + \u0027.yaml\u0027)"},{"line_number":80,"context_line":"            if repo_name not in save_files:"},{"line_number":81,"context_line":"                save_files[repo_name] \u003d os.fdopen("},{"line_number":82,"context_line":"                    os.open(save_file, os.O_WRONLY | os.O_CREAT, 0o640), \u0027w\u0027)"},{"line_number":83,"context_line":"            LOG.debug(\"Collecting file %s to file %s\", filename, save_file)"},{"line_number":84,"context_line":"            save_files[repo_name].writelines(_read_and_format_yaml(filename))"},{"line_number":85,"context_line":"        save_files[curr_site_repo].writelines(yaml.safe_dump("}],"source_content_type":"text/x-python","patch_set":34,"id":"9fb8cfa7_df7ea468","line":82,"range":{"start_line":82,"start_character":20,"end_line":82,"end_character":77},"in_reply_to":"9fb8cfa7_094e4e96","updated":"2019-06-29 13:09:13.000000000","message":"This was changed back to it\u0027s original open(path, \u0027w\u0027) form by patch 39.","commit_id":"c355a8d96d885d7da6126dfcdd627b9b5a888f13"},{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"b8dce8965c126997988eac7a8bc1fa89265c551e","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            repo_name \u003d os.path.normpath(repo_base).split(os.sep)[-1]"},{"line_number":79,"context_line":"            save_file \u003d os.path.join(save_location, repo_name + \u0027.yaml\u0027)"},{"line_number":80,"context_line":"            if repo_name not in save_files:"},{"line_number":81,"context_line":"                save_files[repo_name] \u003d open(save_file, \u0027w\u0027)"},{"line_number":82,"context_line":"            LOG.debug(\"Collecting file %s to file %s\", filename, save_file)"},{"line_number":83,"context_line":"            save_files[repo_name].writelines(_read_and_format_yaml(filename))"},{"line_number":84,"context_line":"        save_files[curr_site_repo].writelines(yaml.safe_dump("}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_e9465a7b","line":81,"range":{"start_line":81,"start_character":40,"end_line":81,"end_character":44},"updated":"2019-06-29 03:24:24.000000000","message":"Better to use with here, but unrelated.","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"e56d7aa360c708920e7a65b412f5df618a8c6bea","unresolved":false,"context_lines":[{"line_number":78,"context_line":"            repo_name \u003d os.path.normpath(repo_base).split(os.sep)[-1]"},{"line_number":79,"context_line":"            save_file \u003d os.path.join(save_location, repo_name + \u0027.yaml\u0027)"},{"line_number":80,"context_line":"            if repo_name not in save_files:"},{"line_number":81,"context_line":"                save_files[repo_name] \u003d open(save_file, \u0027w\u0027)"},{"line_number":82,"context_line":"            LOG.debug(\"Collecting file %s to file %s\", filename, save_file)"},{"line_number":83,"context_line":"            save_files[repo_name].writelines(_read_and_format_yaml(filename))"},{"line_number":84,"context_line":"        save_files[curr_site_repo].writelines(yaml.safe_dump("}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_bf3e5088","line":81,"range":{"start_line":81,"start_character":40,"end_line":81,"end_character":44},"in_reply_to":"9fb8cfa7_e9465a7b","updated":"2019-06-29 13:09:13.000000000","message":"cleanup operations that with open would provide automatically are handled on lines 89-91.","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"},{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"b8dce8965c126997988eac7a8bc1fa89265c551e","unresolved":false,"context_lines":[{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    if output_stream:"},{"line_number":122,"context_line":"        files.dump_all("},{"line_number":123,"context_line":"            output_stream,"},{"line_number":124,"context_line":"            rendered_documents,"},{"line_number":125,"context_line":"            default_flow_style\u003dFalse,"},{"line_number":126,"context_line":"            explicit_start\u003dTrue,"},{"line_number":127,"context_line":"            explicit_end\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_497e86af","line":124,"range":{"start_line":123,"start_character":12,"end_line":124,"end_character":31},"updated":"2019-06-29 03:24:24.000000000","message":"nit: it\u0027s a little error-prone how these are backwards with yaml.dump_all interface","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"e56d7aa360c708920e7a65b412f5df618a8c6bea","unresolved":false,"context_lines":[{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    if output_stream:"},{"line_number":122,"context_line":"        files.dump_all("},{"line_number":123,"context_line":"            output_stream,"},{"line_number":124,"context_line":"            rendered_documents,"},{"line_number":125,"context_line":"            default_flow_style\u003dFalse,"},{"line_number":126,"context_line":"            explicit_start\u003dTrue,"},{"line_number":127,"context_line":"            explicit_end\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_df41c40b","line":124,"range":{"start_line":123,"start_character":12,"end_line":124,"end_character":31},"in_reply_to":"9fb8cfa7_497e86af","updated":"2019-06-29 13:09:13.000000000","message":"Done","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"},{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"b8dce8965c126997988eac7a8bc1fa89265c551e","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        files.dump_all("},{"line_number":123,"context_line":"            output_stream,"},{"line_number":124,"context_line":"            rendered_documents,"},{"line_number":125,"context_line":"            default_flow_style\u003dFalse,"},{"line_number":126,"context_line":"            explicit_start\u003dTrue,"},{"line_number":127,"context_line":"            explicit_end\u003dTrue)"},{"line_number":128,"context_line":"    else:"},{"line_number":129,"context_line":"        yaml.dump_all("},{"line_number":130,"context_line":"            rendered_documents,"}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_69790ac3","line":127,"range":{"start_line":125,"start_character":0,"end_line":127,"end_character":30},"updated":"2019-06-29 03:24:24.000000000","message":"These could all be shifted as defaults to files.dump_all itself to avoid copy/paste of this.","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"e56d7aa360c708920e7a65b412f5df618a8c6bea","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        files.dump_all("},{"line_number":123,"context_line":"            output_stream,"},{"line_number":124,"context_line":"            rendered_documents,"},{"line_number":125,"context_line":"            default_flow_style\u003dFalse,"},{"line_number":126,"context_line":"            explicit_start\u003dTrue,"},{"line_number":127,"context_line":"            explicit_end\u003dTrue)"},{"line_number":128,"context_line":"    else:"},{"line_number":129,"context_line":"        yaml.dump_all("},{"line_number":130,"context_line":"            rendered_documents,"}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_ff85a85a","line":127,"range":{"start_line":125,"start_character":0,"end_line":127,"end_character":30},"in_reply_to":"9fb8cfa7_69790ac3","updated":"2019-06-29 13:09:13.000000000","message":"I was hesitant to default these in files.dump_all in case someone wanted to use a plain yaml.dump_all (via files) but didn\u0027t want to override the defaults that yaml.dump_all provides.","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"}],"pegleg/engine/util/files.py":[{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"b8dce8965c126997988eac7a8bc1fa89265c551e","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        yaml.dump(data, f, **kwargs)"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"def safe_dump(path, data, flag\u003d\u0027w\u0027, **kwargs):"},{"line_number":252,"context_line":"    if flag \u003d\u003d \u0027w\u0027 and os.path.exists(path):"},{"line_number":253,"context_line":"        raise click.ClickException(\u0027%s already exists, aborting\u0027 % path)"},{"line_number":254,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_e96dfa02","line":251,"range":{"start_line":251,"start_character":36,"end_line":251,"end_character":44},"updated":"2019-06-29 03:24:24.000000000","message":"You could set the indent argument and other less-important parameters here explicitly along with their default values so as to avoid having to put that everywhere else, but that could be a refactor for later. Ditto in the sister methods.","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"e56d7aa360c708920e7a65b412f5df618a8c6bea","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        yaml.dump(data, f, **kwargs)"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"def safe_dump(path, data, flag\u003d\u0027w\u0027, **kwargs):"},{"line_number":252,"context_line":"    if flag \u003d\u003d \u0027w\u0027 and os.path.exists(path):"},{"line_number":253,"context_line":"        raise click.ClickException(\u0027%s already exists, aborting\u0027 % path)"},{"line_number":254,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_7f99b8c1","line":251,"range":{"start_line":251,"start_character":36,"end_line":251,"end_character":44},"in_reply_to":"9fb8cfa7_e96dfa02","updated":"2019-06-29 13:09:13.000000000","message":"I\u0027d like to leave these so that when yaml.dump_all gets called below the defaults of the method are used.  Goal is to have yaml.dump_all and files.dump_all be nearly identical, except the write/append flag.","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"},{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"3e58bed0488ade0a0efaaf2bd2ee56f2ec675f85","unresolved":false,"context_lines":[{"line_number":250,"context_line":""},{"line_number":251,"context_line":"def safe_dump(data, path, flag\u003d\u0027w\u0027, **kwargs):"},{"line_number":252,"context_line":"    if flag \u003d\u003d \u0027w\u0027 and os.path.exists(path):"},{"line_number":253,"context_line":"        raise click.ClickException(\u0027%s already exists, aborting\u0027 % path)"},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"    os.makedirs(os.path.dirname(path), exist_ok\u003dTrue)"},{"line_number":256,"context_line":"    with open(path, flag) as f:"}],"source_content_type":"text/x-python","patch_set":47,"id":"9fb8cfa7_e118aed3","line":253,"range":{"start_line":253,"start_character":14,"end_line":253,"end_character":34},"updated":"2019-06-30 17:30:54.000000000","message":"A more precise exception could be raised here: https://docs.python.org/3/library/exceptions.html#FileExistsError\n\nThe error handling in this project isn\u0027t ideal currently; raising a ClickException everywhere makes it hard to distinguish what to do with any exception on the receiving end. But assuming they all bubble up to the user, it doesn\u0027t really matter, but still isn\u0027t best practice to do this.","commit_id":"a8620cfd8d1fd32db546c3e4abbb26a215369649"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"dfa981982632003d3324e15afb21f71eabb0a46b","unresolved":false,"context_lines":[{"line_number":250,"context_line":""},{"line_number":251,"context_line":"def safe_dump(data, path, flag\u003d\u0027w\u0027, **kwargs):"},{"line_number":252,"context_line":"    if flag \u003d\u003d \u0027w\u0027 and os.path.exists(path):"},{"line_number":253,"context_line":"        raise click.ClickException(\u0027%s already exists, aborting\u0027 % path)"},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"    os.makedirs(os.path.dirname(path), exist_ok\u003dTrue)"},{"line_number":256,"context_line":"    with open(path, flag) as f:"}],"source_content_type":"text/x-python","patch_set":47,"id":"9fb8cfa7_043390f7","line":253,"range":{"start_line":253,"start_character":14,"end_line":253,"end_character":34},"in_reply_to":"9fb8cfa7_e118aed3","updated":"2019-06-30 20:43:22.000000000","message":"this format was copied from the existing dump command, while I agree it\u0027s not ideal I\u0027d prefer to handle making the exceptions more concise in a future patch.","commit_id":"a8620cfd8d1fd32db546c3e4abbb26a215369649"},{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"3e58bed0488ade0a0efaaf2bd2ee56f2ec675f85","unresolved":false,"context_lines":[{"line_number":260,"context_line":""},{"line_number":261,"context_line":"def dump_all(data, path, flag\u003d\u0027w\u0027, **kwargs):"},{"line_number":262,"context_line":"    if flag \u003d\u003d \u0027w\u0027 and os.path.exists(path):"},{"line_number":263,"context_line":"        raise click.ClickException(\u0027%s already exists, aborting\u0027 % path)"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    os.makedirs(os.path.dirname(path), exist_ok\u003dTrue)"},{"line_number":266,"context_line":"    with open(path, flag) as f:"}],"source_content_type":"text/x-python","patch_set":47,"id":"9fb8cfa7_810bf27a","line":263,"range":{"start_line":263,"start_character":8,"end_line":263,"end_character":72},"updated":"2019-06-30 17:30:54.000000000","message":"Ditto.","commit_id":"a8620cfd8d1fd32db546c3e4abbb26a215369649"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"dfa981982632003d3324e15afb21f71eabb0a46b","unresolved":false,"context_lines":[{"line_number":260,"context_line":""},{"line_number":261,"context_line":"def dump_all(data, path, flag\u003d\u0027w\u0027, **kwargs):"},{"line_number":262,"context_line":"    if flag \u003d\u003d \u0027w\u0027 and os.path.exists(path):"},{"line_number":263,"context_line":"        raise click.ClickException(\u0027%s already exists, aborting\u0027 % path)"},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"    os.makedirs(os.path.dirname(path), exist_ok\u003dTrue)"},{"line_number":266,"context_line":"    with open(path, flag) as f:"}],"source_content_type":"text/x-python","patch_set":47,"id":"9fb8cfa7_242ed48b","line":263,"range":{"start_line":263,"start_character":8,"end_line":263,"end_character":72},"in_reply_to":"9fb8cfa7_810bf27a","updated":"2019-06-30 20:43:22.000000000","message":"same thoughts as above","commit_id":"a8620cfd8d1fd32db546c3e4abbb26a215369649"}],"tests/unit/engine/util/test_files.py":[{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"b8dce8965c126997988eac7a8bc1fa89265c551e","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        path \u003d os.path.join(config.get_site_repo(), \u0027site\u0027, \u0027cicd\u0027,"},{"line_number":64,"context_line":"                            \u0027test_out.yaml\u0027)"},{"line_number":65,"context_line":"        files.write(path, \"test text\")"},{"line_number":66,"context_line":"        assert oct(os.stat(path).st_mode \u0026 0o777) \u003d\u003d \u00270o640\u0027"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"def test_file_in_subdir():"}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_8978fec3","line":66,"range":{"start_line":66,"start_character":52,"end_line":66,"end_character":60},"updated":"2019-06-29 03:24:24.000000000","message":"Is there a test validating the permissions of folders (which I take default to 0o027)?\n\nAlso, it would be easier to maintain this if 0o640 were made into a constant somewhere.","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"e56d7aa360c708920e7a65b412f5df618a8c6bea","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        path \u003d os.path.join(config.get_site_repo(), \u0027site\u0027, \u0027cicd\u0027,"},{"line_number":64,"context_line":"                            \u0027test_out.yaml\u0027)"},{"line_number":65,"context_line":"        files.write(path, \"test text\")"},{"line_number":66,"context_line":"        assert oct(os.stat(path).st_mode \u0026 0o777) \u003d\u003d \u00270o640\u0027"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"def test_file_in_subdir():"}],"source_content_type":"text/x-python","patch_set":39,"id":"9fb8cfa7_ff0608ce","line":66,"range":{"start_line":66,"start_character":52,"end_line":66,"end_character":60},"in_reply_to":"9fb8cfa7_8978fec3","updated":"2019-06-29 13:09:13.000000000","message":"Done","commit_id":"e8768f071ed0eefe31c35d154582d1560eb07dc1"},{"author":{"_account_id":23186,"name":"Felipe Monteiro","email":"felipe.carneiro.monteiro@gmail.com","username":"felipe.monteiro"},"change_message_id":"3e58bed0488ade0a0efaaf2bd2ee56f2ec675f85","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from tests.unit.fixtures import temp_path"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"EXPECTED_FILE_PERM \u003d \u00270o640\u0027"},{"line_number":26,"context_line":"EXPECTED_DIR_PERM \u003d \u00270o750\u0027"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class TestFileHelpers(object):"}],"source_content_type":"text/x-python","patch_set":47,"id":"9fb8cfa7_011f02b7","line":26,"range":{"start_line":26,"start_character":20,"end_line":26,"end_character":27},"updated":"2019-06-30 17:30:54.000000000","message":"Shouldn\u0027t this be 0o027? Then again you\u0027d probably have to call config.set_umask() in the tests below first.","commit_id":"a8620cfd8d1fd32db546c3e4abbb26a215369649"},{"author":{"_account_id":29624,"name":"Alexander Hughes","email":"Alexander.Hughes@pm.me","username":"alexanderhughes"},"change_message_id":"dfa981982632003d3324e15afb21f71eabb0a46b","unresolved":false,"context_lines":[{"line_number":23,"context_line":"from tests.unit.fixtures import temp_path"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"EXPECTED_FILE_PERM \u003d \u00270o640\u0027"},{"line_number":26,"context_line":"EXPECTED_DIR_PERM \u003d \u00270o750\u0027"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class TestFileHelpers(object):"}],"source_content_type":"text/x-python","patch_set":47,"id":"9fb8cfa7_e42c3c9a","line":26,"range":{"start_line":26,"start_character":20,"end_line":26,"end_character":27},"in_reply_to":"9fb8cfa7_011f02b7","updated":"2019-06-30 20:43:22.000000000","message":"umask is called in cli tests executing before these.  when umask 0o027 is set, we expect that files are then created with 640 permissions, directories with 750.  I am testing directly to make sure that those permissions occur on file/directory creation.","commit_id":"a8620cfd8d1fd32db546c3e4abbb26a215369649"}]}
