123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- #!/usr/bin/perl
- #***************************************************************************
- # _ _ ____ _
- # Project ___| | | | _ \| |
- # / __| | | | |_) | |
- # | (__| |_| | _ <| |___
- # \___|\___/|_| \_\_____|
- #
- # Copyright (C) 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
- #
- # This software is licensed as described in the file COPYING, which
- # you should have received as part of this distribution. The terms
- # are also available at https://curl.se/docs/copyright.html.
- #
- # You may opt to use, copy, modify, merge, publish, distribute and/or sell
- # copies of the Software, and permit persons to whom the Software is
- # furnished to do so, under the terms of the COPYING file.
- #
- # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- # KIND, either express or implied.
- #
- # SPDX-License-Identifier: curl
- #
- ###########################################################################
- my %filelevel= ('file' => 1,
- 'service' => 1);
- my $jobid = 1;
- sub submit {
- my ($jref)=@_;
- my %job = %$jref;
- printf "\n##### job %u \n", $jobid++;
- for my $k (sort keys %job) {
- printf "%s: %s\n", $k, $job{$k} if($job{$k});
- undef $$jref{$k} if(!$filelevel{$k});
- }
- }
- sub githubactions {
- my ($tag)=@_;
- my @files= `git ls-tree -r --name-only $tag .github/workflows 2>/dev/null`;
- my $c = 0;
- foreach my $f (sort @files) {
- my $j = 0;
- my $m = -1;
- my $done = 0;
- chomp $f;
- open(G, "git show $tag:$f 2>/dev/null|");
- # start counting file jobs
- undef %job;
- $job{'file'} = $f;
- $job{'service'} = "gha";
- my @cc;
- my $os;
- my $topname;
- my $line = 1;
- while(<G>) {
- $job{'line'} = $line;
- if($_ =~ /^name: (.*)/) {
- $topname=$1;
- }
- elsif($_ =~ /runs-on: (.*)/) {
- my $r = $1;
- #print "runs-on: $r\n";
- if($r =~ /ubuntu/) {
- $os = "linux";
- }
- elsif($r =~ /macos/) {
- $os = "macos";
- }
- # commit previously counted jobs
- $c += $j;
- # non-matrix job
- $j = 1;
- }
- elsif($_ =~ /matrix:/) {
- # switch to matrix mode
- $m = 0;
- $j = 0;
- }
- elsif($_ =~ /^ - run: .* apt-get install (.*)/) {
- $job{'install'} = $1;
- }
- elsif($m >= 0) {
- if($_ =~ /^ - name: (.*)/) {
- # matrix job
- #print "name: $1\n";
- $job{'name'} = $1;
- $j += ($m?$m:1);
- }
- elsif($_ =~ /install: (.*)/) {
- $job{'install'} = $1;
- }
- elsif($_ =~ /( |curl-)configure: (.*)/) {
- $job{'configure'} = $2;
- $job{'os'}=$os;
- submit(\%job);
- $done++;
- }
- elsif($_ =~ /generate: (.*)/) {
- $job{'cmake'} = $1;
- if($m) {
- # matrix mode, multiple copies
- my %dupe = %job;
- for my $cc (@cc) {
- %job = %dupe;
- $job{'cc'} = $cc;
- $job{'os'}=$os;
- submit(\%job);
- $done++;
- }
- }
- else {
- $job{'os'}=$os;
- submit(\%job);
- $done++;
- }
- }
- elsif($_ =~ /- CC: (.*)/) {
- # matrix multiplier
- push @cc, $1;
- $m++;
- }
- elsif($_ =~ /steps:/) {
- # disable matrix mode
- $m = -1;
- }
- }
- $line++;
- }
- close(G);
- # commit final counted jobs
- $c += $j;
- if(!$done) {
- $job{'name'} = $topname? $topname : '[unnamed]';
- $job{'os'}=$os;
- submit(\%job);
- $done++;
- }
- # reset internal job counter
- $j = 0;
- }
- #print "Jobs: $c\n";
- return $c;
- }
- sub azurepipelines {
- my ($tag)=@_;
- open(G, "git show $tag:.azure-pipelines.yml 2>/dev/null|");
- my $c = 0;
- my $j = 0;
- my $m = -1;
- my $image;
- my %job;
- my $line = 1;
- my $os;
- $job{'file'} = ".azure-pipelines.yml";
- $job{'service'} = "azure";
- while(<G>) {
- if($_ =~ /^ vmImage: (.*)/) {
- my $i = $1;
- if($i =~ /ubuntu/) {
- $os = "linux";
- }
- elsif($i =~ /windows/) {
- $os = "windows";
- }
- }
- elsif($_ =~ /^- stage: (.*)/) {
- my $topname = $1;
- if($topname !~ /(windows|linux)/) {
- $job{'name'} = $topname;
- $job{'line'}=$line;
- submit(\%job);
- }
- }
- elsif($_ =~ /job:/) {
- # commit previously counted jobs
- $c += $j;
- # initial value for non-matrix job
- $j = 1;
- }
- elsif($_ =~ /matrix:/) {
- # start of new matrix list(!)
- $m = 0;
- $j = 0;
- }
- elsif($m >= 0) {
- if($_ =~ /^ name: (.*)/) {
- # single matrix list entry job
- $j++;
- $job{'name'} = $1;
- }
- # azure matrix is a simple list,
- # therefore no multiplier needed
- elsif($_ =~ /steps:/) {
- # disable matrix mode
- $m = -1;
- }
- elsif($_ =~ /^ configure: (.*)/) {
- $job{'configure'} = $1;
- $job{'line'}=$line;
- $job{'os'}=$os;
- submit(\%job);
- }
- }
- $line++;
- }
- close(G);
- # commit final counted jobs
- $c += $j;
- return $c;
- }
- sub appveyor {
- my ($tag)=@_;
- open(G, "git show $tag:appveyor.yml 2>/dev/null|");
- my $c = 0;
- my %job;
- my $line=0;
- $job{'file'} = "appveyor.yml";
- $job{'service'} = "appveyor";
- while(<G>) {
- $line++;
- if($_ =~ /^( - |install)/) {
- if($job{'image'}) {
- $job{'os'} = "windows";
- submit(\%job);
- $c++;
- }
- }
- $job{'line'} = $line;
- if($_ =~ /^ - APPVEYOR_BUILD_WORKER_IMAGE: \"(.*)\"/) {
- $job{'image'}= $1;
- }
- elsif($_ =~ /^ BUILD_SYSTEM: (.*)/) {
- $job{'build'} = lc($1);
- }
- elsif($_ =~ /^ PRJ_GEN: \"(.*)\"/) {
- $job{'compiler'} = $1;
- }
- elsif($_ =~ /^ PRJ_CFG: (.*)/) {
- $job{'config'} = $1;
- }
- elsif($_ =~ /^ OPENSSL: (.*)/) {
- $job{'openssl'} = $1 eq "ON" ? "true": "false";
- }
- elsif($_ =~ /^ SCHANNEL: (.*)/) {
- $job{'schannel'} = $1 eq "ON" ? "true": "false";
- }
- elsif($_ =~ /^ ENABLE_UNICODE: (.*)/) {
- $job{'unicode'} = $1 eq "ON" ? "true": "false";
- }
- elsif($_ =~ /^ HTTP_ONLY: (.*)/) {
- $job{'http-only'} = $1 eq "ON" ? "true": "false";
- }
- elsif($_ =~ /^ TESTING: (.*)/) {
- $job{'testing'} = $1 eq "ON" ? "true": "false";
- }
- elsif($_ =~ /^ SHARED: (.*)/) {
- $job{'shared'} = $1 eq "ON" ? "true": "false";
- }
- elsif($_ =~ /^ TARGET: \"-A (.*)\"/) {
- $job{'target'} = $1;
- }
- }
- close(G);
- return $c;
- }
- sub cirrus {
- my ($tag)=@_;
- open(G, "git show $tag:.cirrus.yml 2>/dev/null|");
- my $c = 0;
- my %job;
- my $line=0;
- my $name = 0;
- my $os;
- $job{'file'} = ".cirrus.yml";
- $job{'service'} = "cirrus";
- while(<G>) {
- $line++;
- if($_ =~ /^ ( |-) (name|image_family|image):/) {
- $c++;
- }
- if($_ =~ /^ - name:/) {
- if($name) {
- $job{'os'} = $os;
- $job{'line'} = $line;
- submit(\%job);
- $name = 0;
- }
- }
- if($_ =~ /^ - name: (.*)/) {
- $job{'name'} = $1;
- $name = 1;
- }
- elsif($_ =~ /^ image_family: (.*)/) {
- $os = "freebsd";
- }
- elsif($_ =~ /^windows_task:/) {
- $os = "windows";
- }
- elsif($_ =~ /^ prepare: pacman -S --needed --noconfirm --noprogressbar (.*)/) {
- $job{'install'} = $1;
- }
- elsif($_ =~ /^ configure: (.*)/) {
- $job{'configure'} = $1;
- }
- }
- close(G);
- if($name) {
- $job{'os'} = $os;
- $job{'line'} = $line;
- submit(\%job);
- }
- return $c;
- }
- sub circle {
- my ($tag)=@_;
- open(G, "git show $tag:.circleci/config.yml 2>/dev/null|");
- my $c = 0;
- my $wf = 0;
- my %job;
- my %cmd;
- my %configure;
- my %target;
- my $line=0;
- my $cmds;
- my $jobs;
- my $workflow;
- $job{'file'} = ".circleci/config.yml";
- $job{'service'} = "circleci";
- while(<G>) {
- $line++;
- if($_ =~ /^commands:/) {
- # we record configure lines in this state
- $cmds = 1;
- }
- elsif($cmds) {
- if($_ =~ /^ ([^ ]*):/) {
- $cmdname = $1;
- }
- elsif($_ =~ /^ .*.\/configure (.*)/) {
- $cmd{$cmdname}=$1;
- }
- }
- if($_ =~ /^jobs:/) {
- # we record which job runs with configure here
- $jobs = 1;
- $cmds = 0;
- }
- elsif($jobs) {
- if($_ =~ /^ ([^ ]*):/) {
- $jobname = $1;
- }
- elsif($_ =~ /^ - (configure.*)/) {
- $configure{$jobname}=$1;
- }
- elsif($_ =~ /^ resource_class: arm.medium/) {
- $target{$jobname}="arm";
- }
- }
- if($_ =~ /^workflows:/) {
- $wf = 1;
- $cmds = 0;
- }
- elsif($wf) {
- if($_ =~ /^ ([^ ]+):/) {
- $workflow = $1;
- }
- elsif($_ =~ /^ - (.*)\n/) {
- my $jb = $1;
- my $cnfgure = $configure{$jb};
- my $trgt = $target{$jb};
- $job{'configure'} = $cmd{$cnfgure};
- $job{'name' }=$workflow;
- $job{'os'} = "linux";
- $job{'line'} = $line;
- $job{'target'} = $trgt if($trgt);
- submit(\%job);
- }
- if($_ =~ / *jobs:/) {
- $c++;
- }
- }
- }
- close(G);
- return $c;
- }
- sub zuul {
- my ($tag)=@_;
- open(G, "git show $tag:zuul.d/jobs.yaml 2>/dev/null|");
- my $c = 0;
- my %job;
- my $line=0;
- my $type;
- $job{'file'} = "zuul.d/jobs.yaml";
- $job{'service'} = "zuul";
- while(<G>) {
- $line++;
- #print "L: ($jobmode / $env) $_";
- if($_ =~ /^- job:/) {
- $jobmode = 1; # start a new
- $type="configure";
- }
- if($jobmode) {
- if($apt) {
- if($_ =~ /^ - (.*)/) {
- my $value = $1;
- $job{'install'} .= "$value ";
- }
- else {
- $apt = 0; # end of curl_apt_packages
- }
- }
- if($env) {
- if($envcont) {
- if($_ =~ /^ (.*)/) {
- $job{$envcont} .= "$1 ";
- }
- else {
- $envcont = "";
- }
- }
- if($_ =~ /^ ([^:]+): (.*)/) {
- my ($var, $value) = ($1, $2);
- if($var eq "C") {
- $var = $type;
- }
- elsif($var eq "T") {
- $var = "tests";
- if($value eq "cmake") {
- # otherwise it remains configure
- $type = "cmake";
- }
- }
- elsif($var eq "CC") {
- $var = "compiler";
- }
- elsif($var eq "CHECKSRC") {
- $job{'checksrc'} = $value ? "true": "false";
- $var = "";
- }
- else {
- $var = "";
- }
- if($value eq ">-") {
- $envcont = $var;
- }
- elsif($var) {
- $job{$var} = $value;
- }
- }
- elsif($_ !~ /^ /) {
- # end of envs
- $env = 0;
- }
- }
- if($_ =~ /^ curl_env:/) {
- $env = 1; # start of envs
- }
- elsif($_ =~ /^ curl_apt_packages:/) {
- $apt = 1; # start of apt packages
- }
- elsif($_ =~ /^ name: (.*)/) {
- my $n = $1;
- if($n eq "curl-base") {
- # not counted
- $jobmode = 0;
- next;
- }
- $job{'name'} = $n;
- }
- elsif($_ =~ /^\n\z/) {
- # a job is complete
- $job{'line'}=$line;
- $job{'os'}="linux";
- submit(\%job);
- $jobmode = 0;
- $c++;
- }
- }
- }
- close(G);
- return $c;
- }
- my $tag = `git rev-parse --abbrev-ref HEAD 2>/dev/null` || "master";
- chomp $tag;
- githubactions($tag);
- azurepipelines($tag);
- appveyor($tag);
- zuul($tag);
- cirrus($tag);
- circle($tag);
|