lib/docker_compose/parser.rb
# frozen_string_literal: true
module DockerCompose
class Parser
# Public: Parse the docker-compose output and get the services
#
# output - The String output results from `docker-compose ps`
#
# Examples:
#
# output = `docker-compose ps`
# pp output
#
# " Name Command State Ports \n" +
# "---------------------------------------------------------------------------------------------------------------------\n" +
# "classroom_memcached docker-entrypoint.sh memcached Up 127.0.0.1:22322->11211/tcp \n" +
# "classroom_postgresql /docker-entrypoint.sh postgres Up 127.0.0.1:2345->5432/tcp \n" +
# "classroom_redis docker-entrypoint.sh redis ... Up 127.0.0.1:9736->6379/tcp \n"
#
# DockerCompose::Parser.parse(output)
# # => #<DockerCompose::Services:0x00007fddea842ef0
# @services=
# [#<DockerCompose::Service:0x00007fddea842c48
# @command="docker-entrypoint.sh postgres",
# @name="classroom_postgresql",
# @ports="127.0.0.1:2345->5432/tcp",
# @state="Up">]>
#
#
# Returns an instance of DockerCompose::Services.
def self.parse(output)
services = DockerCompose::Services.new
output.split("\n")[2..-1].map do |service|
services << DockerCompose::Service.new(**service_attributes(service))
end
services
end
def self.service_attributes(service)
attributes = service.split(" ")
# Grab everything that starts with a number
# which I'm going to assume is a port.
ports = []
while attributes[-1] && attributes[-1][0].match?(/\d/)
ports.unshift(attributes[-1])
attributes.pop
end
state = attributes.pop
name = attributes.shift
command = attributes.join(" ")
{ name: name, command: command, state: state, ports: ports.join(" ").to_s }
end
private_class_method :service_attributes
end
end