github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/gen_deps.pl (about)

     1  #!/usr/bin/env perl
     2  use strict;
     3  use warnings;
     4  use 5.010;
     5  
     6  use Data::Dumper qw(Dumper);
     7  use JSON::PP qw(encode_json);
     8  
     9  my $dep_packages = {};
    10  my @oses = ('linux', 'windows');
    11  my $os_packages = {};
    12  my $total_packages = 0;
    13  # Any packages to exclude. This needs to include CGO packages since those aren't cross-compilable.
    14  my $excluded_pkg_regex = 'github.com/coreos/pkg/dlopen';
    15  
    16  $ENV{'GOARCH'} = 'amd64';
    17  foreach my $os (@oses) {
    18      $ENV{'GOOS'} = $os;
    19      my @packages = split /\n/, `go list ./... | grep -v github.com\\/keybase\\/client\\/go\\/bind`;
    20      $os_packages->{$os} = \@packages;
    21      $total_packages += scalar @packages;
    22  }
    23  say STDERR "total packages for which to calculate dependencies: $total_packages";
    24  
    25  my $forks = 0;
    26  foreach my $os (@oses) {
    27      my $pid = fork;
    28      if (not defined $pid) {
    29          warn "Could not fork for os: $os";
    30          next;
    31      }
    32      if ($pid) {
    33          # In the parent process
    34          $forks++;
    35          next;
    36      }
    37      $ENV{'GOOS'} = $os;
    38      # create a pattern file that matches tracked go modules (excluding the main module github.com/keybase/client/go)
    39      # example pattern: ^github.com/keybase/go-framed-msgpack-rpc(/|$)
    40      chomp(my $gomodulepattern = `mktemp`);
    41      system "go list -f '{{if not .Main}}{{ .Path }}{{end}}' -m all | sed 's/^/\\\^/' | sed 's/\$/\\(\\/\\|\\\$\)/' | sort > '$gomodulepattern'";
    42      my $i = 0;
    43      my $num_packages = scalar @{$os_packages->{$os}};
    44      foreach my $package (@{$os_packages->{$os}}) {
    45          $i++;
    46          my $percent_complete = (($i) * 100) / $num_packages;
    47          printf STDERR ("%7s: %3d of %3d complete (%3.0f%%) [%s]\n", $os, $i, $num_packages, $percent_complete, $package);
    48  
    49          # This should include dependencies required by go.mod
    50          my @deps = split /\n/, `go list -f '{{ printf "%s\\n%s\\n%s" (join .TestImports "\\n") (join .Imports "\\n") "$package" }}' "$package" 2>/dev/null | grep -oE -f "$gomodulepattern" -e "github.com/keybase/client/.*" | sed 's/\\/\$//' | sort -u`;
    51          my $deps = join(' ', @deps);
    52          my @indirect_deps = split /\n/, `go list -f '{{ join .Deps "\\n" }}' $deps 2>/dev/null | grep -oE -f "$gomodulepattern" -e "github.com/keybase/client/.*" | sed 's/\\/\$//' | sort -u | grep -v '$excluded_pkg_regex'`;
    53          push(@deps, @indirect_deps);
    54  
    55          foreach my $dep (do { my %deps; grep { !$deps{$_}++ } @deps}) {
    56              $dep_packages->{$os}->{$dep}->{$package} = 1;
    57          }
    58      }
    59      my $json_output = JSON::PP->new->utf8->pretty->canonical()->encode($dep_packages->{$os});
    60      open(my $fh, '>', ".go_package_deps_$os");
    61      print $fh "$json_output";
    62      close($fh);
    63      exit;
    64  }
    65  
    66  for (1 .. $forks) {
    67      my $pid = wait();
    68  }