#!/bin/perl # # TODO: detect existing repos and automatically modify config file accordingly # TODO: function to detect unclean working trees # TODO: Handle cloning # TODO: Handle pulling # TODO: Trigger hooks on clone/pull # print("This shit ain't done yet!\n"); # exit; use strict; use warnings; use feature ("signatures"); use YAML(); use JSON(); use WWW::Curl::Easy; use WWW::Curl::Multi; use Data::Dump(); use File::Path(); use constant USERAGENT => "User-Agent: MarxBot/4.2.0 (A script reading some information about repos)"; my @handles; my %conf; my $active_repos = 0; my $active_requests = 0; sub set_curl( $handle, $url, @headers ) { $handles[$handle]{curl} = WWW::Curl::Easy->new; $handles[$handle]{curl}->setopt( CURLOPT_URL, $url ); $handles[$handle]{curl}->pushopt( CURLOPT_HTTPHEADER, [USERAGENT] ); for my $header (@headers) { $handles[$handle]{curl}->pushopt( CURLOPT_HTTPHEADER, [$header] ); } $handles[$handle]{curl}->setopt( CURLOPT_PRIVATE, $handle ); $handles[$handle]{curl} ->setopt( CURLOPT_WRITEDATA, \$handles[$handle]{memory} ); } sub add_callback( $handle, $callback ) { push( @{ $handles[$handle]{callbacks} }, $callback ); } sub exec_multicurl() { my $curlm = WWW::Curl::Multi->new; for my $handle (@handles) { if ($handle) { $curlm->add_handle( $handle->{curl} ); $active_requests++; } } while ($active_requests) { my $active_transfers = $curlm->perform; if ( $active_transfers != $active_requests ) { while ( my ( $handle, $return_value ) = $curlm->info_read ) { if ($handle) { $active_requests--; if ( $handles[$handle]{callbacks} ) { for my $callback ( @{ $handles[$handle]->{callbacks} } ) { $callback->($handle); } } delete $handles[$handle]; } } } } } sub json_decode($handle) { $handles[$handle]{memory} = JSON::decode_json( $handles[$handle]{memory} ); } sub filter($handle) { my @tmp; my $plugin = $conf{plugins}[ $handles[$handle]->{plugin} ]; foreach my $repo ( @{ $handles[$handle]{memory} } ) { if ( $repo->{ssh_url} ) { push( @tmp, $repo->{ %$plugin{url_type} } ); } } $handles[$handle]{memory} = \@tmp; } sub process_urls($handle) { my @tmp; foreach my $url ( @{ $handles[$handle]{memory} } ) { my %repo; if ( $url =~ /^(.*[\/:](([a-zA-Z0-9-_.]+)\/([a-zA-Z0-9-_.]+?))(?:\.git)?\/?)$/ ) { $repo{url} = $1; $repo{name} = $2; } else { return; } continue if grep /^$repo{name}$/, $conf{block_repos}; my $path; foreach my $directory ( @{ $conf{directories} } ) { foreach my $reponame ( @{ %$directory{repos} } ) { if ( $reponame =~ $repo{name} ) { $path = %$directory{path}; last; } } } if ( !$path and !$conf{block_unsorted} ) { $path = "\${XDG_DOCUMENTS_DIR}/unsorted_repos"; $repo{path} = `printf $path`; push( @tmp, %repo ); } } $handles[$handle]{memory} = \@tmp; } sub dump($handle) { print("------ Handle $handle ------\n"); Data::Dump::dump( $handles[$handle]{memory} ); } # sub handle_repos($handle) { # foreach my $repo (@{$handles[$handle]->{memory}}) { # if (-d $repo{}) # } # } sub read_conf() { my $configdir; if ( $ENV{XDG_CONFIG_HOME} ) { $configdir = "$ENV{XDG_CONFIG_HOME}/clonedev"; } else { $configdir = "$ENV{HOME}/.config/clonedev"; } open( my $cfg, '<', $configdir . "/config.yml" ) or die; my ( $hashref, $arrayref, $string ) = YAML::Load( do { local $/; <$cfg> } ); close($cfg); %conf = %$hashref; } # ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ # ░ ░░░░ ░░░ ░░░ ░░ ░░░ ░ # ▒ ▒▒ ▒▒ ▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒ ▒ # ▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓ ▓ ▓ # █ █ █ ██ █████ █████ ██ █ # █ ████ ██ ████ ██ ██ ███ █ # ████████████████████████████████████████ read_conf(); # $last_handle++; # set_curl( $last_handle, "https://api.github.com/octocat" ); # add_callback( # $last_handle, # sub ($handle) { # print( $handles[$handle]{memory} ); # } # ); # my $last_handle = 0; foreach my $i ( keys @{ $conf{plugins} } ) { my %plugin = %{ $conf{plugins}[$i] }; chomp( $ENV{TOKEN} = $plugin{token_cmd} ? `$plugin{token_cmd}` : "" ); foreach ( @{ $plugin{extra_headers} } ) { last if ( !$_ ); $_ = `printf "$_"`; } foreach my $j ( keys @{ $plugin{targets} } ) { $last_handle++; $handles[$last_handle]{plugin} = $i; print("$plugin{api_url}/$plugin{targets}[$j]/$plugin{endpoint}\n"); set_curl( $last_handle, "$plugin{api_url}/$plugin{targets}[$j]/$plugin{endpoint}", $plugin{extra_headers} ); add_callback( $last_handle, \&dump ); add_callback( $last_handle, \&json_decode ); add_callback( $last_handle, \&filter ); add_callback( $last_handle, \&process_urls ); add_callback( $last_handle, \&dump ); } } exec_multicurl();