def build(config, archiver, operators):
try:<EOL><INDENT>logger.debug(f"<STR_LIT>")<EOL>archiver = archiver.cls(config)<EOL>revisions = archiver.revisions(config.path, config.max_revisions)<EOL><DEDENT>except InvalidGitRepositoryError:<EOL><INDENT>logger.info(f"<STR_LIT>")<EOL>archiver = FilesystemArchiver(config)<EOL>revisions = archiver.revisions(config.path, config.max_revisions)<EOL><DEDENT>except Exception as e:<EOL><INDENT>if hasattr(e, "<STR_LIT:message>"):<EOL><INDENT>logger.error(f"<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>logger.error(f"<STR_LIT>")<EOL><DEDENT>exit(<NUM_LIT:1>)<EOL><DEDENT>state = State(config, archiver=archiver)<EOL>state.ensure_exists()<EOL>index = state.index[archiver.name]<EOL>revisions = [revision for revision in revisions if revision not in index]<EOL>logger.info(<EOL>f"<STR_LIT>"<EOL>)<EOL>_op_desc = "<STR_LIT:U+002C>".join([operator.name for operator in operators])<EOL>logger.info(f"<STR_LIT>")<EOL>bar = Bar("<STR_LIT>", max=len(revisions) * len(operators))<EOL>state.operators = operators<EOL>try:<EOL><INDENT>with multiprocessing.Pool(processes=len(operators)) as pool:<EOL><INDENT>for revision in revisions:<EOL><INDENT>archiver.checkout(revision, config.checkout_options)<EOL>stats = {"<STR_LIT>": {}}<EOL>data = pool.starmap(<EOL>run_operator,<EOL>[(operator, revision, config) for operator in operators],<EOL>)<EOL>for operator_name, result in data:<EOL><INDENT>roots = []<EOL>for entry in result.keys():<EOL><INDENT>parent = pathlib.Path(entry).parents[<NUM_LIT:0>]<EOL>if parent not in roots:<EOL><INDENT>roots.append(parent)<EOL><DEDENT><DEDENT>for root in roots:<EOL><INDENT>aggregates = [<EOL>path<EOL>for path in result.keys()<EOL>if root in pathlib.Path(path).parents<EOL>]<EOL>result[str(root)] = {}<EOL>for metric in resolve_operator(operator_name).cls.metrics:<EOL><INDENT>func = metric.aggregate<EOL>values = [<EOL>result[aggregate][metric.name]<EOL>for aggregate in aggregates<EOL>if aggregate in result<EOL>and metric.name in result[aggregate]<EOL>]<EOL>if len(values) > <NUM_LIT:0>:<EOL><INDENT>result[str(root)][metric.name] = func(values)<EOL><DEDENT><DEDENT><DEDENT>stats["<STR_LIT>"][operator_name] = result<EOL>bar.next()<EOL><DEDENT>ir = index.add(revision, operators=operators)<EOL>ir.store(config, archiver, stats)<EOL><DEDENT><DEDENT>index.save()<EOL>bar.finish()<EOL><DEDENT>except Exception as e:<EOL><INDENT>logger.error(f"<STR_LIT>")<EOL>raise e<EOL><DEDENT>finally:<EOL><INDENT>archiver.finish()<EOL><DEDENT>
Build the history given a archiver and collection of operators.

:param config: The wily configuration
:type  config: :namedtuple:`wily.config.WilyConfig`

:param archiver: The archiver to use
:type  archiver: :namedtuple:`wily.archivers.Archiver`

:param operators: The list of operators to execute
:type operators: `list` of :namedtuple:`wily.operators.Operator`