<commit_before>require 'base64'

module Awful
  module Short
    def ec2(*args)
      Awful::Ec2.new.invoke(*args)
    end
  end

  class Ec2 < Cli

    COLORS = {
      running:    :green,
      stopped:    :yellow,
      terminated: :red,
    }

    no_commands do
      def color(string)
        set_color(string, COLORS.fetch(string.to_sym, :yellow))
      end
    end

    desc 'ls [NAME]', 'get instances with given name regex'
    method_option :long,        aliases: '-l', type: :boolean, default: false, desc: 'Long listing'
    method_option :ids,         aliases: '-i', type: :array,   default: [],    desc: 'List of instance ids to retrieve'
    method_option :tags,        aliases: '-t', type: :array,   default: [],    desc: 'List of tags to filter, as key:value'
    method_option :stack,       aliases: '-s', type: :string,  default: nil,   desc: 'Filter by given stack'
    method_option :resource,    aliases: '-r', type: :string,  default: nil,   desc: 'Filter by given stack resource logical id'
    method_option :autoscaling, aliases: '-a', type: :string,  default: nil,   desc: 'Filter by given autoscaling group'
    def ls(name = nil)
      params = {instance_ids: [], filters: []}

      ## filter by ids
      options[:ids].each do |id|
        params[:instance_ids] << id
      end

      ## filter by arbitrary tags
      options[:tags].each do |tag|
        key, value = tag.split(/[:=]/)
        params[:filters] << {name: "tag:#{key}", values: [value]}
      end

      ## filter shortcuts for stack, resource, autoscaling group
      params[:filters] << {name: 'tag:aws:cloudformation:stack-name', values: [options[:stack]]}       if options[:stack]
      params[:filters] << {name: 'tag:aws:cloudformation:logical-id', values: [options[:resource]]}    if options[:resource]
      params[:filters] << {name: 'tag:aws:autoscaling:groupName',     values: [options[:autoscaling]]} if options[:autoscaling]

      ## get list of instances
      instances = ec2.describe_instances(params.reject{ |k,v| v.empty? }).reservations.map(&:instances).flatten

      ## filter by Name tag as a regex
      instances.select! { |i| tag_name(i, '').match(name) } if name

      ## output
      instances.tap do |list|
        if options[:long]
          print_table list.map { |i|
            [
              tag_name(i, ''),
              i.instance_id,
              i.instance_type,
              i.image_id,
              i.placement.availability_zone,
              color(i.state.name),
              i.security_groups.map(&:group_name).join(',').slice(0..30),
              i.private_ip_address,
              i.public_ip_address
            ]
          }.sort_by(&:first)
        else
          puts list.map(&:instance_id)
        end
      end<commit_msg>add state flag to ls<commit_after>require 'base64'

module Awful
  module Short
    def ec2(*args)
      Awful::Ec2.new.invoke(*args)
    end
  end

  class Ec2 < Cli

    COLORS = {
      running:    :green,
      stopped:    :yellow,
      terminated: :red,
    }

    no_commands do
      def color(string)
        set_color(string, COLORS.fetch(string.to_sym, :yellow))
      end
    end

    desc 'ls [NAME]', 'get instances with given name regex'
    method_option :long,        aliases: '-l', type: :boolean, default: false, desc: 'Long listing'
    method_option :ids,         aliases: '-i', type: :array,   default: [],    desc: 'List of instance ids to retrieve'
    method_option :tags,        aliases: '-t', type: :array,   default: [],    desc: 'List of tags to filter, as key:value'
    method_option :stack,       aliases: '-s', type: :string,  default: nil,   desc: 'Filter by given stack'
    method_option :resource,    aliases: '-r', type: :string,  default: nil,   desc: 'Filter by given stack resource logical id'
    method_option :autoscaling, aliases: '-a', type: :string,  default: nil,   desc: 'Filter by given autoscaling group'
    method_option :state,       aliases: '-S', type: :string,  default: nil,   desc: 'Filter by given state name'
    def ls(name = nil)
      params = {instance_ids: [], filters: []}

      ## filter by ids
      options[:ids].each do |id|
        params[:instance_ids] << id
      end

      ## filter by arbitrary tags
      options[:tags].each do |tag|
        key, value = tag.split(/[:=]/)
        params[:filters] << {name: "tag:#{key}", values: [value]}
      end

      ## filter shortcuts for stack, resource, autoscaling group
      params[:filters] << {name: 'tag:aws:cloudformation:stack-name', values: [options[:stack]]}       if options[:stack]
      params[:filters] << {name: 'tag:aws:cloudformation:logical-id', values: [options[:resource]]}    if options[:resource]
      params[:filters] << {name: 'tag:aws:autoscaling:groupName',     values: [options[:autoscaling]]} if options[:autoscaling]
      params[:filters] << {name: 'instance-state-name',               values: [options[:state]]}       if options[:state]

      ## get list of instances
      instances = ec2.describe_instances(params.reject{ |k,v| v.empty? }).reservations.map(&:instances).flatten

      ## filter by Name tag as a regex
      instances.select! { |i| tag_name(i, '').match(name) } if name

      ## output
      instances.tap do |list|
        if options[:long]
          print_table list.map { |i|
            [
              tag_name(i, ''),
              i.instance_id,
              i.instance_type,
              i.image_id,
              i.placement.availability_zone,
              color(i.state.name),
              i.security_groups.map(&:group_name).join(',').slice(0..30),
              i.private_ip_address,
              i.public_ip_address
            ]
          }.sort_by(&:first)
        else
          puts list.map(&:instance_id)
        end
      end
{'fraction_non_alphanumeric': 0.1383290267011197, 'fraction_numerical': 0.0031007751937984496, 'mean_word_length': 2.3933372296902395, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3049351', 'n_tokens_mistral': 1819, 'n_tokens_neox': 1771, 'n_words': 478}