#!/usr/bin/env python3 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  dataclasses  import  dataclass 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  functools  import  cache 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  json 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  os 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  pathlib 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  subprocess 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . common . basedir  import  BASEDIR 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . common . swaglog  import  cloudlog 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . common . git  import  get_commit ,  get_origin ,  get_branch ,  get_short_branch ,  get_commit_date 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								RELEASE_BRANCHES  =  [ ' release-tizi-staging ' ,  ' release-tici ' ,  ' release-tizi ' ,  ' nightly ' ] 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TESTED_BRANCHES  =  RELEASE_BRANCHES  +  [ ' devel-staging ' ,  ' nightly-dev ' ] 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								BUILD_METADATA_FILENAME  =  " build.json " 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								training_version :  str  =  " 0.2.0 " 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								terms_version :  str  =  " 2 " 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  get_version ( path :  str  =  BASEDIR )  - >  str : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  with  open ( os . path . join ( path ,  " common " ,  " version.h " ) )  as  _versionf : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    version  =  _versionf . read ( ) . split ( ' " ' ) [ 1 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  version 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_release_notes ( path :  str  =  BASEDIR )  - >  str : 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  with  open ( os . path . join ( path ,  " RELEASES.md " ) )  as  f : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  f . read ( ) . split ( ' \n \n ' ,  1 ) [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@cache 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  is_prebuilt ( path :  str  =  BASEDIR )  - >  bool : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  os . path . exists ( os . path . join ( path ,  ' prebuilt ' ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								@cache 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  is_dirty ( cwd :  str  =  BASEDIR )  - >  bool : 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  not  get_origin ( )  or  not  get_short_branch ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  True 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  dirty  =  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  try : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # Actually check dirty files 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  not  is_prebuilt ( cwd ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      # This is needed otherwise touched files might show up as modified 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      try : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        subprocess . check_call ( [ " git " ,  " update-index " ,  " --refresh " ] ,  cwd = cwd ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      except  subprocess . CalledProcessError : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        pass 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      branch  =  get_branch ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  not  branch : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  True 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      dirty  =  ( subprocess . call ( [ " git " ,  " diff-index " ,  " --quiet " ,  branch ,  " -- " ] ,  cwd = cwd ) )  !=  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  except  subprocess . CalledProcessError : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    cloudlog . exception ( " git subprocess failed while checking dirty " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dirty  =  True 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  dirty 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								@dataclass 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  OpenpilotMetadata : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  version :  str 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  release_notes :  str 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  git_commit :  str 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  git_origin :  str 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  git_commit_date :  str 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  build_style :  str 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  is_dirty :  bool   # whether there are local changes 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  @property 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  short_version ( self )  - >  str : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  self . version . split ( ' - ' ) [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  @property 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  comma_remote ( self )  - >  bool : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # note to fork maintainers, this is used for release metrics. please do not 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # touch this to get rid of the orange startup alert. there's better ways to do that 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  self . git_normalized_origin  ==  " github.com/commaai/openpilot " 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  @property 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  git_normalized_origin ( self )  - >  str : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  self . git_origin  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      . replace ( " git@ " ,  " " ,  1 )  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      . replace ( " .git " ,  " " ,  1 )  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      . replace ( " https:// " ,  " " ,  1 )  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      . replace ( " : " ,  " / " ,  1 ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								@dataclass 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								class  BuildMetadata : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  channel :  str 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  openpilot :  OpenpilotMetadata 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  @property 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  tested_channel ( self )  - >  bool : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  self . channel  in  TESTED_BRANCHES 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  @property 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  release_channel ( self )  - >  bool : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  self . channel  in  RELEASE_BRANCHES 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  @property 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  canonical ( self )  - >  str : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  f " { self . openpilot . version } - { self . openpilot . git_commit } - { self . openpilot . build_style } " 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  @property 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  ui_description ( self )  - >  str : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  f " { self . openpilot . version }  /  { self . openpilot . git_commit [ : 6 ] }  /  { self . channel } " 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  build_metadata_from_dict ( build_metadata :  dict )  - >  BuildMetadata : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  channel  =  build_metadata . get ( " channel " ,  " unknown " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  openpilot_metadata  =  build_metadata . get ( " openpilot " ,  { } ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  version  =  openpilot_metadata . get ( " version " ,  " unknown " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  release_notes  =  openpilot_metadata . get ( " release_notes " ,  " unknown " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  git_commit  =  openpilot_metadata . get ( " git_commit " ,  " unknown " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  git_origin  =  openpilot_metadata . get ( " git_origin " ,  " unknown " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  git_commit_date  =  openpilot_metadata . get ( " git_commit_date " ,  " unknown " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  build_style  =  openpilot_metadata . get ( " build_style " ,  " unknown " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  BuildMetadata ( channel , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            OpenpilotMetadata ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              version = version , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              release_notes = release_notes , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              git_commit = git_commit , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              git_origin = git_origin , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              git_commit_date = git_commit_date , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								              build_style = build_style , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								              is_dirty = False ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  get_build_metadata ( path :  str  =  BASEDIR )  - >  BuildMetadata : 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  build_metadata_path  =  pathlib . Path ( path )  /  BUILD_METADATA_FILENAME 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  build_metadata_path . exists ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    build_metadata  =  json . loads ( build_metadata_path . read_text ( ) ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  build_metadata_from_dict ( build_metadata ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  git_folder  =  pathlib . Path ( path )  /  " .git " 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  git_folder . exists ( ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  BuildMetadata ( get_short_branch ( path ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    OpenpilotMetadata ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      version = get_version ( path ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      release_notes = get_release_notes ( path ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      git_commit = get_commit ( path ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      git_origin = get_origin ( path ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      git_commit_date = get_commit_date ( path ) , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								                      build_style = " unknown " , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								                      is_dirty = is_dirty ( path ) ) ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  cloudlog . exception ( " unable to get build metadata " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  raise  Exception ( " invalid build metadata " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  __name__  ==  " __main__ " : 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  from  openpilot . common . params  import  Params 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  params  =  Params ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  params . put ( " TermsVersion " ,  terms_version ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  params . put ( " TrainingVersion " ,  training_version ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  print ( get_build_metadata ( ) )