 45978435e7
			
		
	
	
		45978435e7
		
			
		
	
	
	
	
		
			
			- Previously I thought that comments were fine to discourage people from wasting their time trying to bump things that used `undef` that Sorbet didn't support. But RuboCop is better at this since it'll complain if the comments are unnecessary. - Suggested in https://github.com/Homebrew/brew/pull/18018#issuecomment-2283369501. - I've gone for a mixture of `rubocop:disable` for the files that can't be `typed: strict` (use of undef, required before everything else, etc) and `rubocop:todo` for everything else that should be tried to make strictly typed. There's no functional difference between the two as `rubocop:todo` is `rubocop:disable` with a different name. - And I entirely disabled the cop for the docs/ directory since `typed: strict` isn't going to gain us anything for some Markdown linting config files. - This means that now it's easier to track what needs to be done rather than relying on checklists of files in our big Sorbet issue: ```shell $ git grep 'typed: true # rubocop:todo Sorbet/StrictSigil' | wc -l 268 ``` - And this is confirmed working for new files: ```shell $ git status On branch use-rubocop-for-sorbet-strict-sigils Untracked files: (use "git add <file>..." to include in what will be committed) Library/Homebrew/bad.rb Library/Homebrew/good.rb nothing added to commit but untracked files present (use "git add" to track) $ brew style Offenses: bad.rb:1:1: C: Sorbet/StrictSigil: Sorbet sigil should be at least strict got true. ^^^^^^^^^^^^^ 1340 files inspected, 1 offense detected ```
		
			
				
	
	
		
			178 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # typed: true # rubocop:disable Sorbet/StrictSigil
 | |
| # frozen_string_literal: true
 | |
| 
 | |
| require "macho"
 | |
| 
 | |
| module Hardware
 | |
|   class CPU
 | |
|     class << self
 | |
|       undef type, family, features, sse4?
 | |
| 
 | |
|       # These methods use info spewed out by sysctl.
 | |
|       # Look in <mach/machine.h> for decoding info.
 | |
|       def type
 | |
|         case sysctl_int("hw.cputype")
 | |
|         when MachO::Headers::CPU_TYPE_I386
 | |
|           :intel
 | |
|         when MachO::Headers::CPU_TYPE_ARM64
 | |
|           :arm
 | |
|         else
 | |
|           :dunno
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def family
 | |
|         if arm?
 | |
|           arm_family
 | |
|         elsif intel?
 | |
|           intel_family
 | |
|         else
 | |
|           :dunno
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       # True when running under an Intel-based shell via Rosetta 2 on an
 | |
|       # Apple Silicon Mac. This can be detected via seeing if there's a
 | |
|       # conflict between what `uname` reports and the underlying `sysctl` flags,
 | |
|       # since the `sysctl` flags don't change behaviour under Rosetta 2.
 | |
|       def in_rosetta2?
 | |
|         sysctl_bool("sysctl.proc_translated")
 | |
|       end
 | |
| 
 | |
|       def features
 | |
|         @features ||= sysctl_n(
 | |
|           "machdep.cpu.features",
 | |
|           "machdep.cpu.extfeatures",
 | |
|           "machdep.cpu.leaf7_features",
 | |
|         ).split.map { |s| s.downcase.to_sym }
 | |
|       end
 | |
| 
 | |
|       def sse4?
 | |
|         sysctl_bool("hw.optional.sse4_1")
 | |
|       end
 | |
| 
 | |
|       def extmodel
 | |
|         sysctl_int("machdep.cpu.extmodel")
 | |
|       end
 | |
| 
 | |
|       def aes?
 | |
|         sysctl_bool("hw.optional.aes")
 | |
|       end
 | |
| 
 | |
|       def altivec?
 | |
|         sysctl_bool("hw.optional.altivec")
 | |
|       end
 | |
| 
 | |
|       def avx?
 | |
|         sysctl_bool("hw.optional.avx1_0")
 | |
|       end
 | |
| 
 | |
|       def avx2?
 | |
|         sysctl_bool("hw.optional.avx2_0")
 | |
|       end
 | |
| 
 | |
|       def sse3?
 | |
|         sysctl_bool("hw.optional.sse3")
 | |
|       end
 | |
| 
 | |
|       def ssse3?
 | |
|         sysctl_bool("hw.optional.supplementalsse3")
 | |
|       end
 | |
| 
 | |
|       def sse4_2?
 | |
|         sysctl_bool("hw.optional.sse4_2")
 | |
|       end
 | |
| 
 | |
|       # NOTE: This is more reliable than checking `uname`. `sysctl` returns
 | |
|       #       the right answer even when running in Rosetta 2.
 | |
|       def physical_cpu_arm64?
 | |
|         sysctl_bool("hw.optional.arm64")
 | |
|       end
 | |
| 
 | |
|       def virtualized?
 | |
|         sysctl_bool("kern.hv_vmm_present")
 | |
|       end
 | |
| 
 | |
|       private
 | |
| 
 | |
|       def arm_family
 | |
|         case sysctl_int("hw.cpufamily")
 | |
|         when 0x2c91a47e             # ARMv8.0-A (Typhoon)
 | |
|           :arm_typhoon
 | |
|         when 0x92fb37c8             # ARMv8.0-A (Twister)
 | |
|           :arm_twister
 | |
|         when 0x67ceee93             # ARMv8.1-A (Hurricane, Zephyr)
 | |
|           :arm_hurricane_zephyr
 | |
|         when 0xe81e7ef6             # ARMv8.2-A (Monsoon, Mistral)
 | |
|           :arm_monsoon_mistral
 | |
|         when 0x07d34b9f             # ARMv8.3-A (Vortex, Tempest)
 | |
|           :arm_vortex_tempest
 | |
|         when 0x462504d2             # ARMv8.4-A (Lightning, Thunder)
 | |
|           :arm_lightning_thunder
 | |
|         when 0x573b5eec, 0x1b588bb3 # ARMv8.4-A (Firestorm, Icestorm)
 | |
|           :arm_firestorm_icestorm
 | |
|         when 0xda33d83d             # ARMv8.5-A (Blizzard, Avalanche)
 | |
|           :arm_blizzard_avalanche
 | |
|         when 0xfa33415e             # ARMv8.6-A (M3, Ibiza)
 | |
|           :arm_ibiza
 | |
|         when 0x5f4dea93             # ARMv8.6-A (M3 Pro, Lobos)
 | |
|           :arm_lobos
 | |
|         when 0x72015832             # ARMv8.6-A (M3 Max, Palma)
 | |
|           :arm_palma
 | |
|         else
 | |
|           # When adding new ARM CPU families, please also update
 | |
|           # test/hardware/cpu_spec.rb to include the new families.
 | |
|           :dunno
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def intel_family(_family = nil, _cpu_model = nil)
 | |
|         case sysctl_int("hw.cpufamily")
 | |
|         when 0x73d67300 # Yonah: Core Solo/Duo
 | |
|           :core
 | |
|         when 0x426f69ef # Merom: Core 2 Duo
 | |
|           :core2
 | |
|         when 0x78ea4fbc # Penryn
 | |
|           :penryn
 | |
|         when 0x6b5a4cd2 # Nehalem
 | |
|           :nehalem
 | |
|         when 0x573b5eec # Westmere
 | |
|           :westmere
 | |
|         when 0x5490b78c # Sandy Bridge
 | |
|           :sandybridge
 | |
|         when 0x1f65e835 # Ivy Bridge
 | |
|           :ivybridge
 | |
|         when 0x10b282dc # Haswell
 | |
|           :haswell
 | |
|         when 0x582ed09c # Broadwell
 | |
|           :broadwell
 | |
|         when 0x37fc219f # Skylake
 | |
|           :skylake
 | |
|         when 0x0f817246 # Kaby Lake
 | |
|           :kabylake
 | |
|         when 0x38435547 # Ice Lake
 | |
|           :icelake
 | |
|         when 0x1cf8a03e # Comet Lake
 | |
|           :cometlake
 | |
|         else
 | |
|           :dunno
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def sysctl_bool(key)
 | |
|         sysctl_int(key) == 1
 | |
|       end
 | |
| 
 | |
|       def sysctl_int(key)
 | |
|         sysctl_n(key).to_i & 0xffffffff
 | |
|       end
 | |
| 
 | |
|       def sysctl_n(*keys)
 | |
|         (@properties ||= {}).fetch(keys) do
 | |
|           @properties[keys] = Utils.popen_read("/usr/sbin/sysctl", "-n", *keys)
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 |