OLD | NEW |
(Empty) | |
| 1 # Copyright 2015 Google Inc. |
| 2 # |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 # you may not use this file except in compliance with the License. |
| 5 # You may obtain a copy of the License at |
| 6 # |
| 7 # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 # |
| 9 # Unless required by applicable law or agreed to in writing, software |
| 10 # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 # See the License for the specific language governing permissions and |
| 13 # limitations under the License. |
| 14 |
| 15 """Contains utilities to help deal with the dependencies of a patchset.""" |
| 16 |
| 17 from codereview import models |
| 18 |
| 19 |
| 20 DEPENDENCY_DELIMITER = ':' |
| 21 |
| 22 |
| 23 def remove_dependencies_from_all_patchsets(issue): |
| 24 """Remove all dependencies from all patchsets of this issue. |
| 25 |
| 26 This method should be called when a CL is closed or deleted. |
| 27 |
| 28 Args: |
| 29 issue: (models.Issue) The issue we to remove dependencies to. |
| 30 """ |
| 31 for patchset in issue.patchsets: |
| 32 remove_dependencies(patchset) |
| 33 |
| 34 |
| 35 def remove_all_patchsets_as_dependents(issue): |
| 36 """Remove all patchsets of this issue as dependents. |
| 37 |
| 38 This method should be called when a CL is deleted. |
| 39 |
| 40 Args: |
| 41 issue: (models.Issue) The issue whose dependencies we want to update. |
| 42 """ |
| 43 for patchset in issue.patchsets: |
| 44 remove_as_dependent(patchset) |
| 45 |
| 46 |
| 47 def remove_dependencies(patchset): |
| 48 """Remove all dependencies on this patchset. |
| 49 |
| 50 This method should be called when a patchset is deleted. |
| 51 |
| 52 Args: |
| 53 patchset: (models.PatchSet) The patchset we want to remove dependencies to. |
| 54 """ |
| 55 _update_dependents(patchset, remove_dependency=True) |
| 56 |
| 57 |
| 58 def remove_as_dependent(patchset): |
| 59 """Remove the specified patchset as a dependent. |
| 60 |
| 61 This method should be called when a patchset is deleted. |
| 62 |
| 63 Args: |
| 64 patchset: (models.PatchSet) The patchset we want to remove as a dependent. |
| 65 """ |
| 66 dependency_str = patchset.depends_on_patchset |
| 67 if not dependency_str: |
| 68 return |
| 69 depends_on_tokens = get_dependency_tokens(dependency_str) |
| 70 depends_on_issue = models.Issue.get_by_id(int(depends_on_tokens[0])) |
| 71 if not depends_on_issue: |
| 72 return |
| 73 depends_on_patchset = models.PatchSet.get_by_id( |
| 74 int(depends_on_tokens[1]), parent=depends_on_issue.key) |
| 75 if not depends_on_patchset: |
| 76 return |
| 77 if depends_on_patchset.dependent_patchsets: |
| 78 target_str = _get_dependency_str(patchset.issue_key.id(), |
| 79 patchset.key.id()) |
| 80 if target_str in depends_on_patchset.dependent_patchsets: |
| 81 depends_on_patchset.dependent_patchsets.remove(target_str) |
| 82 depends_on_patchset.put() |
| 83 |
| 84 |
| 85 def get_dependency_tokens(dependency_str): |
| 86 return dependency_str.split(DEPENDENCY_DELIMITER) |
| 87 |
| 88 |
| 89 def _get_dependency_str(issue_key, patchset_key): |
| 90 return '%s%s%s' % (issue_key, DEPENDENCY_DELIMITER, patchset_key) |
| 91 |
| 92 |
| 93 def _update_dependents(patchset, remove_dependency): |
| 94 if not patchset: |
| 95 return |
| 96 for dependency_str in patchset.dependent_patchsets: |
| 97 depends_on_tokens = get_dependency_tokens(dependency_str) |
| 98 dependent_issue = models.Issue.get_by_id(int(depends_on_tokens[0])) |
| 99 if not dependent_issue: |
| 100 continue |
| 101 dependent_patchset = models.PatchSet.get_by_id( |
| 102 int(depends_on_tokens[1]), parent=dependent_issue.key) |
| 103 if not dependent_patchset: |
| 104 continue |
| 105 dependent_str = _get_dependency_str(patchset.issue_key.id(), |
| 106 patchset.key.id()) |
| 107 if remove_dependency: |
| 108 # Sanity check that the dependency_str of this patchset is what we expect |
| 109 # before we delete it. |
| 110 if dependent_patchset.depends_on_patchset == dependent_str: |
| 111 dependent_patchset.depends_on_patchset = "" |
| 112 dependent_patchset.put() |
| 113 else: |
| 114 # Sanity check that this patchset has no existing dependency before we add |
| 115 # a new one. |
| 116 if dependent_patchset.depends_on_patchset == "": |
| 117 dependent_patchset.depends_on_patchset = dependent_str |
| 118 dependent_patchset.put() |
| 119 |
| 120 |
| 121 def mark_as_dependent_and_get_dependency_str( |
| 122 dependency_str, dependent_issue_key, dependent_patchset_key): |
| 123 """Marks the specified patchset as a dependent and returns its dependency str. |
| 124 |
| 125 Args: |
| 126 dependency_str: (str) The issue and patchset the specified patchset depends |
| 127 on. |
| 128 dependent_issue_key: (str) The issue key of the patchset we want to mark as |
| 129 dependent. |
| 130 dependent_patchset_key: (str) The key of the patchset we want to mark as |
| 131 dependent. |
| 132 """ |
| 133 if not dependency_str: |
| 134 return None |
| 135 depends_on_tokens = get_dependency_tokens(dependency_str) |
| 136 depends_on_issue = models.Issue.get_by_id(int(depends_on_tokens[0])) |
| 137 if not depends_on_issue: |
| 138 return None |
| 139 depends_on_patchset = models.PatchSet.get_by_id( |
| 140 int(depends_on_tokens[1]), parent=depends_on_issue.key) |
| 141 if not depends_on_patchset: |
| 142 return None |
| 143 |
| 144 if not depends_on_patchset.dependent_patchsets: |
| 145 depends_on_patchset.dependent_patchsets = [] |
| 146 dependent_str = _get_dependency_str(dependent_issue_key, |
| 147 dependent_patchset_key) |
| 148 if dependent_str not in depends_on_patchset.dependent_patchsets: |
| 149 depends_on_patchset.dependent_patchsets.append(dependent_str) |
| 150 depends_on_patchset.put() |
| 151 |
| 152 return dependency_str |
| 153 |
OLD | NEW |