From cc4615e7c42f91cb4c818682421d3a3e42f205aa Mon Sep 17 00:00:00 2001 From: Sylvain Date: Sun, 8 Sep 2024 15:14:22 -0300 Subject: [PATCH] fix: do not depend on git-lfs being installed during git clone The current git-lfs integration runs `git lfs pull` after the normal git operations. We therefore setup the git repositories to essentially do nothing on clone/fetch/pull/... However, the way this is done so far is by using the `--skip` options to git-lfs ... which relies on git-lfs itself. This is a problem on platforms where installing git-lfs is an issue. Use pass-through filters that do not rely on git-lfs during cloning instead. The "real" setup is done after the import anyways. --- lib/autobuild/import/git-lfs.rb | 9 +- lib/autobuild/import/git-noop-filter | 134 +++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 3 deletions(-) create mode 100755 lib/autobuild/import/git-noop-filter diff --git a/lib/autobuild/import/git-lfs.rb b/lib/autobuild/import/git-lfs.rb index 4f544027..12469672 100644 --- a/lib/autobuild/import/git-lfs.rb +++ b/lib/autobuild/import/git-lfs.rb @@ -1,8 +1,11 @@ # Disable git-lfs at checkout time, we run install --local and pull later -Autobuild::Git.default_config['filter.lfs.smudge'] = 'git-lfs smudge --skip -- %f' -Autobuild::Git.default_config['filter.lfs.required'] = 'false' - module Autobuild + GIT_NOOP_FILTER = File.join(__dir__, "git-noop-filter") + Git.default_config['filter.lfs.smudge'] = "cat" + Git.default_config['filter.lfs.clean'] = "cat" + Git.default_config["filter.lfs.process"] = GIT_NOOP_FILTER + Git.default_config['filter.lfs.required'] = 'false' + def self.lfs_setup(importer, package) importer.run_git(package, 'lfs', 'install', '--force', '--local', '--skip-smudge') diff --git a/lib/autobuild/import/git-noop-filter b/lib/autobuild/import/git-noop-filter new file mode 100755 index 00000000..68b21f54 --- /dev/null +++ b/lib/autobuild/import/git-noop-filter @@ -0,0 +1,134 @@ +#!/usr/bin/perl +# +# Example implementation for the Git filter protocol version 2 +# See Documentation/gitattributes.txt, section "Filter Protocol" +# +# Please note, this pass-thru filter is a minimal skeleton. No proper +# error handling was implemented. +# + +use strict; +use warnings; + +my $MAX_PACKET_CONTENT_SIZE = 65516; + +sub packet_bin_read { + my $buffer; + my $bytes_read = read STDIN, $buffer, 4; + if ( $bytes_read == 0 ) { + + # EOF - Git stopped talking to us! + exit(); + } + elsif ( $bytes_read != 4 ) { + die "invalid packet: '$buffer'"; + } + my $pkt_size = hex($buffer); + if ( $pkt_size == 0 ) { + return ( 1, "" ); + } + elsif ( $pkt_size > 4 ) { + my $content_size = $pkt_size - 4; + $bytes_read = read STDIN, $buffer, $content_size; + if ( $bytes_read != $content_size ) { + die "invalid packet ($content_size bytes expected; $bytes_read bytes read)"; + } + return ( 0, $buffer ); + } + else { + die "invalid packet size: $pkt_size"; + } +} + +sub packet_txt_read { + my ( $res, $buf ) = packet_bin_read(); + unless ( $buf =~ s/\n$// ) { + die "A non-binary line MUST be terminated by an LF."; + } + return ( $res, $buf ); +} + +sub packet_bin_write { + my $buf = shift; + print STDOUT sprintf( "%04x", length($buf) + 4 ); + print STDOUT $buf; + STDOUT->flush(); +} + +sub packet_txt_write { + packet_bin_write( $_[0] . "\n" ); +} + +sub packet_flush { + print STDOUT sprintf( "%04x", 0 ); + STDOUT->flush(); +} + +( packet_txt_read() eq ( 0, "git-filter-client" ) ) || die "bad initialize"; +( packet_txt_read() eq ( 0, "version=2" ) ) || die "bad version"; +( packet_bin_read() eq ( 1, "" ) ) || die "bad version end"; + +packet_txt_write("git-filter-server"); +packet_txt_write("version=2"); +packet_flush(); + +( packet_txt_read() eq ( 0, "capability=clean" ) ) || die "bad capability"; +( packet_txt_read() eq ( 0, "capability=smudge" ) ) || die "bad capability"; +( packet_txt_read() eq ( 0, "capability=delay" ) ) || die "bad capability"; +my ( $res, $buf ) = packet_bin_read(); +( $buf eq ( 1, "" ) ) || die "bad capability end $buf"; + +packet_txt_write("capability=clean"); +packet_txt_write("capability=smudge"); +packet_flush(); + +while (1) { + my ($command) = packet_txt_read() =~ /^command=(.+)$/; + my ($pathname) = packet_txt_read() =~ /^pathname=(.+)$/; + + if ( $pathname eq "" ) { + die "bad pathname '$pathname'"; + } + + packet_bin_read(); + + my $input = ""; + { + binmode(STDIN); + my $buffer; + my $done = 0; + while ( !$done ) { + ( $done, $buffer ) = packet_bin_read(); + $input .= $buffer; + } + } + + my $output; + if ( $command eq "clean" ) { + ### Perform clean here ### + $output = $input; + } + elsif ( $command eq "smudge" ) { + ### Perform smudge here ### + $output = $input; + } + else { + die "bad command '$command'"; + } + + packet_txt_write("status=success"); + packet_flush(); + while ( length($output) > 0 ) { + my $packet = substr( $output, 0, $MAX_PACKET_CONTENT_SIZE ); + packet_bin_write($packet); + if ( length($output) > $MAX_PACKET_CONTENT_SIZE ) { + $output = substr( $output, $MAX_PACKET_CONTENT_SIZE ); + } + else { + $output = ""; + } + } + packet_flush(); # flush content! + packet_flush(); # empty list, keep "status=success" unchanged! + +}