예제 #1
0
def merge_wikitext(ui_, repo, base_dir, tmp_file, in_stream):
    """ Merge changes from a submission zip file into the
        repository. """

    # HgFileOverlay to read bundle files with.
    prev_overlay = HgFileOverlay(ui_, repo, base_dir, tmp_file)

    # Direct overlay to write updates into the repo.
    head_overlay = DirectFiles(os.path.join(repo.root, base_dir))

    arch = ZipFile(in_stream, 'r')
    try:
        base_ver, dummy = unpack_info(arch.read('__INFO__'))
        if not has_version(repo, base_ver):
            # REDFLAG: Think. What about 000000000000?
            #          It is always legal. hmmmm...
            raise SubmitError("Base version: %s not in repository." %
                              base_ver[:12], True)

        # Still need to check for illegal submissions.
        prev_overlay.version = base_ver

        # REDFLAG: revisit.
        # just assert in forking_extract_wikitext and
        # get rid of extra checking / exception raising?
        check_base_shas(arch, prev_overlay)
        # Hmmmm... checking against a version of readonly.txt
        # which may be later than the one that the submitter
        # used.
        check_writable(head_overlay, arch)
        check_merges([name for name in arch.namelist()
                      if name != '__INFO__'],
                     # pylint gives spurious E1101 here ???
                     #pylint: disable-msg=E1101
                     prev_overlay.list_pages(os.path.join(prev_overlay.
                                                          base_path,
                                                          'wikitext')),
                     ArchiveHasher(arch).hexdigest)

        # created, modified, removed, skipped, forked
        op_lut = (set([]), set([]), set([]), set([]), set([]))

        for name in arch.namelist():
            # check_base_sha validates wikinames.
            if name == "__INFO__":
                continue
            action, versioned_name = forking_extract_wikitext(arch,
                                                              prev_overlay,
                                                              head_overlay,
                                                              name)
            op_lut[action].add(versioned_name)
        return op_lut
    finally:
        arch.close()
예제 #2
0
 def get_hg_overlay(self, repo):
     return HgFileOverlay(self.ui_, repo,
                          DEFAULT_WIKI_ROOT,
                          os.path.join(self.tmp_dir,
                                       '_tmp_shared_hg_overlay_tmp'))
예제 #3
0
def execute_wiki_apply(ui_, repo, params, stored_cfg):
    """ Fetch a wiki change submission CHK and apply it to a local
        directory. """
    update_sm = None
    try:
        assert 'REQUEST_URI' in params
        # Get version, i.e. just the hg parent == hg head
        version = get_hg_version(repo)

        # Get target directory.
        params['ISWIKI'] = True
        read_freesite_cfg(ui_, repo, params, stored_cfg)

        update_sm = setup(ui_, repo, params, stored_cfg)

        # Make an FCP download request which will run on the
        # on the state machine.
        request = StatefulRequest(update_sm)
        request.tag = 'submission_zip_request'
        request.in_params.definition = GET_DEF  # To RAM.
        request.in_params.fcp_params = update_sm.params.copy()
        request.in_params.fcp_params['URI'] = params['REQUEST_URI']
        # Knee high barrier against abuse.
        request.in_params.fcp_params['MaxSize'] = FREENET_BLOCK_LEN

        ui_.status("Requesting wiki submission from...\n%s\n" %
                   params['REQUEST_URI'])
        update_sm.start_single_request(request)
        run_until_quiescent(update_sm, params['POLL_SECS'])

        if update_sm.get_state(QUIESCENT).arrived_from(((FINISHING, ))):
            raw_bytes = update_sm.get_state(RUNNING_SINGLE_REQUEST).\
                        final_msg[2]
            assert request.response[0] == 'AllData'
            ui_.status("Fetched %i byte submission.\n" % len(raw_bytes))
            base_ver, submitter = get_info(StringIO.StringIO(raw_bytes))
            ui_.status("Base version: %s, Submitter: %s (unverifiable!)\n" %
                       (base_ver[:12], submitter))

            #print "H_ACKING base_ver to test exception!"
            #base_ver = 'da2f653c5c47b7ee7a814e668aa1d63c50c3a4f3'
            if not has_version(repo, base_ver):
                ui_.warn("That version isn't in the local repo.\n" +
                         "Try running hg fn-pull --aggressive.\n")
                raise util.Abort("%s not in local repo" % base_ver[:12])

            if base_ver != version:
                ui_.warn("Version mismatch! You might have to " +
                         "manually merge.\n")

            # Set up an IFileFunctions that reads the correct versions of
            # the unpatched files out of Mercurial.
            overlay = HgFileOverlay(
                ui_,
                repo,
                # i.e. "<>/wiki_root" NOT "
                # <>/wiki_root/wikitext"
                os.path.join(repo.root, params['WIKI_ROOT']),
                # cleanup() in finally deletes this.
                make_temp_file(update_sm.ctx.bundle_cache.base_dir))
            overlay.version = base_ver
            validate_wikitext(overlay)
            updates = unbundle_wikitext(overlay, StringIO.StringIO(raw_bytes))
            for index, label in enumerate(
                ('CREATED', 'MODIFIED', 'REMOVED', 'ALREADY PATCHED')):
                if len(updates[index]) > 0:
                    values = list(updates[index])
                    values.sort()
                    ui_.status('%s:\n%s\n' % (label, '\n'.join(values)))

    finally:
        cleanup(update_sm)