App::KGB::Client(3pm)

πŸ’– App::KGB::Client πŸ’–

okay so welcome to App::KGB::Client, bestie!! it's a Perl module from the User Contributed Perl Documentation fam, and it's literally the thing that relays your commits to KGB servers. yes queen, we're doing IRC notifications. πŸŽ€


✨ NAME ✨

App::KGB::Client β€” relay commits to KGB servers. that's it, that's the whole job. she's a messenger. πŸ¦‹


✨ SYNOPSIS ✨

use App::KGB::Client;
my $client = App::KGB::Client( <parameters> );
$client->run;

look at her go. two lines and a dream. πŸ’…


🌸 DESCRIPTION 🌸

So App::KGB::Client is the backend behind kgb-client(1). she's the one doing the actual work while the CLI takes the credit β€” main character energy tbh. πŸ‘‘

What she handles is all the repository-independent parts of yeeting notifications over to the KGB server, aka kgb-bot(1). πŸš€

The stuff that's not her job? Extracting changes from commits, branches, and modules. That's handled by sub-classes that are specific to whatever version control system you're running. She's the generalist, they're the specialists. it's giving delegation. ✨


πŸŽ€ CONFIGURATION πŸŽ€

These are all the parameters the constructor will accept, no cap. every single one, listed, because we do NOT skip options in this house:

  • repo_id repository name β€” a short repository identifier. This is what identifies your repo to the KGB daemon, and the daemon also uses it for IRC notifications. Mandatory. you cannot skip this one bestie. 🚨
  • uri URI β€” the URI of the KGB server. Something like "http://some.server:port". It's mandatory, either as a top-level parameter or as a sub-parameter of the servers array. so you got options, but you do have to give her something. πŸ™ˆ
  • proxy URI β€” the URI of the SOAP proxy. If you don't give one, it's just the value of the uri option with ?session=KGB tacked on the end. she'll figure it out herself, she's smart like that. πŸ’…
  • password password β€” the password for authenticating to the KGB server. Mandatory, either as a top-level parameter or as a sub-parameter of the servers array. again: required. ngl she will not let you in the club without it. 🎟️
  • timeout seconds β€” timeout for server communication. The default is 15 seconds, because we want instant IRC and commit response. instant. periodt. ⏱️
  • servers β€” an array of servers, where each one is an instance of the App::KGB::Client::ServerRef class. πŸ–₯️

When several servers are configured, the list gets shuffled, and then the servers are tried one after another until a successful request goes through β€” or until the list is exhausted, in which case an exception is thrown. 😭

When shuffling happens, preference is added to the last server used by the client, or by other clients (this only applies given that status_dir is configured). she remembers her faves. πŸ’œ

  • batch_messages β€” if true, the notifications are sent as a batch in one request to the server. Useful with VCS that send many changes at a time (e.g. Git). πŸ“¦

Defaults to false, but will be changed later after some grace period for server upgrade. so like, watch this space. πŸ‘€

  • br_mod_re β€” a list of regular expressions (simple strings, not qr objects) used to detect the branch and module of commits. Each item from the list is tried in turn, until an item is found that matches all the paths that were modified by the commit. The regular expressions must have two captures: the first one gives the branch name, and the second one gives the module name. 🧐

All the paths modified by the commit must resolve to the same branch and module in order for the branch and module to be transmitted to the KGB server.

Example:

^/(trunk)/([^/]+)/
# /trunk/module/file
^/branches/([^/]+)/([^/]+)/
# /branches/test/module/file
  • mod_br_re β€” same as br_mod_re, but it captures the module name first and the branch name second. literally the same thing but the order is flipped, she contains multitudes. πŸ™ƒ

Example:

^/branches/([^/]+)/([^/]+)/
# /branches/test/module/file
  • ignore_branch β€” when most of the development happens in one branch, transmitting it to the KGB server and seeing it on IRC all the time gets annoying. so: if you define ignore_branch, and a given commit is in a branch with that name, the branch name is not transmitted to the server. The module name is still transmitted though. she's quiet, not gone. 🀫
  • module β€” forces an explicit module name, overriding the branch and module detection. Useful in Git-hosted sub-projects that want to share a single configuration file, but still want module indication in notifications. one config, many modules, slay. 🧚
  • single_line_commits off|forced|auto β€” requests different modes of commit message processing:
    • off β€” no processing is done. The commit message is printed as it was given, with each line in a separate IRC message, blank lines omitted. This is the only possible behaviour in versions before 1.14. zero filter, raw text energy. πŸ’€
    • forced β€” only the first line is sent to IRC, regardless of whether it's followed by a blank line or not. first line only, no exceptions. βœ‚οΈ
    • auto β€” if the first line is followed by an empty line, only the first line is sent to IRC and the rest is ignored. This is the default since version 1.14. she reads the room. 🌈
  • use_irc_notices β€” if true, signals the server that it should use IRC notices instead of regular messages. Use this if regular messages are too distracting for your channel. lowkey polite of you honestly. 🀍
  • use_color β€” if true (the default), signals the server that it should use colors for commit notifications. because monochrome is not the vibe. 🌈
  • status_dir β€” specifies a directory to store information about the last server contacted successfully. The client touches files in that directory after successful completion of a notification with the remote server. πŸ—‚οΈ

Later, when asked to do another notification, the client starts from the most recently contacted server. But if that server was contacted too far in the past, the information in the directory is ignored and a random server is picked, as usual. bestie keeps receipts but she also lets go. πŸ’–

  • verbose β€” print diagnostic information. spill the tea, girl. β˜•
  • protocol version β€” use the specified protocol version. If "auto" (the default), the version of the protocol is 2, unless web_link is also given, in which case protocol version 3 is the default; πŸ”’
  • web_link template β€” a web link template to be sent to the server. The following items are expanded:
    • ${branch}
    • ${module}
    • ${commit}
    • ${project}
  • short_url_service service β€” a WWW::Shorten service to use for shortening the web_link. See WWW::Shorten for the list of supported services. short links, cute links. πŸ”—
  • msg_template string β€” provides a way to customize the notifications' appearance on IRC. When present, all message construction is done on the client and the prepared messages (possibly with colors etc.) are sent to the server for relaying to IRC. 🎨

The following special items are recognized and replaced with the respective commit elements:

  • ${project_id} β€” the ID of the project.
  • ${author_login} β€” the login of the author (e.g. "joe").
  • ${author_name} β€” the name of the commit author (e.g. "Joe Random").
  • ${author_via} β€” the name of the commit author, plus the name of the committer if that is different (e.g. "Joe Random" or "Joe Random (via Max Random)").
  • ${branch} β€” the branch of the commit.
  • ${module} β€” the module of the commit.
  • ${commit}, ${revision} β€” the ID of the commit.
  • ${path} β€” the changed path(s).
  • ${log} β€” the log message of the commit.
  • ${web} β€” the web link associated with the commit. Replaced with the empty string unless the web_link option is also given. (so if you didn't set web_link, you get nothing. ghosted. πŸ‘»)
  • style hash reference β€” provides a color map for different parts of the message. The following keys are supported. Defaults are used when keys are missing in the hash. use_color must be true for any of this to have any effect. And it's only used when msg_template is also given. the whole glow-up is conditional, iykyk. πŸ’…
    • revision, commit_id β€” commit ID. Default: none.
    • path β€” changed path. Default: teal.

Depending on the action performed on the path, additional coloring is made:

  • addition β€” used for added paths. Default: green.
  • modification β€” used for modified paths. Default: teal.
  • deletion β€” used for deleted paths. Default: bold red.
  • replacement β€” used for replaced paths (a Subversion concept). Default: brown.
  • prop_change β€” used for paths with changed properties (a Subversion concept), combined with other colors depending on the action β€” addition, modification or replacement. Default: underline.
  • author β€” commit author. Default: green.
  • branch β€” commit branch. Default: brown.
  • module β€” project module. Default: purple.
  • web β€” URL to commit information. Default: silver.
  • separator β€” the separator before the commit log. Default: none.
ok that's a LOT of options but every single one is here, don't skip, don't skim, she's thorough. πŸ’–

πŸ‘‘ CONSTRUCTOR πŸ‘‘

✨ new ( { initial values } ) ✨

Standard constructor with the initial values in a hashref. classic. reliable. iconic. 🫢

my $c = App::KGB::Client->new(
    {   repo_id => 'my-repo',
        servers => \@servers,
        ...
    }
);

See above. ⬆️ (that's the whole CONFIGURATION section, btw β€” go read it, bestie, it's right there.)

detect_branch_and_module ( $changes )

Okay so you hand it a whole pile of changes β€” that's an arrayref stuffed with App::KGB::Change objects, bestie β€” and it goes through every single regex listed in br_mod_re and mod_br_re. If one of those regexes matches all the changed paths, it hands you back the branch and the module. Slay.

( $branch, $module ) = $client->detect_branch_and_module($changes);

shuffle_servers

Returns you a shuffled remix of "$self->servers" ✨. But it's a smart shuffle, not a chaos shuffle: it checks who the last successfully used server was for this client instance and bumps that one to the front like the main character. If there's no such server, it peeks at the state living in "status_dir" and grabs the last server noted there β€” but only if that server was used within the last 5 minutes. Otherwise? Nope, no special treatment.


Takes every little ${item} thing floating around in $string and expands it using the data in the hashref you passed in 🫢.

So if you pass this:

 "http://git/${module}.git?commit=${commit}",
 { module => 'dh-make-perl', commit => '225ceca' }

you'd get back http://git/dh-make-perl.git?commit=225ceca. Vibe check passed.


shorten_url (url)

Uses whatever you configured as short_url_service to shorten the URL you gave it. And if you configured no shortening service at all? It just returns the original URL, no drama. You get what you gave. πŸ’…


note_last_server($srv)

If "status_dir" is set up, this notes $srv down as the last used server, so it can get used in the requests that come after. Lowkey just bookkeeping, but important bookkeeping.


init_painter

Creates an internal instance of App::KGB::Painter for all your message-colouring needs 🎨.

Does absolutely nothing if use_color is false, or if a painter has already been created. Like, why would it make a second one. It wouldn't.


colorize category => text

Returns you a colored version of text. And if there's no painter around? You just get the plain text back. No painter, no paint.


colorize_change change

Returns a colorized string representing one single change.


colorize_changes @changes

Returns a colorized string of all of the commit's changes πŸ¦‹.


format_message $template %details

Returns a fully formatted message, all ready to be yeeted off to the servers πŸ’Œ. It formats the message according to the message_format configuration parameter, and it honours colors and use_color while doing it.


process_commit ($commit)

Processes a single commit and gives you back something to send to the remote server. That "something" is either:

  • a reference to an array of arguments destined for App::KGB::ServerRef's send_changes method, or
  • in message-relay mode, a plain scalar string representing the commit.

And here's the cute part: if $commit is already a plain scalar β€” like, not a reference, bestie β€” then it's assumed to already be a processed string, and it just gets returned directly. No re-processing, no double work.


process

The main processing method πŸ‘‘. It calls describe_commit, and for as long as that keeps returning true values, it feeds them into process_commit and sends the result off to the server.

Oh and if the batch_messages flag is true, it relays all the accumulated messages after processing. Batched up and delivered, periodt.


send_changes @args

Tries to send the changes described in the arrayref you handed it to all the configured servers πŸ“‘. All of them. It's trying real hard.


relay_message message

Sends a simple message to the servers for relaying. This one is the implementation behind the --relay-msg command line option, iykyk.


🌸 PROVIDING REPOSITORY-SPECIFIC FUNCTIONALITY 🌸

App::KGB::Client is the generic bestie β€” it provides repository-agnostic functionality and stays out of your repo's business. All the repository-specific methods have to come from classes that inherit from App::KGB::Client. Go look at App::KGB::Client::Subversion and App::KGB::Client::Git if you want examples ✨.

So, repository classes must provide this method:

dsescribe_commit

Yes bestie, the typo is right there in the original and we are keeping it exactly as-is. Do not "fix" it. Copy the spelling. 😭

This method returns an App::KGB::Commit object that represents a single commit of the repository.

Here's the thing though β€” describe_commit gets called several times, over and over, until it returns "undef". The whole idea is that one single App::KGB::Client run can be used to process several commits at once (which happens, for example, if the repository is git(1) πŸ’€). If that's the case, each call to describe_commit should return the info about the next commit in the series. But for svn(1)? This module is expected to return only one commit, and every call after that shall return "undef".


πŸ’– SEE ALSO πŸ’–

  • App::KGB::Client::Subversion
  • App::KGB::Client::Git

And that's a wrap, bestie πŸŽ€ this was App::KGB::Client(3pm) from the perl v5.40.1 era, dated 2026-07-10, straight out of the User Contributed Perl Documentation. Go ship some commits and make your servers proud πŸ’…βœ¨

πŸ“¦ where this page comes from