Skip to content

Instantly share code, notes, and snippets.

@Kila2
Last active November 4, 2023 03:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kila2/bcf2847473f81a773aa543c0234c8a41 to your computer and use it in GitHub Desktop.
Save Kila2/bcf2847473f81a773aa543c0234c8a41 to your computer and use it in GitHub Desktop.
hashStringForPath
#python2
import struct
import hashlib
def hashStringForPath(path):
"""
Returns the hash for a project's DerivedData location.
path is the filesystem path to the .xcodeproj file.
"""
hash_context = hashlib.md5();
hash_context.update(path);
md5_digest_hex = hash_context.digest();
hash_path = [None] * 28;
first_value = struct.unpack('>Q', md5_digest_hex[:8])[0];
counter = 13;
while counter >= 0:
hash_path[counter] = chr((first_value % 26) + ord('a'));
first_value = first_value / 26;
counter -= 1;
second_value = struct.unpack('>Q', md5_digest_hex[8:])[0];
counter = 27;
while counter > 13:
hash_path[counter] = chr((second_value % 26) + ord('a'));
second_value = second_value / 26;
counter -= 1;
hash_path = ''.join(hash_path);
return hash_path;
import struct
import hashlib
def hashStringForPath(path):
"""
Returns the hash for a project's DerivedData location.
path is the filesystem path to the .xcodeproj file.
"""
hash_context = hashlib.md5()
hash_context.update(path)
md5_digest_hex = hash_context.digest()
hash_path = [None] * 28
first_value = struct.unpack('>Q', md5_digest_hex[:8])[0]
counter = 13
while counter >= 0:
hash_path[counter] = chr((first_value % 26) + ord('a'))
first_value = first_value // 26
counter -= 1
second_value = struct.unpack('>Q', md5_digest_hex[8:])[0]
counter = 27
while counter > 13:
hash_path[counter] = chr((second_value % 26) + ord('a'))
second_value = second_value // 26
counter -= 1
hash_path = ''.join(hash_path)
return hash_path
get_derived_path="require 'digest';
require 'json';
def get_uuid(path)
digest = Digest::MD5.hexdigest path;
lenght = path.length;
index = 13;
resultStr = Array.new(28);
digest = [digest].pack('H*');
startValue = digest[0...8].unpack('Q>')[0];
(resultStr[index] = (startValue % 26 + 'a'.ord).chr; startValue /= 26; index -= 1;) while index >= 0;
index = 27;
startValue = digest[8...16].unpack('Q>')[0];
(resultStr[index] = (startValue % 26 + 'a'.ord).chr; startValue /= 26; index -= 1;) while index > 13;
resultStr.join();
end;
def get_derived_path(workspace_path)
user_name = \`whoami\`[0...-1];
workspace_name = File.basename(workspace_path, '.xcworkspace');
xcsettingPath = \"#{workspace_path}/xcuserdata/#{user_name}.xcuserdatad/WorkspaceSettings.xcsettings\";
location = File.expand_path('~/Library/Developer/Xcode/DerivedData');
xcode_location=\`defaults read com.apple.dt.Xcode IDECustomDerivedDataLocation 2>/dev/null\`.strip;
unique_dir = \"#{workspace_name}-#{get_uuid(workspace_path)}\";
if \$?.exitstatus == 0;
Dir.chdir(\"#{workspace_path}/..\") do;
real_xcode_location = File.expand_path(xcode_location);
location = real_xcode_location;
if real_xcode_location == xcode_location;
else;
unique_dir = workspace_name.to_s;
end;
end;
end;
if File.exist?(xcsettingPath);
xcsetting = JSON.parse(\`plutil -convert json -r -o - #{xcsettingPath}\`);
if xcsetting['DerivedDataLocationStyle'] == 'AbsolutePath';
location = xcsetting['DerivedDataCustomLocation'];
unique_dir = \"#{workspace_name}-#{get_uuid(workspace_path)}\";
elsif xcsetting['DerivedDataLocationStyle'] == 'WorkspaceRelativePath';
Dir.chdir(\"#{workspace_path}/..\") do;
location = File.expand_path(xcsetting['DerivedDataCustomLocation']);
end;
unique_dir = workspace_name.to_s;
end;
end;
\"#{location}/#{unique_dir}\";
end;
puts get_derived_path(ENV['WORKSPACE_PATH']);"
echo `echo $get_derived_path |ruby`
def get_derived_path(workspace_path):
user_name = os.getenv("USER")
xcsettingPath = "%s/xcuserdata/%s.xcuserdatad/WorkspaceSettings.xcsettings" % (workspace_path, user_name)
# Default
location = "%s/Library/Developer/Xcode/DerivedData" % (os.path.expanduser("~"))
workspace_name = os.path.splitext(os.path.basename(workspace_path))[0]
code, xcode_location = GetCmdStatusAndOutput("defaults read com.apple.dt.Xcode IDECustomDerivedDataLocation 2>/dev/null", shell=True)
xcode_location = xcode_location.rstrip().decode("utf-8")
unique_dir = "%s-%s" % (workspace_name, hashStringForPath(workspace_path))
if code == 0:
owd = os.getcwd()
try:
os.chdir(os.path.join(workspace_path,".."))
real_xcode_location = os.path.realpath(os.path.expanduser(xcode_location))
location = real_xcode_location
if real_xcode_location == xcode_location:
#custom
pass
else:
#relative
unique_dir = workspace_name
finally:
os.chdir(owd)
if os.path.exists(xcsettingPath):
json_str = GetCmdOutput("plutil -convert json -r -o - \"%s\"" % (xcsettingPath), shell=True).rstrip().decode("utf-8")
xcsetting = json.loads(json_str)
if xcsetting['DerivedDataLocationStyle'] == 'AbsolutePath':
location = xcsetting['DerivedDataCustomLocation']
unique_dir = "%s-%s" % (workspace_name, hashStringForPath(workspace_path))
elif xcsetting['DerivedDataLocationStyle'] == 'WorkspaceRelativePath':
owd = os.getcwd()
try:
os.chdir(os.path.join(workspace_path,".."))
location = os.path.realpath(os.path.expanduser(xcsetting['DerivedDataCustomLocation']))
finally:
os.chdir(owd)
unique_dir = workspace_name
return "%s/%s" % (location, unique_dir)
#include <CommonCrypto/CommonDigest.h>
// this function is used to swap byte ordering of a 64bit integer
uint64_t swap_uint64(uint64_t val) {
val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL );
val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL );
return (val << 32) | (val >> 32);
}
std::shared_ptr<std::string> hashStringForPath(const char *path){
// using uint64_t[2] for ease of use, since it is the same size as char[CC_MD5_DIGEST_LENGTH]
uint64_t digest[CC_MD2_DIGEST_LENGTH] = {0};
// char array that will contain the identifier
unsigned char resultStr[29] = {0};
// setup md5 context
CC_MD5_CTX md5;
CC_MD5_Init(&md5);
// get length of the path string
unsigned long length = strlen(path);
// update the md5 context with the full path string
CC_MD5_Update (&md5, path, (CC_LONG)length);
// finalize working with the md5 context and store into the digest
CC_MD5_Final ( (unsigned char *)digest, &md5);
// take the first 8 bytes of the digest and swap byte order
uint64_t startValue = swap_uint64(digest[0]);
// for indexes 13->0
int index = 13;
do {
// take 'startValue' mod 26 (restrict to alphabetic) and add based 'a'
resultStr[index] = (char)((startValue % 26) + 'a');
// divide 'startValue' by 26
startValue /= 26;
index--;
} while (index >= 0);
// The second loop, this time using the last 8 bytes
// repeating the same process as before but over indexes 27->14
startValue = swap_uint64(digest[1]);
index = 27;
do {
resultStr[index] = (char)((startValue % 26) + 'a');
startValue /= 26;
index--;
} while (index > 13);
return std::make_shared<std::string>((char *)resultStr);
}
def get_derived_path
user_name = `whoami`[0...-1]
xcsettingPath = "#{@workspace_path}/xcuserdata/#{user_name}.xcuserdatad/WorkspaceSettings.xcsettings"
# Default
location = File.expand_path('~/Library/Developer/Xcode/DerivedData')
xcode_location=`defaults read com.apple.dt.Xcode IDECustomDerivedDataLocation 2>/dev/null`.strip
unique_dir = "#{@workspace_name}-#{get_uuid(@workspace_path)}"
if $?.exitstatus == 0
Dir.chdir("#{@workspace_path}/..") do
real_xcode_location = File.expand_path(xcode_location)
location = real_xcode_location
if real_xcode_location == xcode_location
#custom
else
#relative
unique_dir = @workspace_name.to_s
end
end
end
if File.exist?(xcsettingPath)
xcsetting = Xcodeproj::Plist.read_from_path(xcsettingPath)
if xcsetting['DerivedDataLocationStyle'] == 'AbsolutePath'
location = xcsetting['DerivedDataCustomLocation']
unique_dir = "#{@workspace_name}-#{get_uuid(@workspace_path)}"
elsif xcsetting['DerivedDataLocationStyle'] == 'WorkspaceRelativePath'
Dir.chdir("#{@workspace_path}/..") do
location = File.expand_path(xcsetting['DerivedDataCustomLocation'])
end
unique_dir = @workspace_name.to_s
end
end
"#{location}/#{unique_dir}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment