def test_delete_entries(self): fs = MockFileSystem() fs.write_text_file(self._changelog_path, self._example_changelog) ChangeLog(self._changelog_path, fs).delete_entries(8) actual_contents = fs.read_text_file(self._changelog_path) expected_contents = """2011-10-11 Antti Koivisto <*****@*****.**> Resolve regular and visited link style in a single pass https://bugs.webkit.org/show_bug.cgi?id=69838 Reviewed by Darin Adler We can simplify and speed up selector matching by removing the recursive matching done to generate the style for the :visited pseudo selector. Both regular and visited link style can be generated in a single pass through the style selector. == Rolled over to ChangeLog-2009-06-16 == """ self.assertEqual(actual_contents.splitlines(), expected_contents.splitlines()) ChangeLog(self._changelog_path, fs).delete_entries(2) actual_contents = fs.read_text_file(self._changelog_path) expected_contents = "== Rolled over to ChangeLog-2009-06-16 ==\n" self.assertEqual(actual_contents.splitlines(), expected_contents.splitlines())
def test_set_short_description_and_bug_url(self): fs = MockFileSystem() changelog_contents = u"%s\n%s" % ( self._new_entry_boilerplate_with_bugurl, self._example_changelog) fs.write_text_file(self._changelog_path, changelog_contents) short_description = "A short description" bug_url = "http://example.com/b/2344" ChangeLog(self._changelog_path, fs).set_short_description_and_bug_url( short_description, bug_url) actual_contents = fs.read_text_file(self._changelog_path) expected_contents = changelog_contents.replace( "Need a short description (OOPS!).", short_description) self.assertEqual(actual_contents.splitlines(), expected_contents.splitlines()) changelog_contents = u"%s\n%s" % (self._new_entry_boilerplate, self._example_changelog) fs.write_text_file(self._changelog_path, changelog_contents) short_description = "A short description 2" bug_url = "http://example.com/b/2345" ChangeLog(self._changelog_path, fs).set_short_description_and_bug_url( short_description, bug_url) actual_contents = fs.read_text_file(self._changelog_path) expected_message = "%s\n %s" % (short_description, bug_url) expected_contents = changelog_contents.replace( "Need a short description (OOPS!).\n Need the bug URL (OOPS!).", expected_message) self.assertEqual(actual_contents.splitlines(), expected_contents.splitlines())
def run(self, state): bug_id = state.get("bug_id") if not bug_id and state.get("patch"): bug_id = state.get("patch").bug_id() reviewer = self._options.reviewer if not reviewer: if not bug_id: _log.info( "No bug id provided and --reviewer= not provided. Not updating ChangeLogs with reviewer." ) return reviewer = self._guess_reviewer_from_bug(bug_id) if not reviewer: _log.info( "Failed to guess reviewer from bug %s and --reviewer= not provided. Not updating ChangeLogs with reviewer." % bug_id) return # cached_lookup("changelogs") is always absolute paths. for changelog_path in self.cached_lookup(state, "changelogs"): ChangeLog(changelog_path).set_reviewer(reviewer) # Tell the world that we just changed something on disk so that the cached diff is invalidated. self.did_modify_checkout(state)
def test_set_reviewer(self): fs = MockFileSystem() changelog_contents = u"%s\n%s" % ( self._new_entry_boilerplate_with_bugurl, self._example_changelog) reviewer_name = 'Test Reviewer' fs.write_text_file(self._changelog_path, changelog_contents) ChangeLog(self._changelog_path, fs).set_reviewer(reviewer_name) actual_contents = fs.read_text_file(self._changelog_path) expected_contents = changelog_contents.replace('NOBODY (OOPS!)', reviewer_name) self.assertEqual(actual_contents.splitlines(), expected_contents.splitlines()) changelog_contents = u"%s\n%s" % ( self._new_entry_boilerplate_with_unreviewed, self._example_changelog) fs.write_text_file(self._changelog_path, changelog_contents) ChangeLog(self._changelog_path, fs).set_reviewer(reviewer_name) actual_contents = fs.read_text_file(self._changelog_path) self.assertEqual(actual_contents.splitlines(), changelog_contents.splitlines()) changelog_contents_without_reviewer_line = u"%s\n%s" % ( self._new_entry_boilerplate_without_reviewer_line, self._example_changelog) fs.write_text_file(self._changelog_path, changelog_contents_without_reviewer_line) ChangeLog(self._changelog_path, fs).set_reviewer(reviewer_name) actual_contents = fs.read_text_file(self._changelog_path) self.assertEqual(actual_contents.splitlines(), expected_contents.splitlines()) changelog_contents_without_reviewer_line = u"%s\n%s" % ( self._new_entry_boilerplate_without_reviewer_multiple_bugurl, self._example_changelog) fs.write_text_file(self._changelog_path, changelog_contents_without_reviewer_line) ChangeLog(self._changelog_path, fs).set_reviewer(reviewer_name) actual_contents = fs.read_text_file(self._changelog_path) changelog_contents = u"%s\n%s" % ( self._new_entry_boilerplate_with_multiple_bugurl, self._example_changelog) expected_contents = changelog_contents.replace('NOBODY (OOPS!)', reviewer_name) self.assertEqual(actual_contents.splitlines(), expected_contents.splitlines())
def run(self, state): self._tool.executive.run_and_throw_if_fail( self._tool.deprecated_port().prepare_changelog_command()) changelog_paths = self._tool.checkout().modified_changelogs( git_commit=None) for changelog_path in changelog_paths: ChangeLog(changelog_path).update_with_unreviewed_message( state["changelog_message"])
def test_prepend_text(self): fs = MockFileSystem() fs.write_text_file(self._changelog_path, self._example_changelog) ChangeLog(self._changelog_path, fs).prepend_text(self._example_entry + "\n") actual_contents = fs.read_text_file(self._changelog_path) expected_contents = self._example_entry + "\n" + self._example_changelog self.assertEqual(actual_contents.splitlines(), expected_contents.splitlines())
def run(self, state): # This could move to prepare-ChangeLog by adding a --revert= option. self._tool.executive.run_and_throw_if_fail(self._tool.port().prepare_changelog_command()) changelog_paths = self._tool.checkout().modified_changelogs(git_commit=None) bug_url = self._tool.bugs.bug_url_for_bug_id(state["bug_id"]) if state["bug_id"] else None message = self._message_for_revert(state["revision_list"], state["reason"], bug_url) for changelog_path in changelog_paths: # FIXME: Seems we should prepare the message outside of changelogs.py and then just pass in # text that we want to use to replace the reviewed by line. ChangeLog(changelog_path).update_with_unreviewed_message(message)
def _ensure_bug_url(self, state): if not state.get("bug_id"): return bug_id = state.get("bug_id") changelogs = self.cached_lookup(state, "changelogs") for changelog_path in changelogs: changelog = ChangeLog(changelog_path) if not changelog.latest_entry().bug_id(): changelog.set_short_description_and_bug_url( self.cached_lookup(state, "bug_title"), self._tool.bugs.bug_url_for_bug_id(bug_id))
def run(self, state): # This could move to prepare-ChangeLog by adding a --revert= option. self._run_script("prepare-ChangeLog") changelog_paths = self._tool.checkout().modified_changelogs( git_commit=None, squash=False) bug_url = self._tool.bugs.bug_url_for_bug_id( state["bug_id"]) if state["bug_id"] else None for changelog_path in changelog_paths: # FIXME: Seems we should prepare the message outside of changelogs.py and then just pass in # text that we want to use to replace the reviewed by line. ChangeLog(changelog_path).update_for_revert( state["revision"], state["reason"], bug_url)
def _assert_message_for_revert_output(self, args, expected_entry): changelog_contents = u"%s\n%s" % (ChangeLogTest._new_entry_boilerplate, ChangeLogTest._example_changelog) changelog_path = self._write_tmp_file_with_contents(changelog_contents.encode("utf-8")) changelog = ChangeLog(changelog_path) changelog.update_with_unreviewed_message(PrepareChangeLogForRevert._message_for_revert(*args)) actual_entry = changelog.latest_entry() os.remove(changelog_path) self.assertEquals(actual_entry.contents(), expected_entry) self.assertEquals(actual_entry.reviewer_text(), None) # These checks could be removed to allow this to work on other entries: self.assertEquals(actual_entry.author_name(), "Eric Seidel") self.assertEquals(actual_entry.author_email(), "*****@*****.**")
def _assert_message_for_revert_output(self, args, expected_entry): changelog_contents = u"%s\n%s" % (changelog_unittest.ChangeLogTest._new_entry_boilerplate, changelog_unittest.ChangeLogTest._example_changelog) changelog_path = "ChangeLog" fs = MockFileSystem({changelog_path: changelog_contents.encode("utf-8")}) changelog = ChangeLog(changelog_path, fs) changelog.update_with_unreviewed_message(PrepareChangeLogForRevert._message_for_revert(*args)) actual_entry = changelog.latest_entry() self.assertMultiLineEqual(actual_entry.contents(), expected_entry) self.assertIsNone(actual_entry.reviewer_text()) # These checks could be removed to allow this to work on other entries: self.assertEqual(actual_entry.author_name(), "Eric Seidel") self.assertEqual(actual_entry.author_email(), "*****@*****.**")
def _ensure_bug_url(self, state): if not state.get("bug_id"): return bug_id = state.get("bug_id") changelogs = self.cached_lookup(state, "changelogs") for changelog_path in changelogs: changelog = ChangeLog(changelog_path, self._tool.filesystem) if not changelog.latest_entry(): _log.error('Invalid ChangeLog at: {}'.format(changelog_path)) sys.exit(1) if not changelog.latest_entry().bug_id(): changelog.set_short_description_and_bug_url( self.cached_lookup(state, "bug_title"), self._tool.bugs.bug_url_for_bug_id(bug_id))
def run(self, state): # FIXME: For now we disable this check when a user is driving the script # this check is too draconian (and too poorly tested) to foist upon users. if not self._options.non_interactive: return for changelog_path in self.cached_lookup(state, "changelogs"): changelog_entry = ChangeLog(changelog_path).latest_entry() if self._has_valid_reviewer(changelog_entry): continue reviewer_text = changelog_entry.reviewer_text() if reviewer_text: log("%s found in %s does not appear to be a valid reviewer according to committers.py." % (reviewer_text, changelog_path)) error( '%s neither lists a valid reviewer nor contains the string "Unreviewed" or "Rubber stamp" (case insensitive).' % changelog_path)
def commit_message_for_this_commit(self, git_commit, squash): changelog_paths = self.modified_changelogs(git_commit, squash) if not len(changelog_paths): raise ScriptError(message="Found no modified ChangeLogs, cannot create a commit message.\n" "All changes require a ChangeLog. See:\n" "http://webkit.org/coding/contributing.html") changelog_messages = [] for changelog_path in changelog_paths: log("Parsing ChangeLog: %s" % changelog_path) changelog_entry = ChangeLog(changelog_path).latest_entry() if not changelog_entry: raise ScriptError(message="Failed to parse ChangeLog: %s" % os.path.abspath(changelog_path)) changelog_messages.append(changelog_entry.contents()) # FIXME: We should sort and label the ChangeLog messages like commit-log-editor does. return CommitMessage("".join(changelog_messages).splitlines())
def run(self, state): bug_id = state.get("bug_id") if not bug_id and state.get("patch"): bug_id = state.get("patch").bug_id() reviewer = self._options.reviewer if not reviewer: if not bug_id: log("No bug id provided and --reviewer= not provided. Not updating ChangeLogs with reviewer.") return reviewer = self._guess_reviewer_from_bug(bug_id) if not reviewer: log("Failed to guess reviewer from bug %s and --reviewer= not provided. Not updating ChangeLogs with reviewer." % bug_id) return os.chdir(self._tool.scm().checkout_root) for changelog_path in self._tool.checkout().modified_changelogs(self._options.git_commit, self._options.squash): ChangeLog(changelog_path).set_reviewer(reviewer)
def _resolve_existing_entry(self, changelog_path): # When this is called, the top entry in the ChangeLog was just created # by prepare-ChangeLog, as an clean updated version of the one below it. with self._tool.filesystem.open_text_file_for_reading(changelog_path) as changelog_file: entries_gen = ChangeLog.parse_entries_from_file(changelog_file) entries = zip(entries_gen, range(2)) if not len(entries): raise Exception("Expected to find at least two ChangeLog entries in %s but found none." % changelog_path) if len(entries) == 1: # If we get here, it probably means we've just rolled over to a # new CL file, so we don't have anything to resolve. return (new_entry, _), (old_entry, _) = entries final_entry = self._merge_entries(old_entry, new_entry) changelog = ChangeLog(changelog_path, self._tool.filesystem) changelog.delete_entries(2) changelog.prepend_text(final_entry)
def run(self, state): # FIXME: For now we disable this check when a user is driving the script # this check is too draconian (and too poorly tested) to foist upon users. if not self._options.non_interactive: return # FIXME: We should figure out how to handle the current working # directory issue more globally. os.chdir(self._tool.scm().checkout_root) for changelog_path in self._tool.checkout().modified_changelogs( self._options.git_commit, self._options.squash): changelog_entry = ChangeLog(changelog_path).latest_entry() if self._has_valid_reviewer(changelog_entry): continue reviewer_text = changelog_entry.reviewer_text() if reviewer_text: log("%s found in %s does not appear to be a valid reviewer according to committers.py." % (reviewer_text, changelog_path)) error( '%s neither lists a valid reviewer nor contains the string "Unreviewed" or "Rubber stamp" (case insensitive).' % changelog_path)