1515# You should have received a copy of the GNU General Public License 
1616# along with this program.  If not, see <http://www.gnu.org/licenses/>. 
1717
18+ from  abc  import  ABC , abstractmethod 
1819from  datetime  import  datetime 
20+ from  typing  import  Type 
1921
20- from  .errors  import  VersionError 
21- from  .version  import  Version , parse_version 
22+ from  pontos .version .errors  import  VersionError 
2223
24+ from  .version  import  Version 
2325
24- class  VersionCalculator :
25-     def  next_patch_version (self , current_version : Version ) ->  Version :
26-         """ 
27-         Get the next patch version from a valid version 
2826
29-         Examples: 
30-             "1.2.3" will return "1.2.4" 
31-             "1.2.3.dev1" will return "1.2.3" 
27+ class  VersionCalculator (ABC ):
28+     """ 
29+     An abstract base class for calculating a next version from a version 
30+     """ 
31+ 
32+     version_cls : Type [Version ]
33+ 
34+     @classmethod  
35+     def  version_from_string (cls , version : str ) ->  Version :
3236        """ 
37+         Create a version from a version string 
3338
34-         if  current_version .is_prerelease :
35-             next_version  =  parse_version (
36-                 f"{ current_version .major }  
37-                 f"{ current_version .minor }  
38-                 f"{ current_version .micro }  
39-             )
40-         else :
41-             next_version  =  parse_version (
42-                 f"{ current_version .major }  
43-                 f"{ current_version .minor }  
44-                 f"{ current_version .micro  +  1 }  
45-             )
39+         Args: 
40+             version: Version string to parse 
4641
47-         return  next_version 
42+         Raises: 
43+             VersionError: If the version string is invalid. 
44+ 
45+         Returns: 
46+             A new version instance 
47+         """ 
48+         return  cls .version_cls .from_string (version )
4849
49-     def  next_calendar_version (self , current_version : Version ) ->  Version :
50+     @classmethod  
51+     def  next_calendar_version (cls , current_version : Version ) ->  Version :
5052        """ 
5153        Find the correct next calendar version by checking latest version and 
5254        the today's date 
5355
5456        Raises: 
55-             VersionError if  version is invalid. 
57+             VersionError: If  version is invalid. 
5658        """ 
57- 
5859        today  =  datetime .today ()
5960        current_year_short  =  today .year  %  100 
6061
6162        if  current_version .major  <  current_year_short  or  (
6263            current_version .major  ==  current_year_short 
6364            and  current_version .minor  <  today .month 
6465        ):
65-             return  parse_version (f"{ current_year_short } { today .month }  )
66+             return  cls .version_from_string (
67+                 f"{ current_year_short } { today .month }  
68+             )
6669
6770        if  (
6871            current_version .major  ==  today .year  %  100 
6972            and  current_version .minor  ==  today .month 
7073        ):
7174            if  current_version .dev  is  None :
72-                 release_version  =  parse_version (
75+                 release_version  =  cls . version_from_string (
7376                    f"{ current_year_short } { today .month }  
74-                     f"{ current_version .micro  +  1 }  
77+                     f"{ current_version .patch  +  1 }  
7578                )
7679            else :
77-                 release_version  =  parse_version (
80+                 release_version  =  cls . version_from_string (
7881                    f"{ current_year_short } { today .month }  
79-                     f"{ current_version .micro }  
82+                     f"{ current_version .patch }  
8083                )
8184            return  release_version 
8285        else :
@@ -85,147 +88,81 @@ def next_calendar_version(self, current_version: Version) -> Version:
8588                f"'{ current_year_short } { today .month }  
8689            )
8790
88-     def  next_minor_version (self , current_version : Version ) ->  Version :
89-         """ 
90-         Get the next minor version from a valid version 
91- 
92-         Examples: 
93-             "1.2.3" will return "1.3.0" 
94-             "1.2.3.dev1" will return "1.3.0" 
95-         """ 
96-         return  parse_version (
97-             f"{ current_version .major } { current_version .minor  +  1 }  
98-         )
99- 
100-     def  next_major_version (self , current_version : Version ) ->  Version :
91+     @classmethod  
92+     def  next_major_version (cls , current_version : Version ) ->  Version :
10193        """ 
10294        Get the next major version from a valid version 
10395
10496        Examples: 
10597            "1.2.3" will return "2.0.0" 
10698            "1.2.3.dev1" will return "2.0.0" 
99+             "1.2.3-alpha1" will return "2.0.0" 
107100        """ 
108-         return  parse_version (f"{ current_version .major  +  1 }  )
101+         return  cls . version_from_string (f"{ current_version .major  +  1 }  )
109102
110-     def  next_dev_version (self , current_version : Version ) ->  Version :
103+     @classmethod  
104+     def  next_minor_version (cls , current_version : Version ) ->  Version :
111105        """ 
112-         Get the next development  version from a valid version 
106+         Get the next minor  version from a valid version 
113107
114108        Examples: 
115-             "1.2.3" will return "1.2.4.dev1" 
116-             "1.2.3.dev1" will return "1.2.3.dev2" 
109+             "1.2.3" will return "1.3.0" 
110+             "1.2.3.dev1" will return "1.3.0" 
111+             "1.2.3-alpha1" will return "1.3.0" 
117112        """ 
118-         if  current_version .is_devrelease :
119-             release_version  =  parse_version (
120-                 f"{ current_version .major }  
121-                 f"{ current_version .minor }  
122-                 f"{ current_version .micro  } { current_version .dev  +  1 }  
123-             )
124-         elif  current_version .is_prerelease :
125-             release_version  =  parse_version (
126-                 f"{ current_version .major }  
127-                 f"{ current_version .minor }  
128-                 f"{ current_version .micro  } { current_version .pre [0 ]}  
129-                 f"{ current_version .pre [1 ]}  
130-             )
131-         else :
132-             release_version  =  parse_version (
133-                 f"{ current_version .major }  
134-                 f"{ current_version .minor }  
135-                 f"{ current_version .micro  +  1  }  
136-             )
137- 
138-         return  release_version 
113+         return  cls .version_from_string (
114+             f"{ current_version .major } { current_version .minor  +  1 }  
115+         )
139116
140-     def  next_alpha_version (self , current_version : Version ) ->  Version :
117+     @classmethod  
118+     def  next_patch_version (cls , current_version : Version ) ->  Version :
141119        """ 
142-         Get the next alpha  version from a valid version 
120+         Get the next patch  version from a valid version 
143121
144122        Examples: 
145-             "1.2.3" will return "1.2.4a1" 
146-             "1.2.3.dev1" will return "1.2.3a1" 
123+             "1.2.3" will return "1.2.4" 
124+             "1.2.3.dev1" will return "1.2.4" 
125+             "1.2.3-alpha1" will return "1.2.4" 
147126        """ 
148-         if  current_version .is_devrelease :
149-             release_version  =  parse_version (
127+         if  current_version .is_pre_release :
128+             next_version  =  cls . version_from_string (
150129                f"{ current_version .major }  
151130                f"{ current_version .minor }  
152-                 f"{ current_version .micro  }  
153-             )
154-         elif  current_version .is_prerelease  and  current_version .pre [0 ] ==  "a" :
155-             release_version  =  parse_version (
156-                 f"{ current_version .major }  
157-                 f"{ current_version .minor }  
158-                 f"{ current_version .micro  } { current_version .pre [1 ] +  1 }  
131+                 f"{ current_version .patch }  
159132            )
160133        else :
161-             release_version  =  parse_version (
134+             next_version  =  cls . version_from_string (
162135                f"{ current_version .major }  
163136                f"{ current_version .minor }  
164-                 f"{ current_version .micro  +  1   } a1 " 
137+                 f"{ current_version .patch  +  1 }  
165138            )
166139
167-         return  release_version 
140+         return  next_version 
168141
169-     def  next_beta_version (self , current_version : Version ) ->  Version :
142+     @staticmethod  
143+     @abstractmethod  
144+     def  next_dev_version (current_version : Version ) ->  Version :
170145        """ 
171-         Get the next alpha version from a valid version 
172- 
173-         Examples: 
174-             "1.2.3" will return "1.2.4b1" 
175-             "1.2.3.dev1" will return "1.2.3b1" 
146+         Get the next development version from a valid version 
176147        """ 
177-         if  current_version .is_devrelease  or  (
178-             current_version .is_prerelease  and  current_version .pre [0 ] ==  "a" 
179-         ):
180-             release_version  =  parse_version (
181-                 f"{ current_version .major }  
182-                 f"{ current_version .minor }  
183-                 f"{ current_version .micro  }  
184-             )
185-         elif  current_version .is_prerelease  and  current_version .pre [0 ] ==  "b" :
186-             release_version  =  parse_version (
187-                 f"{ current_version .major }  
188-                 f"{ current_version .minor }  
189-                 f"{ current_version .micro  } { current_version .pre [1 ] +  1 }  
190-             )
191-         else :
192-             release_version  =  parse_version (
193-                 f"{ current_version .major }  
194-                 f"{ current_version .minor }  
195-                 f"{ current_version .micro  +  1  }  
196-             )
197- 
198-         return  release_version 
199148
200-     def   next_release_candidate_version ( 
201-          self ,  current_version :  Version 
202-     ) ->  Version :
149+     @ staticmethod 
150+     @ abstractmethod 
151+     def   next_alpha_version ( current_version :  Version ) ->  Version :
203152        """ 
204153        Get the next alpha version from a valid version 
154+         """ 
205155
206-         Examples: 
207-             "1.2.3" will return "1.2.4rc1" 
208-             "1.2.3.dev1" will return "1.2.3rc1" 
156+     @staticmethod  
157+     @abstractmethod  
158+     def  next_beta_version (current_version : Version ) ->  Version :
159+         """ 
160+         Get the next beta version from a valid version 
209161        """ 
210-         if  current_version .is_devrelease  or  (
211-             current_version .is_prerelease  and  current_version .pre [0 ] !=  "rc" 
212-         ):
213-             release_version  =  parse_version (
214-                 f"{ current_version .major }  
215-                 f"{ current_version .minor }  
216-                 f"{ current_version .micro  }  
217-             )
218-         elif  current_version .is_prerelease  and  current_version .pre [0 ] ==  "rc" :
219-             release_version  =  parse_version (
220-                 f"{ current_version .major }  
221-                 f"{ current_version .minor }  
222-                 f"{ current_version .micro  } { current_version .pre [1 ] +  1 }  
223-             )
224-         else :
225-             release_version  =  parse_version (
226-                 f"{ current_version .major }  
227-                 f"{ current_version .minor }  
228-                 f"{ current_version .micro  +  1  }  
229-             )
230162
231-         return  release_version 
163+     @staticmethod  
164+     @abstractmethod  
165+     def  next_release_candidate_version (current_version : Version ) ->  Version :
166+         """ 
167+         Get the next release candidate version from a valid version 
168+         """ 
0 commit comments