Skip to content

Instantly share code, notes, and snippets.

@allanon
Last active October 26, 2018 17:58
Show Gist options
  • Save allanon/38620af49d250005acbf to your computer and use it in GitHub Desktop.
Save allanon/38620af49d250005acbf to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
###############################################################################
# Automatically create a pull request containing official server changes,
# extracted from the server's patch files.
#
# WARNING: This script will DELETE all local modifications to the git clone
# it uses. Please use a git directory which is only for this script
# to avoid loss of any changes you might have made.
use strict;
use warnings;
use Getopt::Long;
use File::NFSLock;
my $configs = {
iro_renewal => {
branch => 'iro_update',
server => 'iRO Renewal',
allow_url => 'http://patch.1.online.ragnarok.warpportal.net/patch02/patch_allow.txt',
list_url => 'http://patch.1.online.ragnarok.warpportal.net/patch02/patch2.txt',
download_base_url => 'ftp://ropatch2.gravityus.com/patch',
git_root => "$ENV{HOME}/git/openkore-updates",
git_dir => "$ENV{HOME}/git/openkore-updates/tables/iRO/official",
download_dir => "$ENV{HOME}/patches/iRO",
},
iro_classic => {
branch => 'iro_update',
server => 'iRO Classic',
allow_url => 'http://patch.1.online.ragnarok.warpportal.net/cpatch02/patch_allow.txt',
list_url => 'http://patch.1.online.ragnarok.warpportal.net/cpatch02/cpatch.txt',
download_base_url => 'ftp://ropatch2.gravityus.com/cpatch',
git_root => "$ENV{HOME}/git/openkore-updates",
git_dir => "$ENV{HOME}/git/openkore-updates/tables/iRO/Classic/official",
download_dir => "$ENV{HOME}/patches/iRO/Classic",
},
iro_restart => {
branch => 'iro_update',
allow_url => 'http://patch.1.online.ragnarok.warpportal.net/repatch01/patch_allow.txt',
list_url => 'http://patch.1.online.ragnarok.warpportal.net/repatch01/repatch2.txt',
download_base_url => 'ftp://ropatch2.gravityus.com/repatch',
git_root => "$ENV{HOME}/git/openkore-updates",
git_dir => "$ENV{HOME}/git/openkore-updates/tables/iRO/Restart/official",
download_dir => "$ENV{HOME}/patches/iRO/Restart",
},
bro => {
branch => 'bro_update',
server => 'bRO',
allow_url => 'http://patch.1.online.ragnarok.warpportal.net/repatch01/patch_allow.txt', # TODO: What should this be?
list_url => 'ftp://fpatch.levelupgames.com.br/patch/patch3.txt',
download_base_url => 'ftp://fpatch.levelupgames.com.br/patch',
git_root => "$ENV{HOME}/git/openkore-updates",
git_dir => "$ENV{HOME}/git/openkore-updates/tables/bRO",
download_dir => "$ENV{HOME}/patches/bRO",
},
fro => {
branch => 'fro_update',
server => 'fRO',
allow_url => 'http://web.ragnarokonline.fr/patch01/patch_allow.txt',
list_url => 'http://web.ragnarokonline.fr/patch01/patch3.txt',
download_base_url => 'ftp://ftp.ragnarokonline.fr/patch01',
git_root => "$ENV{HOME}/git/openkore-updates",
git_dir => "$ENV{HOME}/git/openkore-updates/tables/fRO",
download_dir => "$ENV{HOME}/patches/fRO",
},
};
my $opt = get_options(
{
server => 'iro_renewal',
}, {
'force|f' => 'force download even if the allow-url says we are not allowed to',
'server|s=s' => "server config to use (available: @{[sort keys %$configs]})",
'skip_commit' => 'download updates, but do not commit changes to git',
'check_allow' => 'just check whether patching is allowed and exit',
}
);
my $config = $configs->{ $opt->{server} };
if ( $opt->{check_allow} && $config->{allow_url} ) {
my @cmd = (
'tools/patch.pl',
'--allow-url' => $config->{allow_url},
'--check-allow' => 1,
);
push @cmd, '--force' if $opt->{force};
$cmd[0] = "$ENV{HOME}/bin/patch.pl";
exec @cmd;
exit 1;
}
my $lock = setup_git_dir( $config->{git_root}, $config->{branch} );
# Make sure the target directory exists.
system "mkdir -p '$config->{git_dir}'" if !-d $config->{git_dir};
my @cmd = (
'tools/patch.pl',
'--git-dir' => $config->{git_dir},
'--allow-url' => $config->{allow_url},
'--list-url' => $config->{list_url},
'--download-base-url' => $config->{download_base_url},
'--download-dir' => $config->{download_dir}
);
push @cmd, '--force' if $opt->{force};
$cmd[0] = "$ENV{HOME}/bin/patch.pl";
system @cmd;
exit 1 if $?;
my $commit_message = "update $config->{server} files";
my $pullrq_message = "- [ ] QA Review\n\nThis pull request was auto-generated by patch_iro.pl: https://gist.github.com/allanon/38620af49d250005acbf";
commit( $config->{branch}, $commit_message, $pullrq_message ) if !$opt->{skip_commit};
sub setup_git_dir {
my ( $git_dir, $branch ) = @_;
my $lock = File::NFSLock->new( $git_dir, 'BLOCKING' );
if ( !-d $git_dir ) {
my $dirname = ( $git_dir =~ m{(.*)/} )[0];
system "mkdir -p '$dirname'" if $dirname;
system "git clone git\@github.com:OpenKore/openkore.git '$git_dir'";
if ( !-d $git_dir ) {
print "Updates directory is missing and cannot be created: $!\n";
exit;
}
}
chdir $git_dir;
# Make sure we start out on master.
system 'git checkout master';
# Remove all untracked files.
system 'git clean -d -f';
# Fetch the latest code from github.
system 'git fetch --all';
# Remove remote-tracking references that have been removed upstream. (Eg, the branch was merged and deleted.)
system 'git fetch --prune origin';
# Revert all locally modified files.
system 'git reset --hard origin/master';
my $remote_branches = [ map { s{^\s+|origin/|\s+$}{}gs;$_; } split /\n/, `git branch -r` ];
my $local_branches = [ map { s/^[\s*]+|\s+$//gs;$_; } split /\n/, `git branch` ];
# If we have a local branch, always delete it. We'll re-generate it anyway,
# and it's probably not in sync with the origin (if the origin has it too).
if ( grep { $_ eq $branch } @$local_branches ) {
system "git branch -D $branch";
}
my $remote_exists = grep { $_ eq $branch } @$remote_branches;
if ( $remote_exists ) {
system "git checkout $branch";
system "git clean -d -f";
system "git reset --hard origin/$branch";
}
$lock;
}
sub commit {
my ( $branch, $commit_message, $pullrq_message ) = @_;
my $out = `git ls-files -m`;
if ( !$out || $out =~ /^\s+$/s ) {
print "No changes!\n";
return;
}
my $remote_branches = [ map { s{^\s+|origin/|\s+$}{}gs;$_; } split /\n/, `git branch -r` ];
my $remote_exists = grep { $_ eq $branch } @$remote_branches;
system "git checkout -b $branch" if !$remote_exists;
system "git commit -a -m '$commit_message'";
system "git push -u origin $branch";
# This will fail if there's already an open pull for this branch. And that is good.
system "hub pull-request -b master -h $branch -m '$commit_message\n\n$pullrq_message'";
}
sub get_options {
my ( $opt_def, $opt_str ) = @_;
# Add some default options.
$opt_str = {
'help|h' => 'this help',
%$opt_str,
};
# Auto-convert underscored long names to dashed long names.
foreach ( keys %$opt_str ) {
my ( $name, $type ) = split '=';
my @opts = split /\|/, $name;
my ( $underscored ) = grep {/_/} @opts;
my ( $dashed ) = grep {/-/} @opts;
if ( $underscored && !$dashed ) {
$dashed = $underscored;
$dashed =~ s/_/-/g;
splice @opts, ( length( $opts[-1] ) == 1 ? $#opts : @opts ), 0, $dashed;
my $key = join '|', @opts;
$key .= "=$type" if $type;
$opt_str->{$key} = $opt_str->{$_};
delete $opt_str->{$_};
}
}
my $opt = {%$opt_def};
my $success = GetOptions( $opt, keys %$opt_str );
usage( $opt_def, $opt_str ) if $opt->{help} || !$success;
$opt;
}
sub usage {
my ( $opt_def, $opt_str ) = @_;
my $maxlen = 0;
my $opt = {};
foreach ( keys %$opt_str ) {
my ( $name, $type ) = split '=';
my ( $var ) = split /\|/, $name;
my ( $long ) = reverse grep { length $_ != 1 } split /\|/, $name;
my ( $short ) = grep { length $_ == 1 } split /\|/, $name;
$maxlen = length $long if $long && $maxlen < length $long;
$opt->{ $long || $short || '' } = {
short => $short,
long => $long,
desc => $opt_str->{$_},
default => $opt_def->{$var}
};
}
print "Usage: $0 [options]\n";
foreach ( map { $opt->{$_} } sort keys %$opt ) {
printf " %2s %-*s %s%s\n", #
$_->{short} ? "-$_->{short}" : '', $maxlen + 2, $_->{long} ? "--$_->{long}" : '', $_->{desc}, $_->{default} ? " (default: $_->{default})" : "";
}
exit;
}
@vagetablee
Copy link

vagetablee commented Oct 26, 2018

@allanon
What did I do wrong? Please give me advice concerning what to do.

Thankyou.

untitled1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment