1import os, sys 2from waflib import Utils, Context 3import samba_utils 4from samba_git import find_git 5 6def git_version_summary(path, env=None): 7 git = find_git(env) 8 9 if git is None: 10 return ("GIT-UNKNOWN", {}) 11 12 env.GIT = git 13 14 environ = dict(os.environ) 15 environ["GIT_DIR"] = '%s/.git' % path 16 environ["GIT_WORK_TREE"] = path 17 git = samba_utils.get_string(Utils.cmd_output(env.GIT + ' show --pretty=format:"%h%n%ct%n%H%n%cd" --stat HEAD', silent=True, env=environ)) 18 19 lines = git.splitlines() 20 if not lines or len(lines) < 4: 21 return ("GIT-UNKNOWN", {}) 22 23 fields = { 24 "GIT_COMMIT_ABBREV": lines[0], 25 "GIT_COMMIT_FULLREV": lines[2], 26 "COMMIT_TIME": int(lines[1]), 27 "COMMIT_DATE": lines[3], 28 } 29 30 ret = "GIT-" + fields["GIT_COMMIT_ABBREV"] 31 32 if env.GIT_LOCAL_CHANGES: 33 clean = Utils.cmd_output('%s diff HEAD | wc -l' % env.GIT, silent=True).strip() 34 if clean == "0": 35 fields["COMMIT_IS_CLEAN"] = 1 36 else: 37 fields["COMMIT_IS_CLEAN"] = 0 38 ret += "+" 39 40 return (ret, fields) 41 42 43def distversion_version_summary(path): 44 #get version from .distversion file 45 suffix = None 46 fields = {} 47 48 for line in Utils.readf(path + '/.distversion').splitlines(): 49 if line == '': 50 continue 51 if line.startswith("#"): 52 continue 53 try: 54 split_line = line.split("=") 55 if split_line[1] != "": 56 key = split_line[0] 57 value = split_line[1] 58 if key == "SUFFIX": 59 suffix = value 60 continue 61 fields[key] = value 62 except: 63 print("Failed to parse line %s from .distversion file." % (line)) 64 raise 65 66 if "COMMIT_TIME" in fields: 67 fields["COMMIT_TIME"] = int(fields["COMMIT_TIME"]) 68 69 if suffix is None: 70 return ("UNKNOWN", fields) 71 72 return (suffix, fields) 73 74 75class SambaVersion(object): 76 77 def __init__(self, version_dict, path, env=None, is_install=True): 78 '''Determine the version number of samba 79 80See VERSION for the format. Entries on that file are 81also accepted as dictionary entries here 82 ''' 83 84 self.MAJOR=None 85 self.MINOR=None 86 self.RELEASE=None 87 self.REVISION=None 88 self.TP_RELEASE=None 89 self.ALPHA_RELEASE=None 90 self.BETA_RELEASE=None 91 self.PRE_RELEASE=None 92 self.RC_RELEASE=None 93 self.IS_SNAPSHOT=True 94 self.RELEASE_NICKNAME=None 95 self.VENDOR_SUFFIX=None 96 self.VENDOR_PATCH=None 97 98 for a, b in version_dict.items(): 99 if a.startswith("SAMBA_VERSION_"): 100 setattr(self, a[14:], b) 101 else: 102 setattr(self, a, b) 103 104 if self.IS_GIT_SNAPSHOT == "yes": 105 self.IS_SNAPSHOT=True 106 elif self.IS_GIT_SNAPSHOT == "no": 107 self.IS_SNAPSHOT=False 108 else: 109 raise Exception("Unknown value for IS_GIT_SNAPSHOT: %s" % self.IS_GIT_SNAPSHOT) 110 111 ## 112 ## start with "3.0.22" 113 ## 114 self.MAJOR=int(self.MAJOR) 115 self.MINOR=int(self.MINOR) 116 self.RELEASE=int(self.RELEASE) 117 118 SAMBA_VERSION_STRING = ("%u.%u.%u" % (self.MAJOR, self.MINOR, self.RELEASE)) 119 120## 121## maybe add "3.0.22a" or "4.0.0tp11" or "4.0.0alpha1" or "4.0.0beta1" or "3.0.22pre1" or "3.0.22rc1" 122## We do not do pre or rc version on patch/letter releases 123## 124 if self.REVISION is not None: 125 SAMBA_VERSION_STRING += self.REVISION 126 if self.TP_RELEASE is not None: 127 self.TP_RELEASE = int(self.TP_RELEASE) 128 SAMBA_VERSION_STRING += "tp%u" % self.TP_RELEASE 129 if self.ALPHA_RELEASE is not None: 130 self.ALPHA_RELEASE = int(self.ALPHA_RELEASE) 131 SAMBA_VERSION_STRING += ("alpha%u" % self.ALPHA_RELEASE) 132 if self.BETA_RELEASE is not None: 133 self.BETA_RELEASE = int(self.BETA_RELEASE) 134 SAMBA_VERSION_STRING += ("beta%u" % self.BETA_RELEASE) 135 if self.PRE_RELEASE is not None: 136 self.PRE_RELEASE = int(self.PRE_RELEASE) 137 SAMBA_VERSION_STRING += ("pre%u" % self.PRE_RELEASE) 138 if self.RC_RELEASE is not None: 139 self.RC_RELEASE = int(self.RC_RELEASE) 140 SAMBA_VERSION_STRING += ("rc%u" % self.RC_RELEASE) 141 142 if self.IS_SNAPSHOT: 143 if not is_install: 144 suffix = "DEVELOPERBUILD" 145 self.vcs_fields = {} 146 elif os.path.exists(os.path.join(path, ".git")): 147 suffix, self.vcs_fields = git_version_summary(path, env=env) 148 elif os.path.exists(os.path.join(path, ".distversion")): 149 suffix, self.vcs_fields = distversion_version_summary(path) 150 else: 151 suffix = "UNKNOWN" 152 self.vcs_fields = {} 153 self.vcs_fields["SUFFIX"] = suffix 154 SAMBA_VERSION_STRING += "-" + suffix 155 else: 156 self.vcs_fields = {} 157 158 self.OFFICIAL_STRING = SAMBA_VERSION_STRING 159 160 if self.VENDOR_SUFFIX is not None: 161 SAMBA_VERSION_STRING += ("-" + self.VENDOR_SUFFIX) 162 self.VENDOR_SUFFIX = self.VENDOR_SUFFIX 163 164 if self.VENDOR_PATCH is not None: 165 SAMBA_VERSION_STRING += ("-" + self.VENDOR_PATCH) 166 self.VENDOR_PATCH = self.VENDOR_PATCH 167 168 self.STRING = SAMBA_VERSION_STRING 169 170 if self.RELEASE_NICKNAME is not None: 171 self.STRING_WITH_NICKNAME = "%s (%s)" % (self.STRING, self.RELEASE_NICKNAME) 172 else: 173 self.STRING_WITH_NICKNAME = self.STRING 174 175 def __str__(self): 176 string="/* Autogenerated by waf */\n" 177 string+="#define SAMBA_VERSION_MAJOR %u\n" % self.MAJOR 178 string+="#define SAMBA_VERSION_MINOR %u\n" % self.MINOR 179 string+="#define SAMBA_VERSION_RELEASE %u\n" % self.RELEASE 180 if self.REVISION is not None: 181 string+="#define SAMBA_VERSION_REVISION %u\n" % self.REVISION 182 183 if self.TP_RELEASE is not None: 184 string+="#define SAMBA_VERSION_TP_RELEASE %u\n" % self.TP_RELEASE 185 186 if self.ALPHA_RELEASE is not None: 187 string+="#define SAMBA_VERSION_ALPHA_RELEASE %u\n" % self.ALPHA_RELEASE 188 189 if self.BETA_RELEASE is not None: 190 string+="#define SAMBA_VERSION_BETA_RELEASE %u\n" % self.BETA_RELEASE 191 192 if self.PRE_RELEASE is not None: 193 string+="#define SAMBA_VERSION_PRE_RELEASE %u\n" % self.PRE_RELEASE 194 195 if self.RC_RELEASE is not None: 196 string+="#define SAMBA_VERSION_RC_RELEASE %u\n" % self.RC_RELEASE 197 198 for name in sorted(self.vcs_fields.keys()): 199 string+="#define SAMBA_VERSION_%s " % name 200 value = self.vcs_fields[name] 201 string_types = str 202 if sys.version_info[0] < 3: 203 string_types = basestring 204 if isinstance(value, string_types): 205 string += "\"%s\"" % value 206 elif type(value) is int: 207 string += "%d" % value 208 else: 209 raise Exception("Unknown type for %s: %r" % (name, value)) 210 string += "\n" 211 212 string+="#define SAMBA_VERSION_OFFICIAL_STRING \"" + self.OFFICIAL_STRING + "\"\n" 213 214 if self.VENDOR_SUFFIX is not None: 215 string+="#define SAMBA_VERSION_VENDOR_SUFFIX " + self.VENDOR_SUFFIX + "\n" 216 if self.VENDOR_PATCH is not None: 217 string+="#define SAMBA_VERSION_VENDOR_PATCH " + self.VENDOR_PATCH + "\n" 218 219 if self.RELEASE_NICKNAME is not None: 220 string+="#define SAMBA_VERSION_RELEASE_NICKNAME " + self.RELEASE_NICKNAME + "\n" 221 222 # We need to put this #ifdef in to the headers so that vendors can override the version with a function 223 string+=''' 224#ifdef SAMBA_VERSION_VENDOR_FUNCTION 225# define SAMBA_VERSION_STRING SAMBA_VERSION_VENDOR_FUNCTION 226#else /* SAMBA_VERSION_VENDOR_FUNCTION */ 227# define SAMBA_VERSION_STRING "''' + self.STRING_WITH_NICKNAME + '''" 228#endif 229''' 230 string+="/* Version for mkrelease.sh: \nSAMBA_VERSION_STRING=" + self.STRING_WITH_NICKNAME + "\n */\n" 231 232 return string 233 234 235def samba_version_file(version_file, path, env=None, is_install=True): 236 '''Parse the version information from a VERSION file''' 237 238 f = open(version_file, 'r') 239 version_dict = {} 240 for line in f: 241 line = line.strip() 242 if line == '': 243 continue 244 if line.startswith("#"): 245 continue 246 try: 247 split_line = line.split("=") 248 if split_line[1] != "": 249 value = split_line[1].strip('"') 250 version_dict[split_line[0]] = value 251 except: 252 print("Failed to parse line %s from %s" % (line, version_file)) 253 raise 254 255 return SambaVersion(version_dict, path, env=env, is_install=is_install) 256 257 258 259def load_version(env=None, is_install=True): 260 '''load samba versions either from ./VERSION or git 261 return a version object for detailed breakdown''' 262 if not env: 263 env = samba_utils.LOAD_ENVIRONMENT() 264 265 version = samba_version_file("./VERSION", ".", env, is_install=is_install) 266 Context.g_module.VERSION = version.STRING 267 return version 268