def create_read_permissions_list(protects_dict_list, requested_perm=READ): """The results are used to test for repo read permissions and as such are filtered to serve the algorithm. Return a list of depotFile from protects_dict_list depotFile which grant the requested_perm. Return exclusion lines which which do not start with '=' except those which start with '=requested_perm'. Additionally exclude list inclusions. """ # Build a list of matching lines. lines = [] for pd in protects_dict_list: # skip all =perm unless it matches the requested perm if (pd['perm'].startswith('=') and pd['perm'] != "=" + requested_perm): # eg: "=read user x * -//path/" continue if 'unmap' in pd: # Unmapping ANY permission unmaps ALL permissions lines.append('-' + pd['depotFile']) continue if permission_includes(pd['perm'], requested_perm): if pd['perm'] != 'list': # skip list inclusions lines.append(pd['depotFile']) quoted = [enquote(x) for x in lines] return quoted
def create_read_permissions_map(protects_dict_list, requested_perm=READ): """The results are used to test for repo read permissions and as such are filtered to serve the algorithm. Return a new MapApi instance that maps in all of protects_dict_list depotFile lines that grant the requested_perm Also map in exclusion lines which which do not start with '=' except those which start with '=requested_perm'. Additionally exclude list inclusions. """ # Build a list of matching lines. lines = [] for pd in protects_dict_list: # skip all =perm unless it matches the requested perm if (pd['perm'].startswith('=') and pd['perm'] != "=" + requested_perm): # eg: "=read user x * -//path/" continue if 'unmap' in pd: # Unmapping ANY permission unmaps ALL permissions lines.append('-' + pd['depotFile']) continue if permission_includes(pd['perm'], requested_perm): if pd['perm'] != 'list': # skip list inclusions lines.append(pd['depotFile']) # P4.Map() requires space-riddled paths to be quoted paths # to avoid accidentally splitting a # single path into lhs/rhs. quoted = [enquote(x) for x in lines] mapapi = P4.Map(quoted) return mapapi
def _create_map_for_perm(protects_dict_list, requested_perm): """Return a new MapApi instance that maps in all of protects_dict_list depotFile lines that grant the requested_perm and excludes all lines that exclude it. """ # Build a list of matching lines. lines = [] for pd in protects_dict_list: if 'unmap' in pd: # Unmapping ANY permission unmaps ALL permissions lines.append('-' + pd['depotFile']) continue if permission_includes(pd['perm'], requested_perm): lines.append(pd['depotFile']) # P4.Map() requires space-riddled paths to be quoted paths # to avoid accidentally splitting a # single path into lhs/rhs. quoted = [enquote(x) for x in lines] mapapi = P4.Map(quoted) return mapapi
def _enquote_list(l): """Return a new list with every space-infected item wrapped in quotes.""" return [p4gf_path.enquote(e) for e in l]
def stream_import_exclude(stream_paths): """Convert import paths to exclude for conversion to submodules. If the stream lacks a "share ..." path entry, the input will be returned unmodified, meaning no submodules (can or) will be created. Without the top-level directory, we cannot add a .gitmodules file as it would be outside of the client view. Any import path entry that lacks a depot_path will not be considered a candidate for conversion to a submodule, since it is considered to be a part of the view. Likewise any path not ending with /... cannot be converted to a submodule (potentially overlaps the submodule with files from the stream). Nested paths are currently not supported; only the deepest path will be converted to a submodule. """ # # share ... --> share ... # import x/... //depot/x/...@5 --> exclude x/... # import y/... //depot/y/... --> import y/... //depot/y/... # import y/z/... //depot/y/z/... --> exclude y/z/... # if 'share ...' not in stream_paths: # Without a top-level directory, adding .gitmodules would fall # outside of the client view and thus fail when pushed to Perforce. return stream_paths numbered = list( (n, ) + _split_path(entry) for n, entry in enumerate(stream_paths)) # sort by the view path to make nested paths easier to find numbered.sort(key=lambda e: e[2]) # find path entries that could be imported as submodules submod_candidates = set() previous_view = None previous_pos = 0 for pos, path_type, view_path, depot_path in numbered: if depot_path is None: continue # this operation does not concern itself with changelist specifiers if '@' in depot_path: depot_path = depot_path.split('@')[0] if previous_view and view_path.startswith(previous_view[:-4]): submod_candidates.remove(previous_pos) if not depot_path.endswith("/...") or not view_path.endswith("/..."): continue submod_candidates.add(pos) previous_pos = pos previous_view = view_path # restore the original order of the view paths numbered.sort(key=lambda e: e[0]) # replace 'import' with 'exclude' in submodule candidates for pos in submod_candidates: entry = numbered[pos] numbered[pos] = (entry[0], 'exclude', entry[2], None) # drop the first column, convert back to possibly quoted strings results = [] for pos, path_type, view_path, depot_path in numbered: qv = p4gf_path.enquote(view_path) qd = p4gf_path.enquote(depot_path) if depot_path else '' results.append("{} {} {}".format(path_type, qv, qd).strip()) return results