diff --git a/git_cl.py b/git_cl.py index d69a1cc83..869bbe364 100755 --- a/git_cl.py +++ b/git_cl.py @@ -4509,6 +4509,14 @@ def CMDsplit(parser, args): help='Sends your change to the CQ after an approval. Only ' 'works on repos that have the Auto-Submit label ' 'enabled') + parser.add_option('--max-depth', + type='int', + default=0, + help='The max depth to look for OWNERS files. Useful for ' + 'controlling the granularity of the split CLs, e.g. ' + '--max-depth=1 will only split by top-level ' + 'directory. Specifying a value less than 1 means no ' + 'limit on max depth.') options, _ = parser.parse_args(args) if not options.description_file: @@ -4517,10 +4525,10 @@ def CMDsplit(parser, args): def WrappedCMDupload(args): return CMDupload(OptionParser(), args) - return split_cl.SplitCl( - options.description_file, options.comment_file, Changelist, - WrappedCMDupload, options.dry_run, options.cq_dry_run, - options.enable_auto_submit, settings.GetRoot()) + return split_cl.SplitCl(options.description_file, options.comment_file, + Changelist, WrappedCMDupload, options.dry_run, + options.cq_dry_run, options.enable_auto_submit, + options.max_depth, settings.GetRoot()) @subcommand.usage('DEPRECATED') diff --git a/split_cl.py b/split_cl.py index 420c8ad6e..9afc3d358 100644 --- a/split_cl.py +++ b/split_cl.py @@ -140,7 +140,7 @@ def UploadCl(refactor_branch, refactor_branch_upstream, directory, files, publish=True) -def GetFilesSplitByOwners(files): +def GetFilesSplitByOwners(files, max_depth): """Returns a map of files split by OWNERS file. Returns: @@ -149,7 +149,13 @@ def GetFilesSplitByOwners(files): """ files_split_by_owners = {} for action, path in files: - dir_with_owners = os.path.dirname(path) + # normpath() is important to normalize separators here, in prepration for + # str.split() before. It would be nicer to use something like pathlib here + # but alas... + dir_with_owners = os.path.normpath(os.path.dirname(path)) + if max_depth >= 1: + dir_with_owners = os.path.join( + *dir_with_owners.split(os.path.sep)[:max_depth]) # Find the closest parent directory with an OWNERS file. while (dir_with_owners not in files_split_by_owners and not os.path.isfile(os.path.join(dir_with_owners, 'OWNERS'))): @@ -184,7 +190,7 @@ def PrintClInfo(cl_index, num_cls, directory, file_paths, description, def SplitCl(description_file, comment_file, changelist, cmd_upload, dry_run, - cq_dry_run, enable_auto_submit, repository_root): + cq_dry_run, enable_auto_submit, max_depth, repository_root): """"Splits a branch into smaller branches and uploads CLs. Args: @@ -195,6 +201,8 @@ def SplitCl(description_file, comment_file, changelist, cmd_upload, dry_run, dry_run: Whether this is a dry run (no branches or CLs created). cq_dry_run: If CL uploads should also do a cq dry run. enable_auto_submit: If CL uploads should also enable auto submit. + max_depth: The maximum directory depth to search for OWNERS files. A value + less than 1 means no limit. Returns: 0 in case of success. 1 in case of error. @@ -224,7 +232,7 @@ def SplitCl(description_file, comment_file, changelist, cmd_upload, dry_run, assert refactor_branch_upstream, \ "Branch %s must have an upstream." % refactor_branch - files_split_by_owners = GetFilesSplitByOwners(files) + files_split_by_owners = GetFilesSplitByOwners(files, max_depth) num_cls = len(files_split_by_owners) print('Will split current branch (' + refactor_branch + ') into ' +