Monoton...ateStdio(3)
π NAME π
Monotone::AutomateStdio β bestie, this is the Perl interface to Monotone via automate stdio π«Ά
β¨ VERSION β¨
1.10
πΈ SYNOPSIS πΈ
use Monotone::AutomateStdio qw(:capabilities :severities);
my(@manifest,
$mtn,
@revs);
$mtn = Monotone::AutomateStdio->new("/home/fred/venge.mtn");
$mtn->select(\@revs, "h:net.venge.monotone");
$mtn->get_manifest_of(\@manifest, $revs[0])
or die("mtn: " . $mtn->get_error_message());
π¦ DESCRIPTION π¦
Okay so, the Monotone::AutomateStdio class hands a Perl developer access to Monotone's automate stdio facility through an interface that is genuinely a joy to use. No cap. Every command, option and output format gets handled internally by this class β you do not have to touch any of it. Any structured info that Monotone sends back gets parsed and returned to the caller as lists of records, for easy peasy access (all detailed down below β¬οΈ). And if you'd rather just have Monotone's output as one big ol' string? That option is also there for you, bestie.
The mtn automate stdio subprocess is also controlled by this class, fr fr. A brand new subprocess gets started, if it's needed, whenever anything requiring one is called. That subprocess gets terminated when the object is destroyed, or whenever $mtn->closedown() is called. π
Every single automate command has been implemented in this class except the stdio command β and hopefully the reason for that is, like, extremely obvious :-). The versions of Monotone that this class supports range from 0.35 all the way up to and including the latest version (currently 1.10). And if you happen to be running a newer version of Monotone? This class will hopefully mostly work, but without support for any of the new or changed features. It's giving "we'll see" energy. π
π CONSTRUCTORS π
$mtn = Monotone::AutomateStdio->new([\@options])
Creates a new Monotone::AutomateStdio object, using the database from the current workspace. β¨
$mtn = Monotone::AutomateStdio->new_from_db($db[, \@options])
Creates a new Monotone::AutomateStdio object, using the database named in $db.
$mtn = Monotone::AutomateStdio->new_from_service($service, [\@options])
Creates a new Monotone::AutomateStdio object, using the named network service β which gets expressed as either a Monotone style URL, or a host name optionally followed by a colon and the port number.
(feature: MTN_REMOTE_CONNECTIONS)
$mtn = Monotone::AutomateStdio->new_from_ws($ws[, \@options])
Creates a new Monotone::AutomateStdio object, using the workspace named in $ws.
Please note: Monotone::AutomateStdio->new() is simply an alias for Monotone::AutomateStdio->new_from_db(). Same thing, different name, iconic behaviour. π
The @options parameter specifies which options get passed to the mtn subprocess. The currently supported list (in vaguely the format in which it would be passed to the constructor) is:
["--allow-default-confdir",
"--allow-workspace",
"--builtin-rcfile",
"--clear-rcfiles",
"--confdir" => <Directory>,
"--key" => <Key To Be Used For Signatures>,
"--keydir" => <Key Store Location>,
"--no-builtin-rcfile",
"--no-default-confdir",
"--no-standard-rcfiles",
"--no-workspace",
"--norc",
"--nostd",
"--rcfile" => <LUA File To Load>,
"--root" => <Root Directory>,
"--ssh-sign" => One of "check", "no" or "yes",
"--standard-rcfiles",
"--use-default-key"]
π₯ CLASS METHODS π₯
Monotone::AutomateStdio->register_db_locked_handler([$handler[, $client_data]])
Registers the handler specified as a subroutine reference in $handler for database locked conditions. The value of $client_data is just passed straight to the handler, and the caller can use it to provide a context. This is both a class method and an object one. When you use it as a class method, the database locked handler you specify gets used for all Monotone::AutomateStdio objects that don't specify handlers of their own. And if no handler is given? The database locked condition handling resets to the default behaviour. π«
The handler subroutine gets two arguments: the first is the Monotone::AutomateStdio object that encountered the locked database, and the second is the value passed in as $client_data when the handler was registered. If the handler returns true then the request that failed gets retried β but if false (undef) comes back, the default behaviour kicks in, which is to treat it like any other error.
Typically you'd register a database locked handler when you're using this class in a long running application, where it's quite possible that a user might do an mtn sync in the background. For example, mtn-browse uses this handler to display a Database is locked, please retry... dialog window.
Monotone::AutomateStdio->register_error_handler($severity[, $handler[, $client_data]])
Registers the handler specified as a subroutine reference in $handler for errors of a certain severity, as specified by $severity. $severity can be one of MTN_SEVERITY_WARNING, MTN_SEVERITY_ERROR or MTN_SEVERITY_ALL. The value of $client_data is just passed to the handler, and the caller can use it to provide a context. This one is a class method rather than an object one, because errors can be raised when calling a constructor. If no handler is given, the error handling resets to the default behaviour for that severity level.
The handler subroutine gets three arguments: the first is a severity string that indicates the severity of the error being handled (either MTN_SEVERITY_WARNING or MTN_SEVERITY_ERROR), the second is the error message, and the third is the value passed in as $client_data when the handler was registered.
Please note:
- Warnings can be generated internally, or whenever a message is received from an
mtnsubprocess that's flagged as being in error. For example, this happens when an invalid selector is given to the$mtn->select()method. The subprocess does not exit under these conditions. Errors, however, are generated whenever this class detects abnormal behaviour β like output that's formatted in an unexpected manner, or output appearing on themtnsubprocess'sSTDERRfile descriptor. Under those circumstances it's expected that the application should exit, or at the very least destroy anyMonotone::AutomateStdioobjects that are in error. π - Whilst warnings result in false being returned by those methods that return a boolean success indicator, errors always result in an exception being thrown.
- If the severity is
MTN_SEVERITY_ERRORthen it's expected thatcroakordiewill be called by the handler. If that isn't the case, then this class will callcroak()upon return. If you need to trap errors and prevent program exit, then use anevalblock to protect yourself in the calling code. π‘οΈ - If a warning handler is registered then you can use it to report problems via one routine, rather than checking the boolean success indicator returned by most methods in this class.
- In order to get the severity constants into your namespace you need to use the following to load in this library:
use Monotone::AutomateStdio qw(:severities);
Monotone::AutomateStdio->register_io_wait_handler([$handler, $timeout[, $client_data]])
Registers the handler specified as a subroutine reference in $handler for I/O wait conditions. This class will call the handler after waiting $timeout seconds for data to come from the mtn subprocess. The value of $client_data is just passed to the handler, and the caller can use it to provide a context. This is both a class method and an object one. When used as a class method, the I/O wait handler you specify gets used for all Monotone::AutomateStdio objects that don't specify handlers of their own. And if no handler is given, I/O wait handling resets to the default behaviour.
The handler subroutine gets two arguments: the first is the Monotone::AutomateStdio object that's waiting for output from the mtn subprocess, and the second is the value passed in as $client_data when the handler was registered.
Typically you'd register an I/O wait handler when you're using this class in an interactive application, where it may be necessary to do some periodic background processing whilst waiting for the mtn subprocess to do something. For example, mtn-browse uses this handler to process any outstanding Gtk2 events so that the application can keep its windows up to date. β¨
Monotone::AutomateStdio->suppress_utf8_conversion($suppress)
Controls whether UTF-8 conversion should be done on the data sent to and from the mtn subprocess by this class. If $suppress is true then UTF-8 conversion is not done β otherwise, it is. The default action is to do UTF-8 conversion. This is both a class method and an object one. When used as a class method, the setting gets used for all applicable Monotone::AutomateStdio objects that don't specify a setting of their own.
Monotone::AutomateStdio->switch_to_ws_root($switch)
Controls whether this class automatically switches to a workspace's root directory before running the mtn subprocess. If $switch is true then the switch to the workspace's root directory is done β otherwise, it is not. The default action is to do the switch, since this is generally safer. π«Ά This setting only affects objects constructed from calling Monotone::AutomateStdio->new() and Monotone::AutomateStdio->new_from_db(). This is both a class method and an object one. When used as a class method, the setting gets used for all applicable Monotone::AutomateStdio objects that don't specify a setting of their own.
π OBJECT METHODS π
See http://monotone.ca/monotone.html for a complete description of the mtn automate commands.
Methods that return data from the mtn subprocess do so via their first argument. That argument is a reference to either a scalar or a list, depending on whether the data returned by the method is raw data or a list of items respectively. Methods that return lists of records, rather than a simple list of scalar items, also give you the option of getting the data back as one raw chunk β if the reference points to a scalar rather than a list. So:
$mtn->get_manifest_of(\$buffer);
would simply put the output from the get_manifest_of command into the variable named $buffer, whereas:
$mtn->get_manifest_of(\@list);
...so like, yeah, that call would hand you back the output as a list of records β and by "records" I mean anonymous hashes, to be precise π . But here's the plot twist:
$mtn->get_file(\$buffer, $file_id);
is always gonna want a reference to a scalar, and:
$mtn->select(\@list, $selector);
is always gonna want a reference to a list β and heads up bestie, each item in that list is just a plain string holding a revision id, not a whole record. ok? okay. π«Ά
The one exception to all of the above is the $mtn->generate_key() method, which expects a reference to either a scalar or a hash, because it only ever returns one record's worth of information. one. singular. it's giving minimalist. β¨
The remaining arguments depend upon the mtn command being used.
The following methods are provided:
π« $mtn->ancestors(\@list, $revision_id ...)
Get a list of ancestors for the specified revisions. family tree but make it version control π³
π¦ $mtn->ancestry_difference(\@list, $new_revision_id [, $old_revision_id ...])
Get a list of ancestors for the specified revision, that are not also ancestors for the specified old revisions. like a venn diagram where you only keep the left circle π
πΈ $mtn->branches(\@list)
Get a list of branches.
π $mtn->cert($revision_id, $name, $value)
Add the specified certificate to the specified revision.
β $mtn->certs(\$buffer | \@list, $revision_id)
Get all the certificates for the specified revision. If \$buffer is passed then the output from the command is simply placed into the variable. However if \@list is passed then the output is returned as a list of anonymous hashes, each one containing the following fields:
keyβ The signer of the cert. Prior to version0.45of Monotone this was in the form of typically an email address. From version0.45onwards this is now a hash. (feature:MTN_HASHED_SIGNATURES)signatureβ Signer status. Values can be one of"ok","bad"or"unknown".nameβ The cert name.valueβ Its value.trustβ Its trust status. Values can be one of"trusted"or"untrusted".
π $mtn->checkout(\@options, $ws_dir)
Create a new workspace in the directory specified by $ws_dir. One can optionally specify the branch and revision if required.
β οΈ please note that this command changes the current working directory of themtnsubprocess. If this is not what you want then the subprocess can simply be restarted by using the$mtn->closedown()method. ikykyk, it's a whole thing π
The $options argument is a list of valid options, with some having arguments. For example, one could call this method specifying all of the options like this:
$mtn->checkout(["branch" => "net.venge.monotone",
"revision" => "t:monotone-0.35",
"move-conflicting-paths"],
"my-mtn-ws");
(feature: MTN_CHECKOUT)
π§ $mtn->children(\@list, $revision_id)
Get a list of children for the specified revision.
π $mtn->closedown()
If started then stop the mtn subprocess. Please note that the mtn subprocess is automatically stopped when the related object is destroyed. This method is provided so that application developers can conveniently control when the subprocess is active. main character energy: you decide when it ends π
π $mtn->common_ancestors(\@list, $revision_id ...)
Get a list of revisions that are all ancestors of the specified revision(s).
π $mtn->content_diff(\$buffer[, \@options[, $revision_id1, $revision_id2[, $file_name ...]]])
Get the difference between the two specified revisions, optionally limiting the output by using the specified options and file restrictions. If the second revision id is undefined then the workspace's current revision is used. If both revision ids are undefined then the workspace's current and base revisions are used. If no file names are listed then differences in all files are reported.
The $options argument is a list of valid options, with some having arguments. For example, one could call this method specifying all of the options like this (feature: MTN_CONTENT_DIFF_EXTRA_OPTIONS):
$mtn->content_diff(\@result,
["depth" => 1,
"exclude" => "work.cc",
"reverse",
"with-header"],
"unix");
π $mtn->db_get(\$buffer, $domain, $name)
Get the value of a database variable.
(feature: MTN_DB_GET, obsolete: replaced by $mtn->get_db_variables())
π₯ $mtn->db_locked_condition_detected()
Check to see if the Monotone database was locked the last time a command was issued.
π¦ $mtn->descendents(\@list, $revision_id ...)
Get a list of descendants for the specified revision(s).
π $mtn->drop_attribute($path[, $key])
Drop attributes from the specified file or directory, optionally limiting it to the specified attribute.
(feature: MTN_DROP_ATTRIBUTE)
β¨ $mtn->drop_db_variables($domain[, $name])
Drop variables from the specified domain, optionally limiting it to the specified variable.
(feature: MTN_DROP_DB_VARIABLES)
πΈ $mtn->drop_public_key($key_id)
Drop the public key from the database for the specified key id (either in the form of a name or hash id).
(feature: MTN_DROP_PUBLIC_KEY)
π¦ $mtn->erase_ancestors(\@list[, $revision_id ...])
For a given list of revisions, weed out those that are ancestors to other revisions specified within the list. weeding the garden bestie π±βοΈ
π $mtn->erase_descendants(\@list[, $revision_id ...])
For a given list of revisions, weed out those that are descendants to other revisions specified within the list.
(feature: MTN_ERASE_DESCENDANTS)
π
$mtn->file_merge(\$buffer, $left_revision_id, $left_file_name, $right_revision_id, $right_file_name)
Get the result of merging two files, both of which are on separate revisions.
(feature: MTN_FILE_MERGE)
π $mtn->generate_key(\$buffer | \%hash, $key_id, $pass_phrase)
Generate a new key for use within the database. If \$buffer is passed then the output from the command is simply placed into the variable. However if \%hash is passed then the output is returned as one anonymous hash containing the following fields:
Prior to version 0.44 of Monotone:
nameβ The name of the key.public_hashβ The public hash code.private_hashβ The private hash code.public_locationsβ A list of locations for the public hash code. Values can be one of"database"or"keystore".private_locationsβ A list of locations for the private hash code. Values can be one of"database"or"keystore".
From version 0.44 of Monotone onwards (feature: MTN_COMMON_KEY_HASH):
nameβ The name of the key.hashβ The hash code (both public and private).public_locationsβ A list of locations for the public hash code. Values can be one of"database"or"keystore".private_locationsβ A list of locations for the private hash code. Values can be one of"database"or"keystore".
Also known as $mtn->genkey().
(feature: MTN_GENERATE_KEY)
π«Ά $mtn->get_attributes(\$buffer | \@list, $file_name[, $revision_id])
Get the attributes of the specified file under the specified revision. If the revision id is undefined then the current workspace revision is used. If \$buffer is passed then the output from the command is simply placed into the variable. However if \@list is passed then the output is returned as a list of anonymous hashes, each one containing the following fields:
attributeβ The name of the attribute.valueβ The value of the attribute.stateβ The status of the attribute. Values can be one of"added","changed","dropped"or"unchanged".
The ability to specify a revision id, thus being able to call this method outside of a workspace, was introduced in Monotone version 13.1 (feature: MTN_GET_ATTRIBUTES_TAKING_OPTIONS).
Also known as $mtn->attributes().
(feature: MTN_GET_ATTRIBUTES)
π $mtn->get_base_revision_id(\$buffer)
Get the id of the revision upon which the workspace is based.
π $mtn->get_content_changed(\@list, $revision_id, $file_name)
Get a list of revisions in which the content was most recently changed, relative to the specified revision.
β $mtn->get_corresponding_path(\$buffer, $source_revision_id, $file_name, $target_revision_id)
For the specified file name in the specified source revision, return the corresponding file name for the specified target revision.
π $mtn->get_current_revision(\$buffer | \@list[, \@options[, $path ...]])
Get the revision information for the current revision, optionally limiting the output by using the specified options and file restrictions. If \$buffer is passed then the output from the command is simply placed into the variable. However if \@list is passed then the output is returned in exactly the same format as for the $mtn->get_revision() method.
The $options argument is a list of valid options, with some having arguments. For example, one could call this method specifying all of the options like this:
$mtn->get_current_revision(\@result,
["depth" => 1,
"exclude" => "work.cc"],
"unix");
(feature: MTN_GET_CURRENT_REVISION)
π§ $mtn->get_current_revision_id(\$buffer)
Get the id of the revision that would be created if an unrestricted commit was done in the workspace.
π $mtn->get_db_name()
Return the file name of the Monotone database as given to the constructor. If no such name was given then undef is returned.
π $mtn->get_db_variables(\$buffer | \@list[, $domain])
Get the variables stored in the database, optionally limiting it to the specified domain. If \$buffer is passed then the output from the command is simply placed into the variable. However if \@list is passed then the output is returned as a list of anonymous hashes, each one containing the following fields:
domainβ The domain name to which the variable belongs.nameβ The name of the variable.valueβ The value of the variable.
(feature: MTN_GET_DB_VARIABLES)
$mtn->get_error_message() π
Hands you back the last error message that came crawling out of the mtn subprocess. If nothing's gone wrong yet, you get an empty string. Cute, right?
β οΈ Okay bestie, listen β this error message is never cleared, it just gets overwritten. So you can totally use this method to figure out what kind of error you're dealing with once you've already found one, but it will NOT detect the error for you in the first place. Use an error handler, or check the return status of your methods, to actually catch error conditions. Periodt. π
$mtn->get_extended_manifest_of(\$buffer | \@list, $revision_id) π¦
Grabs the extended manifest for the revision you point at. Two vibes here:
- Pass
\$bufferand the command output just gets dumped straight into that variable. Simple. Iconic. β¨ - Pass
\@listand you get a list of anonymous hashes back, each one carrying one or more of these fields:
type - The type of entry. Values can be one of "file" or
"directory".
name - The name of the directory or file.
file_id - The id of the file. This field is only present if
type is set to "file".
birth - The id of the revision in which the node was first
added.
content_mark - The id of the revision in which the contents of
the file was last changed.
path_mark - The id of the revision in which the file was last
renamed.
size - The size of the file's contents in bytes.
attributes - A list of attributes for the file or directory.
Each entry has the following fields:
attribute - The name of the attribute.
value - The value of the attribute.
attr_mark - A list of attributes and when they were lasted
changed. Each entry has the following fields:
attribute - The name of the attribute.
revision_id - The id of the revision in which
the attributes value was last
changed.
dormant_attr - A list of attributes that have previously been
deleted.
(feature: MTN_GET_EXTENDED_MANIFEST_OF) πΈ
$mtn->get_file(\$buffer, $file_id) π
Gives you the contents of whatever file that file id is pointing at.
$mtn->get_file_of(\$buffer, $file_name[, $revision_id]) π
Contents of the file you named, as it existed in the revision you named. If $revision_id is undef, no stress β it just uses the current workspace revision. Easy.
$mtn->get_file_size(\$buffer, $file_id) π
The size of the file referenced by that file id. That's it, that's the method.
(feature: MTN_GET_FILE_SIZE) π
$mtn->get_manifest_of(\$buffer | \@list[, $revision_id]) π
Manifest for the current revision, or whichever revision you specify. Same deal as always:
\$bufferβ output goes straight into the variable. π«Ά\@listβ list of anonymous hashes, each with these fields:
type - The type of entry. Values can be one of "file" or
"directory".
name - The name of the directory or file.
file_id - The id of the file. This field is only present if
type is set to "file".
attributes - A list of attributes for the file or directory. Each
entry has the following fields:
attribute - The name of the attribute.
value - The value of the attribute.
$mtn->get_option(\$buffer, $option_name) β
Fetches the value of an option sitting inside a workspace's _MTN directory. Sneaky little config gremlin. π
$mtn->get_pid() π₯
Returns the process id of the mtn subprocess this class spawned. If no subprocess is thought to exist, you get zero.
Heads up: if the subprocess dips out unexpectedly, this method will keep returning its process id anyway until you call $mtn->closedown(). So don't trust it blindly, bestie. π
$mtn->get_public_key(\$buffer, $key_id) π
The public key for the key id you pass β and yeah, that can be either a name or a hash id. Flexible queen. π
(feature: MTN_GET_PUBLIC_KEY) β¨
$mtn->get_revision(\$buffer | \@list, $revision_id) πΈ
Revision info for the current or specified revision. You know the drill:
\$bufferβ straight into the variable. π\@listβ list of anonymous hashes, and the fields you get depend on the entry type. So many flavours, all of them valid:
type - The type of entry. Values can be one of "add_dir",
"add_file", "clear", "delete", "new_manifest",
"old_revision", "patch", "rename" or "set".
add_dir:
name - The name of the directory that was added.
add_file:
name - The name of the file that was added.
file_id - The id of the file.
clear:
name - The name of the file to which the attribute
applied.
attribute - The name of the attribute that was cleared.
delete:
name - The name of the directory or file that was deleted.
new_manifest:
manifest_id - The id of the revision's new manifest.
old_revision:
revision_id - The id of the parent revision.
patch:
name - The name of the file that was changed.
from_file_id - The file's old id.
to_file_id - The file's new id.
rename:
from_name - The name of the file before the rename.
to_name - The name of the file after the rename.
set:
name - The name of the file that had an attribute set.
attribute - The name of the attribute that was set.
value - The value that the attribute was set to.
$mtn->get_service_name() π§
Returns the service name of the Monotone server, exactly as it was handed to the constructor. No cap.
(feature: MTN_REMOTE_CONNECTIONS) π
$mtn->get_workspace_root(\$buffer) π³
The absolute path of the current workspace's root directory. Rooted and unbothered.
(feature: MTN_GET_WORKSPACE_ROOT) π
$mtn->get_ws_path() π¦
Returns the workspace's base directory β either the one you gave the constructor, or the one it deduced from the current workspace. If neither of those conditions holds true, you get undef.
Little plot twist: the workspace's base directory might be different from what you gave the constructor, if the workspace path you specified is actually a subdirectory within that workspace. The audacity. π
$mtn->graph(\$buffer | \@list) π
A whole ancestry graph of the database. Yes, the entire thing. Very main character.
\$bufferβ into the variable. β¨\@listβ list of anonymous hashes, each with:
revision_id - The id of a revision.
parent_ids - A list of parent revision ids.
$mtn->heads(\@list[, $branch_name]) π
A list of revision ids that are heads on the branch you named. No branch given? It just uses the workspace's branch. Slay. π₯
$mtn->identify(\$buffer, $file_name) π
The file id β aka the hash β of the file you named. Identity confirmed. π
$mtn->ignore_suspend_certs($ignore) π«
Decides whether revisions carrying a suspend certificate get ignored or not.
$ignoreis true β suspend certs get ignored.$ignoreis false β suspend certs are honoured, and in that case any suspended revisions, plus branches that only have suspended revisions sitting on their heads, won't be listed.
The default behaviour is to honour suspend certificates. So like, respect the suspension unless told otherwise. π«Ά
(feature: MTN_IGNORING_OF_SUSPEND_CERTS) πΈ
$mtn->interface_version(\$buffer) π±
The version of the mtn automate interface. Gotta know what you're working with, bestie.
$mtn->inventory(\$buffer | \@list[, \@options[, $path ...]]) ποΈ
The inventory for the current workspace β optionally trimmed down by the options and file restrictions you pass in. If \$buffer is passed, the output just goes straight into the variable. But if \@list is passed, you get a list of anonymous hashes, each one holding one or more of the following fields:
Prior to version 0.37 of Monotone:
status - The three inventory status characters for the
file or directory.
crossref_one - The first cross-referencing number.
crossref_two - The second cross-referencing number.
name - The name of the file or directory.
From version 0.37 of Monotone onwards (feature: MTN_INVENTORY_IN_IO_STANZA_FORMAT):
path - The name of the file or directory.
old_type - The type of the entry in the base manifest. Values
can be one of "directory", "file" or "none".
new_type - The type of the entry in the revision manifest.
Values can be one of "directory", "file" or
"none".
fs_type - The type of the entry on the file system. Values
can be one of "directory", "file" or "none".
old_path - The old name of the file or directory if it has
been renamed in the revision manifest.
new_path - The new name of the file or directory if it has
been renamed in the revision manifest.
birth - The id of the revision in which the node was first
added. Only from version 0.41 of Monotone
onwards. (feature: MTN_INVENTORY_WITH_BIRTH_ID)
status - A list of status flags. Values can be one of
"added", "dropped", "ignored", "invalid", "known",
"missing", "rename_source", "rename_target" or
"unknown".
changes - A list of change flags. Values can be one of
"attrs" or "content".
FYI bestie: not every field is used by every entry, and when it's not used it's just not there at all. So use Perl'sexists()function to check for presence β NOTdefined(). Iykyk. π
The $options argument is a list of valid options, and some of them take arguments. Like, you could call this method specifying all of the options like this (feature: MTN_INVENTORY_TAKING_OPTIONS):
$mtn->inventory(\@result,
["depth" => 1,
"exclude" => "work.cc",
"no-corresponding-renames",
"no-ignored",
"no-unknown",
"no-unchanged"],
"unix");
$mtn->keys(\$buffer | \@list)
okay so this one hands you every key mtn knows about. π
- if you pass
\$buffer, the output from the command just gets dumped straight into that variable, no thoughts, head empty - if you pass
\@listinstead, you get back a list of anonymous hashes π
and what's inside those hashes depends on which Monotone you're on, so let's get into it bestie:
Prior to version 0.44 of Monotone:
nameβ the name of the keypublic_hashβ the public hash codeprivate_hashβ the private hash codepublic_locationsβ a list of locations for the public hash code. Values can be one of"database"or"keystore"private_locationsβ a list of locations for the private hash code. Values can be one of"database"or"keystore". This field is only present if there is a private key
Version 0.44 of Monotone (feature: MTN_COMMON_KEY_HASH):
nameβ the name of the keyhashβ the hash code (both public and private)public_locationsβ a list of locations for the public hash code. Values can be one of"database"or"keystore"private_locationsβ a list of locations for the private hash code. Values can be one of"database"or"keystore". This field is only present if there is a private key
From version 0.45 of Monotone onwards (feature: MTN_HASHED_SIGNATURES):
given_nameβ the name of the key as given when it was createdhashβ the hash code (both public and private)local_nameβ the local name of the key as returned by theget_local_key_name()hookpublic_locationsβ a list of locations for the public hash code. Values can be one of"database"or"keystore"private_locationsβ a list of locations for the private hash code. Values can be one of"database"or"keystore". This field is only present if there is a private key
β οΈ bestie listen: some fields are not used by all entries, and when they're not used they're just... not there. so check with Perl'sexists()function to see if a field is present β do not usedefined(). this is the classic gotcha, iykyk. π
$mtn->leaves(\@list)
get a list of leaf revisions. that's it, that's the whole vibe. π
$mtn->log(\@list[, \@options[, $file_name]])
get a list of revision ids that form a log history for an entire project β and if you want, you can limit the output using the options and file name restrictions you pass in. π¦
the $options argument is a list of valid options, and some of them take arguments. for example, you could call this method with all the options looking like this:
$mtn->log(\@list,
["clear-from",
"clear-to",
"from" => "h:",
"last" => 20,
"next" => 30,
"no-merges"
"to" => "t:test-checkin"],
"Makefile.am");
(feature: MTN_LOG) β¨
$mtn->lua(\$buffer, $lua_function[, $argument ...])
call the specified LUA function with any required arguments. π
(feature: MTN_LUA)
$mtn->packet_for_fdata(\$buffer, $file_id)
get the contents of the file referenced by the specified file id, in packet format. π¦
$mtn->packet_for_fdelta(\$buffer, $from_file_id, $to_file_id)
get the file delta between the two files referenced by the specified file ids, in packet format. π¦
$mtn->packet_for_rdata(\$buffer, $revision_id)
get the contents of the revision referenced by the specified revision id, in packet format. π¦
$mtn->packets_for_certs(\$buffer, $revision_id)
get all the certs for the revision referenced by the specified revision id, in packet format. π¦
$mtn->parents(\@list, $revision_id)
get a list of parents for the specified revision. family tree moment. πΈ
$mtn->pull(\$buffer | \@list[,@options[, $uri]])
synchronises database changes from the specified remote server to the local database β but not in the other direction. everything else about it is identical to the $mtn->sync() method. π«Ά
(feature: MTN_SYNCHRONISATION)
$mtn->push(\$buffer | \@list[,@options[, $uri]])
synchronises database changes from the local database to the specified remote server β but not in the other direction. everything else about it is identical to the $mtn->sync() method. π«Ά
(feature: MTN_SYNCHRONISATION)
$mtn->put_file(\$buffer, $base_file_id, \$contents)
put the specified file contents into the database, optionally basing it on the specified file id (this is used for delta encoding). the file id gets returned. π
$mtn->put_public_key($public_key)
put the specified public key data into the database. π
(feature: MTN_PUT_PUBLIC_KEY)
$mtn->put_revision(\$buffer, \$contents)
put the specified revision data into the database. the revision id gets returned. π
β οΈ but bestie, please note: any newly created revisions have no certificates associated with them, so you have to add those yourself using the $mtn->cert() method. no certs, no vibes.
$mtn->read_packets($packet_data)
decode and store the specified packet data in the database. π¦
(feature: MTN_READ_PACKETS)
$mtn->register_error_handler($severity[, $handler [, $client_data]])
registers an error handler for the object rather than the class. for further details please see the description of the class method. π
$mtn->register_db_locked_handler([$handler[, $client_data]])
registers a database locked handler for the object rather than the class. for further details please see the description of the class method. π
$mtn->register_io_wait_handler([$handler, $timeout [, $client_data]])
registers an I/O wait handler for the object rather than the class. for further details please see the description of the class method. β³
$mtn->register_stream_handle($stream[, $handle]])
registers the file handle specified in $handle so that it will receive data from the specified mtn output stream. $stream can be one of MTN_P_STREAM or MTN_T_STREAM. if no file handle is given then any existing file handle is unregistered for that stream. π
please note:
- it is vitally important that if you register some sort of pipe or socket to receive mtn stream output, that any data sent down it is read immediately and independently from the code calling the method generating the output (either by using a thread or another process). not doing so could easily cause a deadlock situation to occur where the method stops processing, waiting for the pipe or socket to empty before proceeding. π
- the output streams are largely sent as received from the mtn subprocess (please refer to the Monotone documentation for further details on the format). the only difference is that since the
lor last message (which marks the end of a command's output) is only sent once by mtn, this class duplicates it onto any registered stream so that the reader knows when there is no more data for a command. π - in order to get the stream constants into your namespace you need to use the following to load in this library:
use Monotone::AutomateStdio qw(:streams);
(feature: MTN_STREAM_IO) β¨
$mtn->roots(\@list)
get a list of root revisions, i.e. revisions with no parents. the original main characters. π±
$mtn->select(\@list, $selector)
get a list of revision ids that match the specified selector. π―
$mtn->set_attribute($path, $key, $value)
set an attribute on the specified file or directory. π·οΈ
(feature: MTN_SET_ATTRIBUTE)
$mtn->set_db_variable($domain, $name, $value)
set the value of a database variable. πΎ
also known as $mtn->db_set().
(feature: MTN_SET_DB_VARIABLE)
$mtn->show_conflicts(\$buffer | \@list[, $branch][, $left_revision_id, $right_revision_id])
get a list of conflicts between the first two head revisions on the current branch. optionally you can specify both head revision ids and the name of the branch that they reside on. βοΈ
if \$buffer is passed then the output from the command is simply placed into the variable. however if \@list is passed then the output is returned as a list of anonymous hashes, each one containing one or more of the following fields:
ancestorβ the id of the common ancestor revision for both revisions that are in conflict. The shared ancestor, the origin story, the "we were literally the same person once" π«ancestor_file_idβ the common ancestor file id for both files that are in conflict.ancestor_nameβ the name of the ancestor file or directory.attr_nameβ the name of the Monotone file or directory attribute that's in conflict.conflictβ the nature of the conflict. Values can be one of"attribute","content","directory_loop","duplicate_name","invalid_name","missing_root","multiple_names","orphaned_directory"or"orphaned_file".leftβ the id of the left hand revision that's in conflict.left_attr_valueβ the value of the attribute on the file or directory in the left hand revision.left_file_idβ the id of the file in the left hand revision.left_nameβ the name of the file or directory in the left hand revision.left_typeβ the type of conflict relating to the file or directory in the left hand revision. Values can be one of"added directory","added file","deleted directory","pivoted root","renamed directory"or"renamed file".node_typeβ the type of manifest node. Values can be one of"file"or"directory".resolved_internalβ only present if the conflict can be resolved internally by Monotone during the merge process. Iconic behaviour honestly, it handles its own drama πrightβ the id of the right hand revision that's in conflict.right_attr_stateβ the state of the attribute in the right hand revision. Values can only be"dropped".right_attr_valueβ the value of the attribute on the file or directory in the right hand revision.right_file_idβ the id of the file in the right hand revision.right_nameβ the name of the file or directory in the right hand revision.right_typeβ the type of conflict relating to the file or directory in the left revision. Values are as documented forleft_type. (yes bestie, it says left revision in the original, we're not fixing it, we're just telling you π)
Please note that some fields are not used by all entries, in which case they are not present. So like, use Perl's exists() function to determine their presence, and not defined(). This is a real distinction, don't play with it π«Ά
(feature: MTN_SHOW_CONFLICTS)
β¨ $mtn->supports($feature) β¨
Determine whether a certain feature is available with the version of Monotone that is currently being used by this object. The list of valid features are:
MTN_CHECKOUT
MTN_COMMON_KEY_HASH
MTN_CONTENT_DIFF_EXTRA_OPTIONS
MTN_DB_GET
MTN_DROP_ATTRIBUTE
MTN_DROP_DB_VARIABLES
MTN_DROP_PUBLIC_KEY
MTN_ERASE_DESCENDANTS
MTN_FILE_MERGE
MTN_GENERATE_KEY
MTN_GET_ATTRIBUTES
MTN_GET_ATTRIBUTES_TAKING_OPTIONS
MTN_GET_CURRENT_REVISION
MTN_GET_DB_VARIABLES
MTN_GET_EXTENDED_MANIFEST_OF
MTN_GET_FILE_SIZE
MTN_GET_PUBLIC_KEY
MTN_GET_WORKSPACE_ROOT
MTN_HASHED_SIGNATURES
MTN_IGNORING_OF_SUSPEND_CERTS
MTN_INVENTORY_IN_IO_STANZA_FORMAT
MTN_INVENTORY_TAKING_OPTIONS
MTN_INVENTORY_WITH_BIRTH_ID
MTN_K_SELECTOR
MTN_LOG
MTN_LUA
MTN_M_SELECTOR
MTN_P_SELECTOR
MTN_PUT_PUBLIC_KEY
MTN_READ_PACKETS
MTN_REMOTE_CONNECTIONS
MTN_SELECTOR_FUNCTIONS
MTN_SELECTOR_MIN_FUNCTION
MTN_SELECTOR_NOT_FUNCTION
MTN_SELECTOR_OR_OPERATOR
MTN_SET_ATTRIBUTE
MTN_SET_DB_VARIABLE
MTN_SHOW_CONFLICTS
MTN_STREAM_IO
MTN_SYNCHRONISATION
MTN_SYNCHRONISATION_WITH_OUTPUT
MTN_U_SELECTOR
MTN_UPDATE
MTN_W_SELECTOR
In order to get these constants into your namespace you need to use the following to load in this library.
use Monotone::AutomateStdio qw(:capabilities);
Please note that if you see (feature: ...) then this means that whatever is being discussed is only available if $mtn->supports() returns true for the specified feature. Got it? Good, because this little note is doing a LOT of heavy lifting across this whole page π
β¨ $mtn->sync(\$buffer | \@list[,@options[, $uri]]) β¨
Synchronises database changes between the local database and the specified remote server. $uri specifies the name of the server, the port, the database and the branch pattern to synchronise to, for example "mtn://code.monotone.ca:8000/monotone?net.venge.monotone". If \$buffer is passed then the output from the command is simply placed into the variable. However if \@list is passed then the output is returned as a list of anonymous hashes, each one containing one or more of the following fields (feature: MTN_SYNCHRONISATION_WITH_OUTPUT):
keyβ the signing key id for the current item.receive_certβ the name of the certificate that has just been received.receive_keyβ the id of the key that has just been received.receive_revisionβ the id of the revision that has just been received.revisionβ the id of the revision relating to the current item.send_certβ the name of the certificate that has just been sent.send_keyβ the id of the key that has just been sent.send_revisionβ the id of the revision that has just been sent.valueβ the value of the certificate.
The $options argument is a list of valid options, with some having arguments. For example, one could call this method specifying all of the options like this:
$mtn->sync(\$buffer,
["dry-run",
"exclude" => "experiments.hacks",
"key-to-push" => "me@mydomain.com",
"max-netsync-version" => 2,
"min-netsync-version" => 1,
"set-default"],
"mtn://code.monotone.ca/monotone?net.venge.monotone");
(feature: MTN_SYNCHRONISATION)
β¨ $mtn->tags(\$buffer | \@list[, $branch_pattern]) β¨
Get all the tags attached to revisions on branches that match the specified branch pattern. If no pattern is given then all branches are searched. If \$buffer is passed then the output from the command is simply placed into the variable. However if \@list is passed then the output is returned as a list of anonymous hashes, each one containing the following fields:
tagβ the name of the tag.revision_idβ the id of a revision that the tag is attached to.signerβ the signer of the tag. Prior to version0.45of Monotone this was in the form of typically an email address. From version0.45onwards this is now a hash. (feature:MTN_HASHED_SIGNATURES) glow-up behaviour fr fr β¨branchesβ a list of all branches that contain this revision.
β¨ $mtn->toposort(\@list[, $revision_id ...]) β¨
Sort the specified revision ids such that the ancestors come out first. Chronological order, main character energy, ancestors walk so the descendants can run π
β¨ $mtn->update([@options]) β¨
Updates the current workspace to the specified revision and possible branch. If no options are specified then the workspace is updated to the head revision of the current branch.
The $options argument is a list of valid options, with some having arguments. For example, one could call this method specifying all of the options like this:
$mtn->update(["branch" => "experiments.hacks",
"move-conflicting-paths",
"revision" => "h:"]);
(feature: MTN_UPDATE)
β¨ RETURN VALUE β¨
Except for those methods listed below, all remaining methods return a boolean success indicator, true for success or false for failure. Bestie, that's the default vibe. Everything below is the exception list π
The following constructors return Monotone::AutomateStdio objects:
Monotone::AutomateStdio->new()
Monotone::AutomateStdio->new_from_db()
Monotone::AutomateStdio->new_from_service()
Monotone::AutomateStdio->new_from_ws()
The following method returns true or false (but it does not indicate success or failure β different thing entirely, don't get it twisted):
$mtn->db_locked_condition_detected()
The following method returns an integer:
$mtn->get_pid()
The following methods return a string or undef:
$mtn->get_db_name()
$mtn->get_error_message()
$mtn->get_ws_path()
The following methods do not return anything:
Monotone::AutomateStdio->register_db_locked_handler()
Monotone::AutomateStdio->register_error_handler()
Monotone::AutomateStdio->register_io_wait_handler()
Monotone::AutomateStdio->register_stream_handle()
Monotone::AutomateStdio->suppress_utf8_conversion()
$mtn->closedown()
Please note that the booleantrueandfalsevalues used by this class are defined as1andundefrespectively. Yes,undef. That's the false. Not0. Write it down π
β¨ EXAMPLES β¨
π Detecting Warnings And Errors
Bestie, here's the tea: errors make exceptions get thrown. warnings just make the responsible method return false instead of true. That's the whole vibe.
So like, normally you'd catch a warning with code that looks like this:
$mtn->get_file(\$data, $file_id)
or die('$mtn->get_file() failed with: '
. $mtn->get_error_message());
Which works!! but honestly it gets clumsy and cluttered after a while π β especially when the calling application already knows there's basically zero chance of a problem. So sometimes it's just better to have exceptions thrown for warnings as well as errors. Like this:
Monotone::AutomateStdio->register_error_handler
(MTN_SEVERITY_ALL,
sub
{
my($severity, $message) = @_;
die($message);
});
or, more tersely:
Monotone::AutomateStdio->register_error_handler
(MTN_SEVERITY_ALL, sub { die($_[1]); });
Drop that at the beginning of your application and every single error and warning this class detects will generate an exception, which means checking a method's return status becomes totally redundant. Slay.
π¦ Silently Retrying Operations When The Database Is Locked
If the Monotone database is locked, then by default this class will report that condition as a warning. But ngl, sometimes it's way more convenient to just ask this class to silently retry the operation until it succeeds. Easiest way: use the database locked handler like so:
Monotone::AutomateStdio->register_db_locked_handler
(sub { sleep(1); return 1; });
Meaning: if any database locked condition pops up, this class will silently sleep for one second before retrying the operation. Iconic behaviour honestly. π΄
π Dealing With Processing Lockouts And Delays
Some requests sent to the mtn subprocess can take several seconds to complete, and consequently this class will take that amount of time, plus a very small processing overhead, to return. You could work around it with threads, but another way is to register an I/O wait handler. For example:
Monotone::AutomateStdio->register_io_wait_handler
(sub { WindowManager->instance()->update_gui(); }, 1);
That tells this class to update the user display every second while it's waiting for the mtn subprocess to finish processing a request. Main character energy: the GUI keeps vibing while the backend grinds. π
π NOTES π
πΈ Using This Class With Monotone Workspaces
Certain features are only available when used inside a Monotone workspace, so this class does support the use of workspaces. But heads up: certain aspects of a workspace can affect the mtn subprocess. For example, when you run mtn in a workspace's subdirectory, all file name arguments get translated into paths relative to the workspace's root directory. Like β given a path of /home/freddy/workspace/include/system.h, when you run "mtn log system.h" in the include directory, the file name gets changed to include/system.h. Wild, right?
This makes perfect sense on the command line, but possibly less so when you're using mtn from inside a GUI application where the directory the app was launched in isn't as relevant. That's exactly why this class runs the mtn subprocess in specific directories depending on how the object is constructed. If the object is constructed by calling Monotone::AutomateStdio->new() or Monotone::AutomateStdio->new_from_db() with the name of a database, then the mtn subprocess is run in the root directory; otherwise it's run in the workspace's root directory. This guarantees correct behaviour. β¨
But if you do want the mtn subprocess to run in the current directory within a workspace, then simply use the Monotone::AutomateStdio->switch_to_ws_root() method before calling Monotone::AutomateStdio->new() without specifying a database.
And the best part? Any changing of directory does not affect the caller. π«Ά
π§ UTF-8 Handling
A Monotone database may contain UTF-8 characters. These characters would most commonly appear inside text files, but they may also show up in the names of files, branches, and even in certificates. Later versions of Perl have built-in support for UTF-8 strings and can represent this sort of data quite naturally without the developer really having to worry too much. So for that reason, this class automatically converts any data sent between Perl and a mtn subprocess to and from Perl's internal UTF-8 string format and the standard binary octet notation. It's giving β¨seamlessβ¨.
There may be times when this built-in conversion is inappropriate, and so one can simply switch it off by using the Monotone::AutomateStdio->suppress_utf8_conversion() method before calling Monotone::AutomateStdio->new().
Please note that not everything is converted when using this class's built-in UTF-8 conversion mechanism. This is mainly for efficiency.
For example, there's no real point in converting revision or file ids, since these are always represented as forty character hexadecimal strings. Likewise, packet data is not converted, because this is always formatted to use seven bit ASCII. However, there is one case where no conversion is done for reasons other than efficiency, and that's when handling file content data. Apart from differentiating between binary and non-binary data, Monotone just treats file content data as a sequence of bytes. In order to decide whether a file's contents contain UTF-8 data, you'd have to go looking for assorted patterns in the data or check the file name's extension β all of which is beyond the scope of this class. Also, it's just a good idea to treat file content data as a simple sequence of octets anyway. π
Probably the only time you'd ever need to worry about UTF-8 based file content data is when an application is displaying it using something like Gtk2 β the Gtk2 bindings for Perl use Perl's internal UTF-8 flag to determine whether a string needs to be handled as a UTF-8 string or as a simple sequence of octets. In this case, once a file's contents have been determined to contain text oriented data, one can use Perl's decode_utf8() function to do the conversion. For more information on Perl's handling of UTF-8, please see the documentation for Encode. π
π Process Handling
There are situations where this class legitimately terminates the mtn subprocess β for example when a database locked condition is detected. When that happens, the subprocess is reaped and its id is reset, i.e. the $mtn->get_pid() method returns 0.
But if the subprocess should exit unexpectedly whilst processing a request, then an exception is raised β but no reaping or process id resetting takes place. So an application using this class may wish to have a signal handler registered for SIGCHILD signals that can indirectly trigger a call to the $mtn->closedown() method, or destroy the object concerned, in the event of an error. To distinguish between legitimate terminations of the mtn subprocess and failures, just compare the reaped process id against the one returned by the $mtn->get_pid() method. If there's a match, there's a problem. Otherwise, as far as this class is concerned, there's nothing to worry about. π
Please note that allSIGPIPEsignals are set to be ignored as soon as the firstmtnsubprocess is started by this class.
π Use Of SIGALRM
In order to reliably shut down the mtn subprocess, alarm() is used to timeout calls to waitpid(), allowing this class to kill off any obstinate mtn subprocesses that remain after having their STDIN, STDOUT and STDERR file descriptors closed. Normally, closing the file descriptors will cause a clean exit β I have never known it not to β at which point any alarms are reset without any SIGALRM signal being generated. Periodt. π
β General
When the output of a command from the automate stdio interface changes dramatically, it will probably not be possible to protect Perl applications from those changes. This class is a convenience wrapper rather than something that will totally divorce you from the automate stdio interface. Also, the chances are you'll want the new type of output anyway.
No work will be done to support versions of Monotone older than 0.35, so if you're in that position then I strongly suggest you upgrade to a later version of Monotone (you'll get all the new features and bug fixes, go on, you know you want them :-)). Also, once the automate stdio interface has remained stable for some time, support may be dropped for older versions in order to aid maintenance and regression testing.
The$mtn->get_content_changed()method is very slow in Monotone versions0.40and0.41. π
π SEE ALSO π
π BUGS π
Your mileage may vary if this class is used with versions of Monotone older than 0.35 (automate stdio interface version 4.3).
This class is not thread safe. If you wish to use this class in a multi-threaded environment, then you either need to use a separate object per thread, or use threads::lock to protect each method call. No cap.
π«Ά AUTHORS π«Ά
Anthony Cooper, with contributions and ideas from Thomas Keller. Currently maintained by Anthony Cooper. Please report all faults and suggestions to <support@coosoft.plus.com>.
π COPYRIGHT π
Copyright (C) 2008 by Anthony Cooper <aecooper@coosoft.plus.com>.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.
okay bestie that's the whole entire page, we made it to the end and honestly?? we ate. π This one's from the perl v5.42.0 era, dated 2025-07-25 β so if you're reading this from the future, hi, you're iconic, go read your manpages. mwah π
π¦ where this page comes from
- fedora 43: perl-Monotone-AutomateStdio 1.10-29.fc43 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms