diff --git a/README.md b/README.md index 012a22d..3bbd5f5 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,6 @@ As an example, the generated profile could look like this: "Jumpstations", "tag with spaces" ], - "Custom Command": "Yes", "Command": "ssh bastion" } ``` @@ -118,16 +117,27 @@ With regular profiles this is impossible. As soon as you duplicate it it is no l ### CustomCommand -"`Yes`" to configure a custom command to execute via the `Command` keyword. If no `CustomCommand` option is found, an `ssh ` custom command will be automatically added for you. +"`Yes`" to configure a custom command to execute via the `Command` keyword. You can just specify a `Command` though, `Custom Command` will automatically be added. ### Command -See above, the actual command to execute if you want to specify your own. (`CustomCommand` is not automatically added at this point, so make sure to add it yourself) +Related to above, but the actual command to execute if you want to specify your own. `CustomCommand` is automatically added if you specify a command, so adding that is optional. +If no `CustomCommand` option is found after the processing of the Host, an `ssh ` custom command will be automatically added for you. ### Tags A space-separated list of tags for the profile. Spaces within tags are supported by double-quoting them ("*tag with spaces*"). +### Trigger + +Can contain the JSON to define a trigger. This can be specified multiple times (one per trigger). +The easiest way to obtain the syntax is to define them manually in iTerm2 and then use "Copy Profile as JSON" under "Other Actions..." to extract it. +Just specify it as a one liner to use (example is to open the password manager): + +``` +# Trigger {"partial": true, "parameter": "client\/hostname\/username", "regex": "assword:", "action" : "PasswordTrigger"} +``` + ## Command Line Arguments An overview of the command line arguments. The default behavior is to use `~/.ssh/config` and write the resulting json will to the screen. diff --git a/src/Console/GenerateProfiles.php b/src/Console/GenerateProfiles.php index da783c3..1a38853 100644 --- a/src/Console/GenerateProfiles.php +++ b/src/Console/GenerateProfiles.php @@ -133,7 +133,7 @@ private function getCallbacks(InputInterface $input): array $callbacks = [ // If no custom command was specified add one. We can safely assume all hosts are SSH hosts I think... // Note that if the first pattern is a wildcard pattern, this won't work - 'CustomCommand' => function($profile, $host, $array) { + 'CustomCommand' => function($array, $host) { if (!array_key_exists('Command', $array)) { // Use the first pattern to connect instead of hostname (on the chance that hostname is not a part of // the config section and will not be assigned the correct options by ssh) @@ -147,7 +147,7 @@ private function getCallbacks(InputInterface $input): array ]; if ($input->getOption('bind')) { - $callbacks['BoundHosts'] = function($profile, $host, $array) { + $callbacks['BoundHosts'] = function($array, $host) { $array['Bound Hosts'] = $host->get('Host')->value; if ($hostname = $host->get('Hostname')) { $array['Bound Hosts'][] = $hostname->valueString; @@ -159,7 +159,7 @@ private function getCallbacks(InputInterface $input): array if ($autoTags = $input->getOption('autotag')) { $autoTags = new Line('AutoTag ' . $autoTags); - $callbacks['AutoTag'] = function($profile, $host, $array) use ($autoTags) { + $callbacks['AutoTag'] = function($array, $host) use ($autoTags) { $tags = array_key_exists('Tags', $array) ? $array['Tags'] : []; // Assemble substitutes diff --git a/src/DynamicProfiles/Profile.php b/src/DynamicProfiles/Profile.php index e281b13..7e3ebba 100644 --- a/src/DynamicProfiles/Profile.php +++ b/src/DynamicProfiles/Profile.php @@ -21,27 +21,29 @@ public function __construct(string $pattern, Host $host, string $guid = null) public function asArray($options, $extraCallbacks = []) { $profile = [ - 'Name' => $this->name(), + 'Name' => $name = $this->name(), 'Guid' => $this->guid(), ]; foreach ($options as $keyword => $action) { - $line = $this->host->get($keyword); - if ($line) { + $lines = $this->host->get($keyword, [], true); + foreach ($lines as $line) { if ($action === false) { continue; } if (\is_string($action)) { $profile[$action] = $line->valueString; + } elseif (\is_callable($action)) { + $profile = $action($profile, $line, $this->host, $this); } - elseif (\is_callable($action)) { - $profile = $action($this, $this->host, $profile); + if (!\is_array($profile)) { + throw new \RuntimeException("Processing keyword '$keyword' for host '$name' did not result in an array"); } } } foreach ($extraCallbacks as $callback) { - $profile = $callback($this, $this->host, $profile); + $profile = $callback($profile, $this->host, $this); } return $profile; diff --git a/src/DynamicProfiles/options.php b/src/DynamicProfiles/options.php index 0568ff5..9acd7af 100644 --- a/src/DynamicProfiles/options.php +++ b/src/DynamicProfiles/options.php @@ -15,12 +15,30 @@ 'Badge' => 'Badge Text', 'ParentProfile' => 'Dynamic Profile Parent Name', 'CustomCommand' => 'Custom Command', - 'Command' => 'Command', - 'Tags' => function($profile, $host, $array) { - $tags = $host->get('tags'); + 'Command' => function($array, $line) { + $command = $line->firstValue; + if ($command) { + if (!array_key_exists('Custom Command', $array)) { + $array['Custom Command'] = 'Yes'; + } + $array['Command'] = $command; + } + return $array; + }, + 'Tags' => function($array, $tags) { if ($tags && \count($tags->value)) { $array['Tags'] = $tags->value; } return $array; }, + 'Trigger' => function($array, $line) { + $trigger = json_decode($line->valueString, true); + if ($trigger) { + if (!array_key_exists('Triggers', $array)) { + $array['Triggers'] = []; + } + $array['Triggers'][] = $trigger; + } + return $array; + } ]; \ No newline at end of file diff --git a/src/SSH/Host.php b/src/SSH/Host.php index 5269d95..95c07b7 100644 --- a/src/SSH/Host.php +++ b/src/SSH/Host.php @@ -59,17 +59,23 @@ public function __set($name, $value) } } - public function get($name, $default = null) + public function get($name, $default = null, $supportMultiple = false) { if (\in_array($name, ['patterns', 'commentValues', 'file'])) { return $this->$name; } + $lines = []; foreach ($this->lines as $line) { if ($line->is($name)) { - return $line; + $lines[] = $line; } } + + if (\count($lines)) { + return $supportMultiple ? $lines : reset($lines); + } + return $default; }