Skip to content

Instantly share code, notes, and snippets.

@mrmiller
Last active April 19, 2020 08:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrmiller/875f9b4890c9f52928187468f03ada9d to your computer and use it in GitHub Desktop.
Save mrmiller/875f9b4890c9f52928187468f03ada9d to your computer and use it in GitHub Desktop.
git ❤️ FMOD
#
# To use, place this in ~/.zsh (or ~/.bash if you're using bash; untested)
# fmodlookup.pl should also be placed in ~/ or you can place it somewhere else
# and update the path below.
#
function git() {
command git -c color.status=always -c color.ui=always "$@" | ~/fmodlookup.pl | less -FRX
}
#!/usr/bin/perl
#
# Script to add FMOD's path names to Metadata filesystem paths. It looks for
# any text that resembles the path an FMOD metadata resource. It then parses
# the metadata to find its name and walks through its parent folders doing the
# same. Once it's gathered the full path, it appends a parenthetical to the output.
#
# For example:
# % git status
# Changes not staged for commit:
# modified: Metadata/Event/{0be85c46-92bf-4ac7-8ce3-2076ea0d6dde}.xml (/Master/Cutscenes/England/After E1)
#
# To make sure this runs on every git command, you can create a shell function
# which always pipes the output of git through this script. See included example
# for zsh (macOS).
#
# Known issues:
# - paths may not display if executed outside the repository root.
#
use File::Find;
use File::Spec;
use Term::ANSIColor 2.01 qw(colorstrip);
my %guid_cache;
sub xpath{
my ($xpath, $path) = @_;
}
sub last_commit{
my ($path) = @_;
my $last_commit = qx(git rev-list --max-count=1 --all -- $path);
chomp($last_commit);
return $last_commit;
}
sub xpath{
my ($path, $xpath) = @_;
if (-f $path) {
return qx(xmllint --xpath "$xpath" $path 2>/dev/null);
} else {
my $last_commit = last_commit($path);
return qx(git show $last_commit^:$path | xmllint --xpath "$xpath" - 2>/dev/null);
}
}
my $XPATH_NAME = '/objects/object[1]/property[@name=\\"name\\"]/value[1]/text()';
my $XPATH_PARENT = '//relationship[@name=\\"folder\\"]/destination/text()';
my $XPATH_ASSET_PATH = '/objects/object[1]/property[@name=\\"assetPath\\"]/value[1]/text()';
sub path_to_name{
return xpath($_[0], $XPATH_NAME);
}
sub path_to_asset_path{
return xpath($_[0], $XPATH_ASSET_PATH);
}
sub path_to_parent_guid{
return xpath($_[0], $XPATH_PARENT);
}
sub find_first_file{
my ($regex, $root) = @_;
my $result = "";
find(
sub {
return unless -f;
if (/$regex/) {
$result = File::Spec->abs2rel($File::Find::name, $root);
}
},
$root
);
return $result;
}
sub _guid_path_to_fmod_path{
my ($guid_path, $root) = @_;
return "" if $guid_path eq "";
$path = $root . $guid_path;
my $name = path_to_name($path);
$name = path_to_asset_path($path) if $name eq"";
return "" if $name eq "";
my $parent_guid = path_to_parent_guid($path);
my $folder = find_first_file($parent_guid, $root);
return guid_path_to_fmod_path($folder, $root) . "/" . $name;
}
sub guid_path_to_fmod_path{
my ($guid_path, $root) = @_;
$fmod_path = $guid_cache{$guid_path};
unless ($fmod_path) {
$fmod_path = $guid_cache{$guid_path} = _guid_path_to_fmod_path($guid_path, $root);
}
return $fmod_path;
}
sub lookup_fmod_path{
my ($guid_path, $root) = @_;
$root =~ s[^(a|b)/][]; # remove git diff prefix if present
return guid_path_to_fmod_path($guid_path, $root);
}
while (<>) {
s[(\S*?Metadata/)(.*?\.xml)]["$1$2 (${\lookup_fmod_path(colorstrip($2), colorstrip($1))})" =~ s/\n$//r ]ge;
print "$_";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment