def pre_process(control)
      Engine.logger.debug "Pre-processing #{control.file}"
      control.pre_processors.each do |processor|
        processor.process
      end
      Engine.logger.debug "Pre-processing complete"
    end

def
pre_process
(
control
)
Engine
.
logger
.
debug
"Pre-processing #{control.file}"
control
.
pre_processors
.
each
do
|
processor
|
processor
.
process
end
Engine
.
logger
.
debug
"Pre-processing complete"
end


def post_process(control)
      say_on_own_line "Executing post processes"
      Engine.logger.debug "Post-processing #{control.file}"
      control.post_processors.each do |processor|
        processor.process
      end
      Engine.logger.debug "Post-processing complete"
      say "Post-processing complete"
    end

def
post_process
(
control
)
say_on_own_line
"Executing post processes"
Engine
.
logger
.
debug
"Post-processing #{control.file}"
control
.
post_processors
.
each
do
|
processor
|
processor
.
process
end
Engine
.
logger
.
debug
"Post-processing complete"
say
"Post-processing complete"
end


def execute_dependencies(control)
      Engine.logger.debug "Executing dependencies"
      control.dependencies.flatten.each do |dependency|
        case dependency
        when Symbol
          f = dependency.to_s + '.ctl'
          Engine.logger.debug "Executing dependency: #{f}"
          say "Executing dependency: #{f}"
          process(f)
        when String
          Engine.logger.debug "Executing dependency: #{f}"
          say "Executing dependency: #{f}"
          process(dependency)
        else
          raise "Invalid dependency type: #{dependency.class}"
        end
      end
    end


def execute_screens(control, timing = :before_post_process)
      screens = case timing
        when :after_post_process
          control.after_post_process_screens
        else # default to before post-process screens
          control.screens
        end
      [:fatal,:error,:warn].each do |type|
        screens[type].each do |block|
          begin
            block.call
          rescue => e
            case type
            when :fatal
              raise FatalScreenError, e
            when :error
              raise ScreenError, e
            when :warn
              say "Screen warning: #{e}"
            end
          end
        end
      end
    end

def
execute_screens
(
control
,
timing
=
:before_post_process
)
screens
=
case
timing
when
:after_post_process
control
.
after_post_process_screens
else
control
.
screens
end
[
:fatal
,
:error
,
:warn
]
.
each
do
|
type
|
screens
[
type
]
.
each
do
|
block
|
begin
block
.
call
rescue
=>
e
case
type
when
:fatal
raise
FatalScreenError
,
e
when
:error
raise
ScreenError
,
e
when
:warn
say
"Screen warning: #{e}"
end
end
end
end
end


def redis_key *fields
      @redis_key_config = fields.flatten

      validate_redis_key

      #own specification of redis key - delete autoincrement
      remove_redis_autoincrement_key unless redis_user_field_config.include?(:id) || @redis_key_config.include?(:id)

      # automaticaly add all fields from key to validation
      # if any of fields in redis key is nil
      # then prevent to save it
      @redis_key_config.each do |field|
        validates field, :presence => :true if field != :id
      end
    end

def redis_key * fields @redis_key_config = fields . flatten validate_redis_key remove_redis_autoincrement_key unless redis_user_field_config . include? ( :id ) || @redis_key_config . include? ( :id ) @redis_key_config . each do | field | validates field , :presence => :true if field != :id end end

set redis key which will be used for storing model


def redis_key_normalize *metrics
      @redis_key_normalize_conf ||= []
      metrics.each do |metric|
        raise ArgumentError, "Please provide valid normalization: #{VALID_NORMALIZATIONS.join(", ")}" unless VALID_NORMALIZATIONS.include?(metric)
        @redis_key_normalize_conf << metric
      end
    end


def redis_alias name, main_fields, name_of_field_for_order = nil, name_of_field_for_args = nil
      #set fields if they are not allready set!
      if name_of_field_for_order && name_of_field_for_args
        redis_field name_of_field_for_order, :array, [] unless redis_fields_config.has_key?(name_of_field_for_order)
        redis_field name_of_field_for_args, :hash, {} unless redis_fields_config.has_key?(name_of_field_for_args)
      end

      @redis_alias_config ||= {}
      #add specification of dynamic alias
      @redis_alias_config[name] = {
        main_fields: main_fields,
        order_field: name_of_field_for_order,
        args_field: name_of_field_for_args,
      }

      #create alias methods for find and get (find_by_name, get_by_name)
      create_class_alias_method(name)
    end


def store_redis_keys
      args = to_arg
      #store main key
      redis_old_keys[:key] = self.class.generate_key(args) #store main key

      #store alias keys
      redis_old_keys[:aliases] = []
      redis_alias_config.each do |alias_name, fields|
        redis_old_keys[:aliases] << redis_alias_key(alias_name) if valid_alias_key? alias_name
      end
    end

def store_redis_keys args = to_arg redis_old_keys [ :key ] = self . class . generate_key ( args ) redis_old_keys [ :aliases ] = [ ] redis_alias_config . each do | alias_name , fields | redis_old_keys [ :aliases ] << redis_alias_key ( alias_name ) if valid_alias_key? alias_name end end


def conf
      fields = {}
      redis_fields_config.each do |key, type|
        fields[key] = TYPE_TRANSLATIONS[type] if TYPE_TRANSLATIONS.has_key?(type)
      end
      {
        fields: fields,
        required: @required_config.sort,
        redis_key: redis_key_config,
        redis_aliases: redis_alias_config.inject({}){|o,(k,v)| o[k] = v[:main_fields]; o},
        reject_nil_values: !redis_save_fields_with_nil_conf,
      }
    end

def conf fields = { } redis_fields_config . each do | key , type | fields [ key ] = TYPE_TRANSLATIONS [ type ] if TYPE_TRANSLATIONS . has_key? ( type ) end { fields : fields , required : @required_config . sort , redis_key : redis_key_config , redis_aliases : redis_alias_config . inject ( { } ) { | o , ( k , v ) | o [ k ] = v [ :main_fields ] ; o } , reject_nil_values : ! redis_save_fields_with_nil_conf , } end


def exists? args = {}
      RedisModelExtension::Database.redis.exists(self.name.constantize.generate_key(args))
    end

def exists? args = { } RedisModelExtension :: Database . redis . exists ( self . name . constantize . generate_key ( args ) ) end


def alias_exists? alias_name, args = {}
      RedisModelExtension::Database.redis.exists(self.name.constantize.generate_alias_key(alias_name, args))
    end

def alias_exists? alias_name , args = { } RedisModelExtension :: Database . redis . exists ( self . name . constantize . generate_alias_key ( alias_name , args ) ) end

Check if key by alias name and arguments exists in db


def valid_item_for_redis_key? args, key
      (args.has_key?(key) && !args[key].nil?) || redis_fields_config[key] == :autoincrement
    end

def valid_item_for_redis_key? args , key ( args . has_key? ( key ) && ! args [ key ] . nil? ) || redis_fields_config [ key ] == :autoincrement end


def validate_redis_key
      valid_fields = redis_fields_config.select{|k,v| v != :array && v != :hash  }.keys
      bad_fields = redis_key_config - valid_fields
      raise ArgumentError, "Sorry, but you cannot use as redis key [nonexisting | array | hash] fields: [#{bad_fields.join(",")}], availible are: #{valid_fields.join(", ")}" unless bad_fields.size == 0
    end

look for bad cofiguration in redis key and raise argument error


def to_arg
      redis_fields_config.inject({}) do |args, (key, type)|
        args[key] = self.send(key)
        args
      end
    end

def to_arg redis_fields_config . inject ( { } ) do | args , ( key , type ) | args [ key ] = self . send ( key ) args end end


def find_by_alias(alias_name, args = {})
      #check if asked dynamic alias exists
      raise ArgumentError, "Unknown dynamic alias: '#{alias_name}', use: #{redis_alias_config.keys.join(", ")} " unless redis_alias_config.has_key?(alias_name.to_sym)

      #normalize input hash of arguments
      args = HashWithIndifferentAccess.new(args)

      out = []
      klass = self.name.constantize
      search_key = klass.generate_alias_key(alias_name, args)
      #is key specified directly? -> no needs of looking for other keys! -> faster
      unless search_key =~ /\*/
        out = klass.get_by_alias(alias_name, args) if klass.alias_exists?(alias_name, args)
      else
        RedisModelExtension::Database.redis.keys(search_key).each do |key|
          out << klass.get_by_alias_key(key)
        end
      end
      out.flatten
    end


def get(args = {})
      # when argument is integer - search by id
      args = { id: args } if args.is_a?(Integer)

      #normalize input hash of arguments
      args = HashWithIndifferentAccess.new(args)

      klass = self.name.constantize
      if klass.valid_key?(args) && klass.exists?(args)
        klass.new_by_key(klass.generate_key(args))
      else
        nil
      end
    end

def get ( args = { } ) args = { id : args } if args . is_a? ( Integer ) args = HashWithIndifferentAccess . new ( args ) klass = self . name . constantize if klass . valid_key? ( args ) && klass . exists? ( args ) klass . new_by_key ( klass . generate_key ( args ) ) else nil end end

GET BY ARGUMENTS

fastest method to get object from redis by getting it by arguments
 * args (Integer) - search by id
 * args (Hash) - search by arguments in redis_key


def get_by_alias_key(alias_key)
      klass = self.name.constantize
      if RedisModelExtension::Database.redis.exists(alias_key)
        out = []
        RedisModelExtension::Database.redis.smembers(alias_key).each do |key|
          item = klass.new_by_key(key)
          out << item if item
        end
        return out
      end
      nil
    end

def get_by_alias_key ( alias_key ) klass = self . name . constantize if RedisModelExtension :: Database . redis . exists ( alias_key ) out = [ ] RedisModelExtension :: Database . redis . smembers ( alias_key ) . each do | key | item = klass . new_by_key ( key ) out << item if item end return out end nil end

fastest method to get object from redis by getting it by alias and arguments


def new_by_key(key)
      args = RedisModelExtension::Database.redis.hgetall(key)
      return nil unless args && args.any?
      args.symbolize_keys!

      new_instance = new(args)
      new_instance.store_keys

      return new_instance
    end

def new_by_key ( key ) args = RedisModelExtension :: Database . redis . hgetall ( key ) return nil unless args && args . any? args . symbolize_keys! new_instance = new ( args ) new_instance . store_keys return new_instance end

CREATE NEW OBJECT BY HASH VALUES

 read all data from redis and create new instance (used for Find & Get method)


def value_to_redis name, value
      if redis_fields_config.has_key?(name)
        value_transform value, redis_fields_config[name]
      else
        value
      end
    end

def value_to_redis name , value if redis_fields_config . has_key? ( name ) value_transform value , redis_fields_config [ name ] else value end end

choose right type of value and then transform it for redis


def value_transform value, type
      return nil if value.nil? || value.to_s.size == 0
      case type
      when :integer then value.to_i
      when :autoincrement then value.to_i
      when :string then value.to_s
      when :float then value.to_f
      when :bool then value.to_s
      when :symbol then value.to_s
      when :marshal then Marshal.dump(value)
      when :array then Yajl::Encoder.encode(value)
      when :hash then Yajl::Encoder.encode(value)
      when :time then Time.parse(value.to_s).strftime("%Y.%m.%d %H:%M:%S")
      when :date then Date.parse(value.to_s).strftime("%Y-%m-%d")
      else value
      end
    end

def
value_transform
value
,
type
return
if
value
.
nil?
||
value
.
to_s
.
size
==
0
case
type
when
:integer
then
value
.
to_i
when
:autoincrement
then
value
.
to_i
when
:string
then
value
.
to_s
when
:float
then
value
.
to_f
when
:bool
then
value
.
to_s
when
:symbol
then
value
.
to_s
when
:marshal
then
Marshal
.
dump
(
value
)
when
:array
then
Yajl
::
Encoder
.
encode
(
value
)
when
:hash
then
Yajl
::
Encoder
.
encode
(
value
)
when
:time
then
Time
.
parse
(
value
.
to_s
)
.
strftime
(
"%Y.%m.%d %H:%M:%S"
)
when
:date
then
Date
.
parse
(
value
.
to_s
)
.
strftime
(
"%Y-%m-%d"
)
else
value
end
end

convert value for valid format which can be saved in redis


def value_parse value, type
      return nil if value.nil? || value.to_s.size == 0
      case type
      when :integer then value.to_i
      when :autoincrement then value.to_i
      when :string then value.to_s
      when :float then value.to_f
      when :bool then value.to_s.to_bool
      when :symbol then value.to_s.to_sym
      when :marshal then value.is_a?(String) ? Marshal.load(value) : value
      when :array then value.is_a?(String) ? Yajl::Parser.parse(value) : value
      when :hash then value.is_a?(String) ? Hashr.new(Yajl::Parser.parse(value)) : Hashr.new(value)
      when :time then value.is_a?(String) ? Time.parse(value) : value
      when :date then value.is_a?(String) ? Date.parse(value) : value
      else value
      end
    end

def value_parse value , type return nil if value . nil? || value . to_s . size == 0 case type when :integer then value . to_i when :autoincrement then value . to_i when :string then value . to_s when :float then value . to_f when :bool then value . to_s . to_bool when :symbol then value . to_s . to_sym when :marshal then value . is_a? ( String ) ? Marshal . load ( value ) : value when :array then value . is_a? ( String ) ? Yajl :: Parser . parse ( value ) : value when :hash then value . is_a? ( String ) ? Hashr . new ( Yajl :: Parser . parse ( value ) ) : Hashr . new ( value ) when :time then value . is_a? ( String ) ? Time . parse ( value ) : value when :date then value . is_a? ( String ) ? Date . parse ( value ) : value else value end end

convert value from redis into valid format in ruby


def update args
      args.each do |key, value|
        method = "#{key}=".to_sym
        if self.respond_to? method
          self.send(method, value)
        end
      end
    end

def update args args . each do | key , value | method = "#{key}=" . to_sym if self . respond_to? method self . send ( method , value ) end end end


def destroy_aliases!
      #do it only if it is existing object!
      if redis_old_keys[:aliases].size > 0
        redis_old_keys[:aliases].each do |alias_key|
          RedisModelExtension::Database.redis.srem alias_key, redis_old_keys[:key]
          #delete alias with 0 keys
          RedisModelExtension::Database.redis.del(alias_key) if RedisModelExtension::Database.redis.scard(alias_key).to_i == 0
        end
      end
    end

def destroy_aliases! if redis_old_keys [ :aliases ] . size > 0 redis_old_keys [ :aliases ] . each do | alias_key | RedisModelExtension :: Database . redis . srem alias_key , redis_old_keys [ :key ] RedisModelExtension :: Database . redis . del ( alias_key ) if RedisModelExtension :: Database . redis . scard ( alias_key ) . to_i == 0 end end end


def add(username, token)
      Firim::AccountManager.new(
        user: username,
        token: token
      ).add_to_keychain
    end

def add ( username , token ) Firim :: AccountManager . new ( user : username , token : token ) . add_to_keychain end


def get_nsqds(lookupd, topic = nil)
      uri_scheme = 'http://' unless lookupd.match(%r(https?://))
      uri = URI.parse("#{uri_scheme}#{lookupd}")

      uri.query = "ts=#{Time.now.to_i}"
      if topic
        uri.path = '/lookup'
        uri.query += "&topic=#{URI.escape(topic)}"
      else
        uri.path = '/nodes'
      end

      begin
        body = Net::HTTP.get(uri)
        data = JSON.parse(body)
        producers = data['producers'] || # v1.0.0-compat
                      (data['data'] && data['data']['producers'])

        if producers
          producers.map do |producer|
            "#{producer['broadcast_address']}:#{producer['tcp_port']}"
          end
        else
          []
        end
      rescue Exception => e
        error "Error during discovery for #{lookupd}: #{e}"
        nil
      end
    end

Returns an array of nsqd addresses
 If there's an error, return nil

Returns an array of nsqd addresses If there s an error return nil


def discover_repeatedly(opts = {})
      @discovery_thread = Thread.new do

        @discovery = Discovery.new(opts[:nsqlookupds])

        loop do
          begin
            nsqds = nsqds_from_lookupd(opts[:topic])
            drop_and_add_connections(nsqds)
          rescue DiscoveryException
            # We can't connect to any nsqlookupds. That's okay, we'll just
            # leave our current nsqd connections alone and try again later.
            warn 'Could not connect to any nsqlookupd instances in discovery loop'
          end
          sleep opts[:interval]
        end

      end

      @discovery_thread.abort_on_exception = true
    end

discovers nsqds from an nsqlookupd repeatedly

   opts:
     nsqlookups: ['127.0.0.1:4161'],
     topic: 'topic-to-find-nsqds-for',
     interval: 60


def with_retries(&block)
      base_sleep_seconds = 0.5
      max_sleep_seconds = 300 # 5 minutes

      # Let's do this thing
      attempts = 0

      begin
        attempts += 1
        return block.call(attempts)

      rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EHOSTUNREACH,
             Errno::ENETDOWN, Errno::ENETUNREACH, Errno::ETIMEDOUT, Timeout::Error => ex

        raise ex if attempts >= 100

        # The sleep time is an exponentially-increasing function of base_sleep_seconds.
        # But, it never exceeds max_sleep_seconds.
        sleep_seconds = [base_sleep_seconds * (2 ** (attempts - 1)), max_sleep_seconds].min
        # Randomize to a random value in the range sleep_seconds/2 .. sleep_seconds
        sleep_seconds = sleep_seconds * (0.5 * (1 + rand()))
        # But never sleep less than base_sleep_seconds
        sleep_seconds = [base_sleep_seconds, sleep_seconds].max

        warn "Failed to connect: #{ex}. Retrying in #{sleep_seconds.round(1)} seconds."

        snooze(sleep_seconds)

        retry
      end
    end

Retry the supplied block with exponential backoff.

 Borrowed liberally from:
 https://github.com/ooyala/retries/blob/master/lib/retries.rb

Retry the supplied block with exponential backoff .


def show(ind = '')
      count = 0
      self.to_a.each{|i|
        #puts "#{ind}#{i.name} #{i.object_id} #{i.super.object_id} [#{count}]: #{i.parsed_str} #{i.super.class}"
        puts "#{ind}#{i.name} [#{count}]: #{i.to_s.sub(/^(.{30})(.*?)(.{30})$/, '\1...\3')}"
        # Force parsing a segment
        if i.kind_of?(X12::Segment) && i.nodes[0]
          i.find_field(i.nodes[0].name)
        end
        i.nodes.each{|j|
          case
          when j.kind_of?(X12::Base)  then j.show(ind+'  ')
          when j.kind_of?(X12::Field) then puts "#{ind+'  '}#{j.name} -> '#{j.to_s}'"
          end
        }
        count += 1
      }
    end

Prints a tree-like representation of the element

Prints a tree - like representation of the element


def do_repeats(s)
      if self.repeats.end > 1
        possible_repeat = self.dup
        p_s = possible_repeat.parse(s)
        if p_s
          s = p_s
          self.next_repeat = possible_repeat
        end # if parsed
      end # more repeats
      s
    end

def do_repeats ( s ) if self . repeats . end > 1 possible_repeat = self . dup p_s = possible_repeat . parse ( s ) if p_s s = p_s self . next_repeat = possible_repeat end end s end

Try to parse the current element one more time if required. Returns the rest of the string
 or the same string if no more repeats are found or required.

Try to parse the current element one more time if required . Returns the rest of the string or the same string if no more repeats are found or required .


def find(e)
      #puts "Finding [#{e}] in #{self.class} #{name}"
      case self
        when X12::Loop
        # Breadth first
        res = nodes.find{|i| e==i.name }
        return res if res
        # Depth now
        nodes.each{|i|
          res = i.find(e) if i.kind_of?(X12::Loop)
          return res unless res.nil? or EMPTY==res # otherwise keep looping
        }
        when X12::Segment
        return find_field(e).to_s
      end # case
      return EMPTY
    end

def find ( e ) case self when X12 :: Loop res = nodes . find { | i | e == i . name } return res if res nodes . each { | i | res = i . find ( e ) if i . kind_of? ( X12 :: Loop ) return res unless res . nil? or EMPTY == res } when X12 :: Segment return find_field ( e ) . to_s end return EMPTY end

Make a deep copy of the element
 dup
 Recursively find a sub-element, which also has to be of type Base.

Make a deep copy of the element dup Recursively find a sub - element which also has to be of type Base .


def method_missing(meth, *args, &block)
      str = meth.id2name
      str = str[1..str.length] if str =~ /^_\d+$/ # to avoid pure number names like 270, 997, etc.
      #puts "Missing #{str}"
      if str =~ /=$/
        # Assignment
        str.chop!
        #puts str
        case self
        when X12::Segment
          res = find_field(str)
          throw Exception.new("No field '#{str}' in segment '#{self.name}'") if EMPTY == res
          res.content = args[0].to_s
          #puts res.inspect
        else
          throw Exception.new("Illegal assignment to #{meth} of #{self.class}")
        end # case
      else
        # Retrieval
        res = find(str)
        yield res if block_given?
        res
      end # if assignment
    end

The main method implementing Ruby-like access methods for nested elements

The main method implementing Ruby - like access methods for nested elements


def parse(str)
      s = str
      #puts "Parsing segment #{name} from #{s} with regexp [#{regexp.source}]"
      m = regexp.match(s)
      #puts "Matched #{m ? m[0] : 'nothing'}"

      return nil unless m

      s = m.post_match
      self.parsed_str = m[0]
      s = do_repeats(s)

      #puts "Parsed segment "+self.inspect
      return s
    end

def parse ( str ) s = str m = regexp . match ( s ) return nil unless m s = m . post_match self . parsed_str = m [ 0 ] s = do_repeats ( s ) return s end

Parses this segment out of a string, puts the match into value, returns the rest of the string - nil
 if cannot parse

Parses this segment out of a string puts the match into value returns the rest of the string - nil if cannot parse


def render
      self.to_a.inject(''){|repeat_str, i|
        if i.repeats.begin < 1 and !i.has_content?
          # Skip optional empty segments
          repeat_str
        else
          # Have to render no matter how empty
          repeat_str += i.name+i.nodes.reverse.inject(''){|nodes_str, j|
            field = j.render
            (j.required or nodes_str != '' or field != '') ? field_separator+field+nodes_str : nodes_str
          } + segment_separator
        end
      }
    end

def render self . to_a . inject ( '' ) { | repeat_str , i | if i . repeats . begin < 1 and ! i . has_content? repeat_str else repeat_str += i . name + i . nodes . reverse . inject ( '' ) { | nodes_str , j | field = j . render ( j . required or nodes_str != '' or field != '' ) ? field_separator + field + nodes_str : nodes_str } + segment_separator end } end

parse
 Render all components of this segment as string suitable for EDI


def regexp
      unless @regexp
        if self.nodes.find{|i| i.type =~ /^".+"$/ }
          # It's a very special regexp if there are constant fields
          re_str = self.nodes.inject("^#{name}#{Regexp.escape(field_separator)}"){|s, i|
            field_re = i.simple_regexp(field_separator, segment_separator)+Regexp.escape(field_separator)+'?'
            field_re = "(#{field_re})?" unless i.required
            s+field_re
          } + Regexp.escape(segment_separator)
          @regexp = Regexp.new(re_str)
        else
          # Simple match
          @regexp = Regexp.new("^#{name}#{Regexp.escape(field_separator)}[^#{Regexp.escape(segment_separator)}]*#{Regexp.escape(segment_separator)}")
        end
        #puts sprintf("%s %p", name, @regexp)
      end
      @regexp
    end

render
 Returns a regexp that matches this particular segment


def find_field(str)
      #puts "Finding field [#{str}] in #{self.class} #{name}"
      # If there is such a field to begin with
      field_num = nil
      self.nodes.each_index{|i|
        field_num = i if str == self.nodes[i].name
      }
      return EMPTY if field_num.nil?
      #puts field_num

      # Parse the segment if not parsed already
      unless @fields
        @fields = self.to_s.chop.split(Regexp.new(Regexp.escape(field_separator)))
        self.nodes.each_index{|i| self.nodes[i].content = @fields[i+1] }
      end
      #puts self.nodes[field_num].inspect
      return self.nodes[field_num]
    end

def find_field ( str ) field_num = nil self . nodes . each_index { | i | field_num = i if str == self . nodes [ i ] . name } return EMPTY if field_num . nil? unless @fields @fields = self . to_s . chop . split ( Regexp . new ( Regexp . escape ( field_separator ) ) ) self . nodes . each_index { | i | self . nodes [ i ] . content = @fields [ i + 1 ] } end return self . nodes [ field_num ] end

Finds a field in the segment. Returns EMPTY if not found.

Finds a field in the segment . Returns EMPTY if not found .


def parse(loop_name, str)
      loop = @x12_definition[X12::Loop][loop_name]
      #puts "Loops to parse #{@x12_definition[X12::Loop].keys}"
      throw Exception.new("Cannot find a definition for loop #{loop_name}") unless loop
      loop = loop.dup
      loop.parse(str)
      return loop
    end

Creates a parser out of a definition
 initialize
 Parse a loop of a given name out of a string. Throws an exception if the loop name is not defined.

Creates a parser out of a definition initialize Parse a loop of a given name out of a string . Throws an exception if the loop name is not defined .


def factory(loop_name)
      loop = @x12_definition[X12::Loop][loop_name]
      throw Exception.new("Cannot find a definition for loop #{loop_name}") unless loop
      loop = loop.dup
      return loop
    end

parse
 Make an empty loop to be filled out with information


def process_loop(loop)
      loop.nodes.each{|i|
        case i
          when X12::Loop then process_loop(i)
          when X12::Segment then process_segment(i) unless i.nodes.size > 0
          else return
        end
      }
    end

def process_loop ( loop ) loop . nodes . each { | i | case i when X12 :: Loop then process_loop ( i ) when X12 :: Segment then process_segment ( i ) unless i . nodes . size > 0 else return end } end

Recursively scan the loop and instantiate fields' definitions for all its
 segments

Recursively scan the loop and instantiate fields definitions for all its segments


def process_segment(segment)
      #puts "Trying to process segment #{segment.inspect}"
      unless @x12_definition[X12::Segment] && @x12_definition[X12::Segment][segment.name]
        # Try to find it in a separate file if missing from the @x12_definition structure
        initialize(segment.name+'.xml')
        segment_definition = @x12_definition[X12::Segment][segment.name]
        throw Exception.new("Cannot find a definition for segment #{segment.name}") unless segment_definition
      else
        segment_definition = @x12_definition[X12::Segment][segment.name]
      end
      segment_definition.nodes.each_index{|i|
        segment.nodes[i] = segment_definition.nodes[i]
        # Make sure we have the validation table if any for this field. Try to read one in if missing.
        table = segment.nodes[i].validation
        if table
          unless @x12_definition[X12::Table] && @x12_definition[X12::Table][table]
            initialize(table+'.xml')
            throw Exception.new("Cannot find a definition for table #{table}") unless @x12_definition[X12::Table] && @x12_definition[X12::Table][table]
          end
        end
      }
    end

Instantiate segment's fields as previously defined

Instantiate segment s fields as previously defined


def render
      if self.has_content?
        self.to_a.inject(''){|loop_str, i|
          loop_str += i.nodes.inject(''){|nodes_str, j|
            nodes_str += j.render
          }
        }
      else
        ''
      end
    end

def render if self . has_content? self . to_a . inject ( '' ) { | loop_str , i | loop_str += i . nodes . inject ( '' ) { | nodes_str , j | nodes_str += j . render } } else '' end end

parse
 Render all components of this loop as string suitable for EDI


def calculate_sortable_values
      response_fieldable.input_fields.each do |response_field|
        if (x = response_value(response_field)).present?
          get_responses["#{response_field.id}_sortable_value"] = response_field.sortable_value(x)
        end
      end

      mark_responses_as_changed!
    end

def calculate_sortable_values response_fieldable . input_fields . each do | response_field | if ( x = response_value ( response_field ) ) . present? get_responses [ "#{response_field.id}_sortable_value" ] = response_field . sortable_value ( x ) end end mark_responses_as_changed! end


def normalize_responses
      return if form.blank?

      form.response_fields.each do |response_field|
        if (x = self.response_value(response_field))
          response_field.normalize_response(x, get_responses)
        end
      end

      mark_responses_as_changed!
    end

def normalize_responses return if form . blank? form . response_fields . each do | response_field | if ( x = self . response_value ( response_field ) ) response_field . normalize_response ( x , get_responses ) end end mark_responses_as_changed! end

Normalizations get run before validation.

Normalizations get run before validation .


def audit_responses
      form.response_fields.each do |response_field|
        response_field.audit_response(self.response_value(response_field), get_responses)
      end

      mark_responses_as_changed!
    end

def audit_responses form . response_fields . each do | response_field | response_field . audit_response ( self . response_value ( response_field ) , get_responses ) end mark_responses_as_changed! end


def tag!(tag, *args, &block)
      text, attributes = nil, {}
      args.each do |arg|
        case arg
        when ::Hash
          attributes.merge!(arg)
        when ::String
          text ||= ''
          text << arg
        end
      end
      @stack << [tag, attributes, text ? [text] : []]
      if block
        _process(&block)
      end
      if @stack.length > 1
        node = @stack.pop
        @stack.last[2] << node
        NodeBuilder.new(node, self)
      else
        NodeBuilder.new(@stack.last, self)
      end
    end

def tag! ( tag , * args , & block ) text , attributes = nil , { } args . each do | arg | case arg when :: Hash attributes . merge! ( arg ) when :: String text ||= '' text << arg end end @stack << [ tag , attributes , text ? [ text ] : [ ] ] if block _process ( & block ) end if @stack . length > 1 node = @stack . pop @stack . last [ 2 ] << node NodeBuilder . new ( node , self ) else NodeBuilder . new ( @stack . last , self ) end end

Construct a new builder, and start building

 The recommended way to call this is through `Hexp.build`. If the block
 takes an argument, then builder methods need to be called on that variable.

 @example With an explicit builder
   hi = Hexp.build {|html| html.span "Hello" ; html.span " World"}

 @example Without a builder object
   hi = Hexp.build { span "Hello" ; span " World"}

 @param [Symbol] tag
   The tag of the outermost element (optional)
 @param [Array<Hash,String>] args
   Extra arguments, a String for a text node, a Hash for attributes

 @yieldparam [Hexp::Builder]
   If the block takes an argument it will receive the builder object

 @api private

 Add a tag (HTML element)

 Typically this is called implicitly through method missing, but in case of
 name clashes or dynamically generated tags you can call this directly.

 @example
   hexp = Hexp.build :div do
     tag!(:p, "Oh the code, such sweet joy it brings")
   end
   hexp.to_html #=> "

Oh the code, such sweet joy it brings

"

 @param [Symbol] tag
   The tag name, like 'div' or 'head'
 @param [Array<Hash|String>] args
   A hash of attributes, or a string to use inside the tag, or both. Multiple
   occurences of each can be specified
 @param [Proc] block
   Builder directives for the contents of the tag

 @return [nil]

 @api public

Construct a new builder and start building


def <<(*args)
      args.each do |arg|
        if arg.respond_to?(:to_hexp)
          @stack.last[2] << arg
          self
        else
          ::Kernel.raise ::Hexp::FormatError, "Inserting literal HTML into a builder with << is deliberately not supported by Hexp"
        end
      end
    end

Add Hexp objects to the current tag

 Any Hexp::Node or other object implementing to_hexp can be added with
 this operator. Multiple objects can be specified in one call.

 Nokogiri and Builder allow inserting of strings containing HTML through
 this operator. Since this would violate the core philosophy of Hexp, and
 open the door for XSS vulnerabilities, we do not support that usage.

 If you really want to insert HTML that is already in serialized form,
 consider parsing it to Hexps first

 @example
   widget = H[:button, "click me!"]
   node = Hexp.build :div do |h|
     h << widget
   end
   node.to_html #=>
<button>click me!</button>

 @param [Array<#to_hexp>] args
   Hexpable objects to add to the current tag

 @return [Hexp::Builder]

 @api public


def rewrite(css_selector = nil, &block)
      return Rewriter.new(self, block) if css_selector.nil?
      CssSelection.new(self, css_selector).rewrite(&block)
    end

def rewrite ( css_selector = nil , & block ) return Rewriter . new ( self , block ) if css_selector . nil? CssSelection . new ( self , css_selector ) . rewrite ( & block ) end

Replace nodes in a tree

 With a CSS selector string like +"form.checkout"+ you specify the nodes
 you want to operate on. These will be passed one by one into the block.
 The block returns the {Hexp::Node} that will replace the old node, or it
 can replace an +Array+ of nodes to fill the place of the old node.

 Because of this you can add one or more nodes, or remove nodes by
 returning an empty array.

 @example Remove all script tags
   tree.replace('script') {|_| [] }

 @example Wrap each +<input>+ tag into a +<p>+ tag
   tree.replace('input') do |input|
     H[:p, input]
   end

 @param [String] css_selector

 @yieldparam [Hexp::Node]
   The matching nodes

 @return [Hexp::Node]
   The rewritten tree

 @api public


def select(css_selector = nil, &block)
      if css_selector
        CssSelection.new(self, css_selector).each(&block)
      else
        Selection.new(self, block)
      end
    end

def select ( css_selector = nil , & block ) if css_selector CssSelection . new ( self , css_selector ) . each ( & block ) else Selection . new ( self , block ) end end

Select nodes based on a css selector

 @param [String] css_selector
 @yieldparam [Hexp::Node]

 @return [Hexp::Selector,Hexp::CssSelector]

 @api public


def add_configuration(config_hash)
      config_hash.each do |key, val|
        instance_eval { instance_variable_set("@#{key}",val) }
        self.class.instance_eval { attr_accessor key }
      end
    end

def add_configuration ( config_hash ) config_hash . each do | key , val | instance_eval { instance_variable_set ( "@#{key}" , val ) } self . class . instance_eval { attr_accessor key } end end

Extend configuration variables

 @param config_hash [Hash]

 @example
   IronHide.configuration.add_configuration(couchdb_server: 'http://127.0.0.1:5984')
   IronHide.configuration.couchdb_server)
   #=> 'http://127.0.0.1:5984'

   IronHide.configuration.couchdb_server = 'other'
   #=> 'other'


def pid_exists(pid)
  return false if pid < 0
  # According to "man 2 kill" PID 0 has a special meaning:
  # it refers to <<every process in the process group of the
  # calling process>> so we don't want to go any further.
  # If we get here it means this UNIX platform *does* have
  # a process with id 0.
  return true if pid == 0

  ::Process.kill(0, pid)
  return true
  rescue Errno::ESRCH # No such process
    return false
  rescue Errno::EPERM
    # EPERM clearly means there's a process to deny access to
    return true
  rescue RangeError # the given pid is invalid.
    return false
end

def pid_exists ( pid ) return false if pid < 0 return true if pid == 0 :: Process . kill ( 0 , pid ) return true rescue Errno :: ESRCH return false rescue Errno :: EPERM return true rescue RangeError return false end

Check whether pid exists in the current process table."""

Check whether pid exists in the current process table .


def wait_pid(pid, timeout=nil)

  def check_timeout(delay, stop_at, timeout)
    if timeout
      raise Timeout::Error.new("when waiting for (pid=#{pid})") if Time.now >= stop_at
    end
    sleep(delay)
    delay * 2 < 0.04 ? delay * 2 : 0.04
  end

  if timeout
    waitcall = proc { ::Process.wait(pid, ::Process::WNOHANG)}
    stop_at = Time.now + timeout
  else
    waitcall = proc { ::Process.wait(pid)}
  end

  delay = 0.0001
  loop do
    begin
      retpid = waitcall.call()
    rescue Errno::EINTR
      delay = check_timeout(delay, stop_at, timeout)
      next
    rescue Errno::ECHILD
      # This has two meanings:
      # - pid is not a child of Process.pid in which case
      #   we keep polling until it's gone
      # - pid never existed in the first place
      # In both cases we'll eventually return nil as we
      # can't determine its exit status code.
      loop do
        return nil unless pid_exists(pid)
        delay = check_timeout(delay, stop_at, timeout)
      end
    end

    unless retpid
      # WNOHANG was used, pid is still running
      delay = check_timeout(delay, stop_at, timeout)
      next
    end

    # process exited due to a signal; return the integer of
    # that signal
    if $?.signaled?
      return $?.termsig
    # process exited using exit(2) system call; return the
    # integer exit(2) system call has been called with
    elsif $?.exited?
      return $?.exitstatus
    else
      # should never happen
      raise RuntimeError.new("unknown process exit status")
    end
  end
end

def
wait_pid
(
pid
,
timeout
=
)
def
check_timeout
(
delay
,
stop_at
,
timeout
)
if
timeout
raise
Timeout
::
Error
.
new
(
"when waiting for (pid=#{pid})"
)
if
Time
.
now
>=
stop_at
end
sleep
(
delay
)
delay
*
2
<
0.04
delay
*
2
:
0.04
end
if
timeout
waitcall
=
proc
{
::
Process
.
wait
(
pid
,
::
Process
::
WNOHANG
)
}
stop_at
=
Time
.
now
+
timeout
else
waitcall
=
proc
{
::
Process
.
wait
(
pid
)
}
end
delay
=
0.0001
loop
do
begin
retpid
=
waitcall
.
call
(
)
rescue
Errno
::
EINTR
delay
=
check_timeout
(
delay
,
stop_at
,
timeout
)
next
rescue
Errno
::
ECHILD
loop
do
return
unless
pid_exists
(
pid
)
delay
=
check_timeout
(
delay
,
stop_at
,
timeout
)
end
end
unless
retpid
delay
=
check_timeout
(
delay
,
stop_at
,
timeout
)
next
end
if
$?
.
signaled?
return
$?
.
termsig
elsif
$?
.
exited?
return
$?
.
exitstatus
else
raise
RuntimeError
.
new
(
"unknown process exit status"
)
end
end
end

Wait for process with pid 'pid' to terminate and return its
 exit status code as an integer.

 If pid is not a children of Process.pid (current process) just
 waits until the process disappears and return nil.

 If pid does not exist at all return nil immediately.

 Raise Timeout::Error on timeout expired.

Wait for process with pid pid to terminate and return its exit status code as an integer .


def upload_module_changes(parent_sha1, sha1s)
    remote_path = fetch_module
    # search for the first revision that is not
    tmp_git_path = clone_or_fetch_repository(remote_path, module_tmp_git_path(@remote_path))
    RIM::git_session(tmp_git_path) do |dest|
      local_branch = nil
      remote_branch = nil
      infos = nil
      if @module_info.subdir
        dest_path = File.join([tmp_git_path] + @module_info.subdir.split("/"))
      else
        dest_path = tmp_git_path
      end
      RIM::git_session(@ws_root) do |src|
        infos = get_branches_and_revision_infos(src, dest, parent_sha1, sha1s)
        if infos.branches.size == 1
          remote_branch = infos.branches[0]
          if dest.has_remote_branch?(remote_branch)
            infos.rev_infos.each do |rev_info|
              local_branch = create_update_branch(dest, infos.parent_sha1, rev_info.src_sha1) if !local_branch
              copy_revision_files(
                src,
                rev_info.src_sha1,
                dest_path,
                rev_info.rim_info.ignores
              )
              commit_changes(dest, local_branch, rev_info.src_sha1, rev_info.message)
            end
          else
            raise RimException.new("The target revision '#{@module_info.target_revision}' of module #{@module_info.local_path} is not a branch. No push can be performed.")
          end
        elsif infos.branches.size > 1
          raise RimException.new("There are commits for module #{@module_info.local_path} on multiple target revisions (#{infos.branches.join(", ")}).")
        end
      end
      # Finally we're done. Push the changes
      if local_branch && dest.rev_sha1(local_branch) != infos.parent_sha1
        push_branch = @review && @module_info.remote_branch_format && !@module_info.remote_branch_format.empty? \
            ? @module_info.remote_branch_format % remote_branch : remote_branch
        dest.execute("git push #{@remote_url} #{local_branch}:#{push_branch}")
        dest.execute("git checkout --detach #{local_branch}")
        dest.execute("git branch -D #{local_branch}")
        @logger.info("Commited changes for module #{@module_info.local_path} to remote branch #{push_branch}.")
      else
        @logger.info("No changes to module #{@module_info.local_path}.")
      end
    end
  end


def get_branches_and_revision_infos(src_session, dest_session, parent_sha1, sha1s)
    infos = []
    branches = []
    dest_parent_sha1 = nil
    (sha1s.size() - 1).step(0, -1) do |i|
      info = get_revision_info(src_session, dest_session, sha1s[i])
      if !info.dest_sha1 && info.rim_info.target_revision
        infos.unshift(info)
        branches.push(info.rim_info.target_revision) if !branches.include?(info.rim_info.target_revision)
      else
        dest_parent_sha1 = info.dest_sha1
        break
      end
    end
    dest_parent_sha1 = get_riminfo_for_revision(src_session, parent_sha1).revision_sha1 if !dest_parent_sha1
    dest_parent_sha1 = infos.first.rim_info.revision_sha1 if !dest_parent_sha1 && !infos.empty?
    return Struct.new(:branches, :parent_sha1, :rev_infos).new(branches, dest_parent_sha1, infos)
  end

def get_branches_and_revision_infos ( src_session , dest_session , parent_sha1 , sha1s ) infos = [ ] branches = [ ] dest_parent_sha1 = nil ( sha1s . size ( ) - 1 ) . step ( 0 , - 1 ) do | i | info = get_revision_info ( src_session , dest_session , sha1s [ i ] ) if ! info . dest_sha1 && info . rim_info . target_revision infos . unshift ( info ) branches . push ( info . rim_info . target_revision ) if ! branches . include? ( info . rim_info . target_revision ) else dest_parent_sha1 = info . dest_sha1 break end end dest_parent_sha1 = get_riminfo_for_revision ( src_session , parent_sha1 ) . revision_sha1 if ! dest_parent_sha1 dest_parent_sha1 = infos . first . rim_info . revision_sha1 if ! dest_parent_sha1 && ! infos . empty? return Struct . new ( :branches , :parent_sha1 , :rev_infos ) . new ( branches , dest_parent_sha1 , infos ) end


def get_revision_info(src_session, dest_session, src_sha1)
    module_status = StatusBuilder.new.rev_module_status(src_session, src_sha1, @module_info.local_path)
    rim_info = get_riminfo_for_revision(src_session, src_sha1)
    dest_sha1 = dest_session.rev_sha1("rim-#{src_sha1}")
    msg = src_session.execute("git show -s --format=%B #{src_sha1}")
    RevisionInfo.new(module_status && module_status.dirty? ? dest_sha1 : rim_info.revision_sha1, src_sha1, rim_info, msg)
  end


def commit_changes(session, branch, sha1, msg)
    if session.status.lines.any?
      # add before commit because the path can be below a not yet added path
      session.execute("git add --all")
      msg_file = Tempfile.new('message')
      begin
        msg_file << msg
        msg_file.close
        session.execute("git commit -F #{msg_file.path}")
      ensure
        msg_file.close(true)
      end
      # create tag
      session.execute("git tag rim-#{sha1} refs/heads/#{branch}")
    end
  end


def get_riminfo_for_revision(session, sha1)
    session.execute("git show #{sha1}:#{File.join(@module_info.local_path, RimInfo::InfoFileName)}") do |out, e|
      return RimInfo.from_s(!e ? out : "")
    end
  end

get target revision for this module for workspace revision


def copy_revision_files(src_session, src_sha1, dest_dir, ignores)
    Dir.mktmpdir do |tmp_dir|
      tmp_dir = Dir.glob(tmp_dir)[0]
      src_session.execute("git archive --format tar #{src_sha1} #{@module_info.local_path} | tar -C #{tmp_dir} -xf -")
      tmp_module_dir = File.join(tmp_dir, @module_info.local_path)
      files = FileHelper.find_matching_files(tmp_module_dir, false, "/**/*", File::FNM_DOTMATCH)
      files.delete(".")
      files.delete("..")
      files.delete(RimInfo::InfoFileName)
      files -= FileHelper.find_matching_files(tmp_module_dir, false, ignores)
      # have source files now. Now clear destination folder and copy
      prepare_empty_folder(dest_dir, ".git/**/*")
      files.each do |f|
        src_path = File.join(tmp_module_dir, f)
        if File.file?(src_path)
          path = File.join(dest_dir, f)
          FileUtils.mkdir_p(File.dirname(path))
          FileUtils.cp(src_path, path)
        end
      end
    end
  end

copy files from given source revision into destination dir


def rev_history_status(git_session, rev, options={})
    stop_rev = options[:stop_rev]
    relevant_revs = {}
    if stop_rev
      git_session.execute("git rev-list #{rev} \"^#{stop_rev}\"").split("\n").each do |r|
        relevant_revs[r] = true
      end
    elsif options[:gerrit]
      # in gerrit mode, stop on all known commits
      git_session.execute("git rev-list #{rev} --not --all --").split("\n").each do |r|
        relevant_revs[r] = true
      end
    else
      # remote revs are where we stop traversal
      git_session.all_reachable_non_remote_revs(rev).each do |r|
        relevant_revs[r] = true
      end
    end
    # make sure we deal only with sha1s
    rev = git_session.rev_sha1(rev)
    build_rev_history_status(git_session, rev, relevant_revs, {}, :fast => options[:fast])
  end

def
rev_history_status
(
git_session
,
rev
,
options
=
{
}
)
stop_rev
=
options
[
:stop_rev
]
relevant_revs
=
{
}
if
stop_rev
git_session
.
execute
(
"git rev-list #{rev} \"^#{stop_rev}\""
)
.
split
(
"\n"
)
.
each
do
|
r
|
relevant_revs
[
r
]
=
true
end
elsif
options
[
:gerrit
]
git_session
.
execute
(
"git rev-list #{rev} --not --all --"
)
.
split
(
"\n"
)
.
each
do
|
r
|
relevant_revs
[
r
]
=
true
end
else
git_session
.
all_reachable_non_remote_revs
(
rev
)
.
each
do
|
r
|
relevant_revs
[
r
]
=
true
end
end
rev
=
git_session
.
rev_sha1
(
rev
)
build_rev_history_status
(
git_session
,
rev
,
relevant_revs
,
{
}
,
:fast
=>
options
[
:fast
]
)
end

status object tree for revision rev
 returns the root status object which points to any parent status objects
 note that merge commits mean that the status tree branches
 at the point were the merged branch branched off, the status tree joins
 i.e. the parent status objects are the same at this point

 stops traversing a specific branch when a commit is found which is an ancestor
 of :stop_rev or any remote branch if :stop_rev is not provided;

 with the :gerrit option, stops traversing on any ancestor of any known commit;
 this is necessary since on gerrit there are no "remote" commits;
 at the same time, gerrit doesn't "know" commits pushed in the ref-update hook yet
 so the status will be built for the new commits pushed in the ref-update hook

 the leafs of the tree are the stop commits or commits which have no parents

 with the :fast option set to true, the leafs in the tree will not be checked
 but instead all modules present in those commits will assumed to be clean;
 be aware that this assumption might be wrong!
 if the leaves of the tree are remote commits, the fast check basically tells
 if any of the local commits is dirty or not

status object tree for revision rev returns the root status object which points to any parent status objects note that merge commits mean that the status tree branches at the point were the merged branch branched off the status tree joins i . e . the parent status objects are the same at this point


def rev_status(git_session, rev)
    mod_dirs = module_dirs(git_session, rev)
    mod_stats = []
    # export all relevant modules at once
    # this makes status calculation significantly faster compared
    # to exporting each module separately
    # (e.g. 1.0s instead of 1.5s on linux for a commit with 20 modules)
    git_session.within_exported_rev(rev, mod_dirs) do |d|
      mod_dirs.each do |rel_path|
        mod_stats << build_module_status(d, d+"/"+rel_path)
      end
    end
    stat = RevStatus.new(mod_stats)
    stat.git_rev = git_session.rev_sha1(rev)
    stat
  end

def rev_status ( git_session , rev ) mod_dirs = module_dirs ( git_session , rev ) mod_stats = [ ] git_session . within_exported_rev ( rev , mod_dirs ) do | d | mod_dirs . each do | rel_path | mod_stats << build_module_status ( d , d + "/" + rel_path ) end end stat = RevStatus . new ( mod_stats ) stat . git_rev = git_session . rev_sha1 ( rev ) stat end

status object for single revision +rev+ without status of ancestors

status object for single revision + rev + without status of ancestors


def rev_module_status(git_session, rev, local_path)
    mod_stat = nil
    if git_session.execute("git ls-tree -r --name-only #{rev}").split("\n").include?(File.join(local_path, ".riminfo"))
      git_session.within_exported_rev(rev, [local_path]) do |d|
        mod_stat = build_module_status(d, File.join(d, local_path))
      end
    end
    mod_stat
  end

def
rev_module_status
(
git_session
,
rev
,
local_path
)
mod_stat
=
if
git_session
.
execute
(
"git ls-tree -r --name-only #{rev}"
)
.
split
(
"\n"
)
.
include?
(
File
.
join
(
local_path
,
".riminfo"
)
)
git_session
.
within_exported_rev
(
rev
,
[
local_path
]
)
do
|
d
|
mod_stat
=
build_module_status
(
d
,
File
.
join
(
d
,
local_path
)
)
end
end
mod_stat
end

status object for a single module at +local_path+ in revision +rev+
 returns nil if there is no such module in this revision

status object for a single module at + local_path + in revision + rev + returns nil if there is no such module in this revision


def fs_status(dir)
    RevStatus.new(
      fs_rim_dirs(dir).collect { |d|
        build_module_status(dir, d)
      })
  end

def fs_status ( dir ) RevStatus . new ( fs_rim_dirs ( dir ) . collect { | d | build_module_status ( dir , d ) } ) end

status object for the current file system content of dir
 this can by any directory even outside of any git working copy


def build_rev_history_status(gs, rev, relevant_revs, status_cache={}, options={})
    return status_cache[rev] if status_cache[rev]
    stat = nil
    if relevant_revs[rev]
      parent_revs = gs.parent_revs(rev)
      if parent_revs.size > 0
        # build status for all parent nodes
        parent_stats = parent_revs.collect do |p|
          build_rev_history_status(gs, p, relevant_revs, status_cache, options)
        end

        # if this is a merge commit with multiple parents
        # we decide to use the first commit (git primary parent)
        # note that it's not really important, which one we choose
        # just make sure to use the same commit when checking for changed files
        base_stat = parent_stats.first

        changed_files = gs.changed_files(rev, parent_revs.first)

        # build list of modules in this commit
        module_dirs = base_stat.modules.collect{|m| m.dir}
        changed_files.each do |f|
          if File.basename(f.path) == RimInfo::InfoFileName
            if f.kind == :added
              module_dirs << File.dirname(f.path)
            elsif f.kind == :deleted
              module_dirs.delete(File.dirname(f.path))
            end
          end
        end

        # a module needs to be checked if any of the files within were touched
        check_dirs = module_dirs.select{|d| changed_files.any?{|f| f.path.start_with?(d)} }

        module_stats = []
        # check out all modules to be checked at once
        if check_dirs.size > 0
          gs.within_exported_rev(rev, check_dirs) do |ws|
            check_dirs.each do |d|
              module_stats << build_module_status(ws, File.join(ws, d))
            end
          end
        end
        (module_dirs - check_dirs).each do |d|
          base_mod = base_stat.modules.find{|m| m.dir == d}
          module_stats << RevStatus::ModuleStatus.new(d, base_mod.rim_info, base_mod.dirty?)
        end

        stat = RevStatus.new(module_stats)
        stat.git_rev = gs.rev_sha1(rev)
        stat.parents.concat(parent_stats)
      else
        # no parents, need to do a full check
        if options[:fast]
          stat = rev_status_fast(gs, rev)
        else
          stat = rev_status(gs, rev)
        end
      end
    else
      # first "non-relevant", do the full check
      if options[:fast]
        stat = rev_status_fast(gs, rev)
      else
        stat = rev_status(gs, rev)
      end
    end
    status_cache[rev] = stat
  end

def build_rev_history_status ( gs , rev , relevant_revs , status_cache = { } , options = { } ) return status_cache [ rev ] if status_cache [ rev ] stat = nil if relevant_revs [ rev ] parent_revs = gs . parent_revs ( rev ) if parent_revs . size > 0 parent_stats = parent_revs . collect do | p | build_rev_history_status ( gs , p , relevant_revs , status_cache , options ) end base_stat = parent_stats . first changed_files = gs . changed_files ( rev , parent_revs . first ) module_dirs = base_stat . modules . collect { | m | m . dir } changed_files . each do | f | if File . basename ( f . path ) == RimInfo :: InfoFileName if f . kind == :added module_dirs << File . dirname ( f . path ) elsif f . kind == :deleted module_dirs . delete ( File . dirname ( f . path ) ) end end end check_dirs = module_dirs . select { | d | changed_files . any? { | f | f . path . start_with? ( d ) } } module_stats = [ ] if check_dirs . size > 0 gs . within_exported_rev ( rev , check_dirs ) do | ws | check_dirs . each do | d | module_stats << build_module_status ( ws , File . join ( ws , d ) ) end end end ( module_dirs - check_dirs ) . each do | d | base_mod = base_stat . modules . find { | m | m . dir == d } module_stats << RevStatus :: ModuleStatus . new ( d , base_mod . rim_info , base_mod . dirty? ) end stat = RevStatus . new ( module_stats ) stat . git_rev = gs . rev_sha1 ( rev ) stat . parents . concat ( parent_stats ) else if options [ :fast ] stat = rev_status_fast ( gs , rev ) else stat = rev_status ( gs , rev ) end end else if options [ :fast ] stat = rev_status_fast ( gs , rev ) else stat = rev_status ( gs , rev ) end end status_cache [ rev ] = stat end

building of the status of an ancestor chain works by checking
 the dirty state of modules only when any files affecting some module
 were changed; otherwise the status of the module in the ancestor is assumed

 for this to work, the chain must be walked from older commit to newer ones

 at the end of the chain, the status must be calculated in the regular "non-fast" way

building of the status of an ancestor chain works by checking the dirty state of modules only when any files affecting some module were changed ; otherwise the status of the module in the ancestor is assumed


def rev_status_fast(git_session, rev)
    mod_dirs = module_dirs(git_session, rev)
    mod_stats = []
    git_session.within_exported_rev(rev, mod_dirs.collect{|d| "#{d}/#{RimInfo::InfoFileName}"}) do |temp_dir|
      mod_dirs.each do |rel_path|
        mod_stats << RevStatus::ModuleStatus.new(
          rel_path,
          RimInfo.from_dir("#{temp_dir}/#{rel_path}"),
          # never dirty
          false
        )
      end
    end
    stat = RevStatus.new(mod_stats)
    stat.git_rev = git_session.rev_sha1(rev)
    stat
  end

def rev_status_fast ( git_session , rev ) mod_dirs = module_dirs ( git_session , rev ) mod_stats = [ ] git_session . within_exported_rev ( rev , mod_dirs . collect { | d | "#{d}/#{RimInfo::InfoFileName}" } ) do | temp_dir | mod_dirs . each do | rel_path | mod_stats << RevStatus :: ModuleStatus . new ( rel_path , RimInfo . from_dir ( "#{temp_dir}/#{rel_path}" ) , false ) end end stat = RevStatus . new ( mod_stats ) stat . git_rev = git_session . rev_sha1 ( rev ) stat end

creates a RevStatus object for +rev+ with all modules assumend to be clean

creates a RevStatus object for + rev + with all modules assumend to be clean


def sync(message = nil, rebase = nil, split = true)
    # get the name of the current workspace branch
    RIM::git_session(@ws_root) do |s|
      branch = s.current_branch || ''
      rim_branch = "rim/" + branch
      branch_sha1 = nil
      changed_modules = nil
      if branch.empty?
        raise RimException.new("Not on a git branch.")
      elsif branch.start_with?("rim/")
        raise RimException.new("The current git branch '#{branch}' is a rim integration branch. Please switch to a non rim branch to proceed.")
      else
        branch = "refs/heads/#{branch}"
        branch_sha1 = s.rev_sha1(rim_branch)
        remote_rev = get_latest_remote_revision(s, branch)
        rev = get_latest_clean_path_revision(s, branch, remote_rev)
        if !s.has_branch?(rim_branch) || has_ancestor?(s, branch, s.rev_sha1(rim_branch)) || !has_ancestor?(s, rim_branch, remote_rev)
          s.execute("git branch -f #{rim_branch} #{rev}")
          branch_sha1 = s.rev_sha1(rim_branch)
        end
        remote_url = "file://" + @ws_root
        @logger.debug("Folder for temporary git repositories: #{@rim_path}")
        tmpdir = clone_or_fetch_repository(remote_url, module_tmp_git_path(".ws"), "Cloning workspace git...")
        RIM::git_session(tmpdir) do |tmp_session|
          tmp_session.execute("git reset --hard")
          tmp_session.execute("git clean -xdf")
          # use -f here to prevent git checkout from checking for untracked files which might be overwritten.
          # this is safe since we removed any untracked files before.
          # this is a workaround for a name case problem on windows:
          # if a file's name changes case between the current head and the checkout target,
          # git checkout will report the file with the new name as untracked and will fail
          tmp_session.execute("git checkout -B #{rim_branch} -f remotes/origin/#{rim_branch}")
          changed_modules = sync_modules(tmp_session, message)
          if !split
            tmp_session.execute("git reset --soft #{branch_sha1}")
            commit(tmp_session, message ? message : get_commit_message(changed_modules)) if tmp_session.uncommited_changes?
          end
          tmp_session.execute("git push #{remote_url} #{rim_branch}:#{rim_branch}")
        end
      end
      if !changed_modules.empty?
        if rebase
          s.execute("git rebase #{rim_branch}")
          @logger.info("Changes have been commited to branch #{rim_branch} and workspace has been rebased successfully.")
        else
          @logger.info("Changes have been commited to branch #{rim_branch}. Rebase to apply changes to workspace.")
        end
      else
        @logger.info("No changes.")
      end
    end
  end


def sync_modules(session, message)
    module_helpers = []
    @module_infos.each do |module_info|
      module_helpers.push(SyncModuleHelper.new(session.execute_dir, @ws_root, module_info, @logger))
    end
    changed_modules = []
    module_helpers.each do |m|
      @logger.info("Synchronizing #{m.module_info.local_path}...")
      if m.sync(message)
        changed_modules << m.module_info
      end
    end
    changed_modules
  end


def has_ancestor?(session, rev, ancestor)
    # make sure we deal only with sha1s
    rev = session.rev_sha1(rev)
    return rev == ancestor || session.is_ancestor?(ancestor, rev)
  end

def has_ancestor? ( session , rev , ancestor ) rev = session . rev_sha1 ( rev ) return rev == ancestor || session . is_ancestor? ( ancestor , rev ) end

check whether revision has a given ancestor


def get_parent(session, rev)
    parents = session.parent_revs(rev)
    !parents.empty? ? parents.first : nil
  end

def get_parent ( session , rev ) parents = session . parent_revs ( rev ) ! parents . empty? ? parents . first : nil end


def get_commit_message(changed_modules)
    StringIO.open do |s|
      s.puts "rim sync."
      s.puts
      changed_modules.each do |m|
        s.puts m.local_path
      end
      s.string
    end
  end

def
get_commit_message
(
changed_modules
)
StringIO
.
open
do
|
s
|
s
.
puts
"rim sync."
s
.
puts
changed_modules
.
each
do
|
m
|
s
.
puts
m
.
local_path
end
s
.
string
end
end

create default commit message from array of changed modules


def pmmap_ext(data)
    pmmap_ext = ['addr', 'perms', 'path', 'rss', 'size', 'pss',
                 'shared_clean', 'shared_dirty', 'private_clean',
                 'private_dirty', 'referenced', 'anonymous', 'swap']
    os_list = []
    data.each do |datum|
      os = OpenStruct.new
      pmmap_ext.each_index {|i| os[pmmap_ext[i]] = datum[i]}
      os_list.push(os)
    end
    os_list
  end

def pmmap_ext ( data ) pmmap_ext = [ 'addr' , 'perms' , 'path' , 'rss' , 'size' , 'pss' , 'shared_clean' , 'shared_dirty' , 'private_clean' , 'private_dirty' , 'referenced' , 'anonymous' , 'swap' ] os_list = [ ] data . each do | datum | os = OpenStruct . new pmmap_ext . each_index { | i | os [ pmmap_ext [ i ] ] = datum [ i ] } os_list . push ( os ) end os_list end


def pmmap_grouped(data)
    pmmap_grouped = ['rss', 'size', 'pss', 'shared_clean',
                     'shared_dirty', 'private_clean', 'private_dirty',
                     'referenced', 'anonymous', 'swap']
    os_list = []
    data.each do |k, v|
      os = OpenStruct.new
      os.path = k
      pmmap_grouped.each_index {|i| os[pmmap_grouped[i]] = v[i]}
      os_list.push(os)
    end
    os_list
  end

def pmmap_grouped ( data ) pmmap_grouped = [ 'rss' , 'size' , 'pss' , 'shared_clean' , 'shared_dirty' , 'private_clean' , 'private_dirty' , 'referenced' , 'anonymous' , 'swap' ] os_list = [ ] data . each do | k , v | os = OpenStruct . new os . path = k pmmap_grouped . each_index { | i | os [ pmmap_grouped [ i ] ] = v [ i ] } os_list . push ( os ) end os_list end


def calc_checksum(mi, dir)
    if check_required_attributes(mi)
      sha1 = Digest::SHA1.new
      # all files and directories within dir
      files = FileHelper.find_matching_files(dir, false, "/**/*", File::FNM_DOTMATCH)
      # Dir.glob with FNM_DOTMATCH might return . and ..
      files.delete(".")
      files.delete("..")
      # ignore the info file itself
      files.delete(RimInfo::InfoFileName)
      # ignores defined by user
      files -= FileHelper.find_matching_files(dir, false, mi.ignores)
      # order of files makes a difference
      # sort to eliminate platform specific glob behavior
      files.sort!
      files.each do |fn|
        update_file(sha1, dir, fn)
      end
      ChecksumAttributes.each do |a|
        sha1.update(mi.send(a))
      end
      sha1.hexdigest
    else
      # can't calc checksum
      nil
    end
  end

def calc_checksum ( mi , dir ) if check_required_attributes ( mi ) sha1 = Digest :: SHA1 . new files = FileHelper . find_matching_files ( dir , false , "/**/*" , File :: FNM_DOTMATCH ) files . delete ( "." ) files . delete ( ".." ) files . delete ( RimInfo :: InfoFileName ) files -= FileHelper . find_matching_files ( dir , false , mi . ignores ) files . sort! files . each do | fn | update_file ( sha1 , dir , fn ) end ChecksumAttributes . each do | a | sha1 . update ( mi . send ( a ) ) end sha1 . hexdigest else nil end end

returns nil if checksum can't be calculated due to missing info

returns nil if checksum can t be calculated due to missing info


def current_branch
    out = execute "git branch"
    out.split("\n").each do |l|
      if !l.include?('(') && (l =~ /^\*\s+(\S+)/)
        return $1
      end
    end
    nil
  end

def
current_branch
out
=
execute
"git branch"
out
.
split
(
"\n"
)
.
each
do
|
l
|
if
!
l
.
include?
(
'('
)
&&
(
l
=~
/
\*
\s
\S
/
)
return
$1
end
end
end


def has_remote_branch?(branch)
    out = execute("git ls-remote --heads")
    out.split("\n").each do |l|
      return true if l.split(/\s+/)[1] == "refs/heads/#{branch}"
    end
    false
  end

def
has_remote_branch?
(
branch
)
out
=
execute
(
"git ls-remote --heads"
)
out
.
split
(
"\n"
)
.
each
do
|
l
|
return
true
if
l
.
split
(
/
\s
/
)
[
1
]
==
"refs/heads/#{branch}"
end
false
end


def rev_sha1(rev)
    sha1 = nil
    execute "git rev-list -n 1 #{rev} --" do |out, e|
      sha1 = out.strip if !e
    end
    sha1
  end

def
rev_sha1
(
rev
)
sha1
=
execute
"git rev-list -n 1 #{rev} --"
do
|
out
,
e
|
sha1
=
out
.
strip
if
!
e
end
sha1
end

returns the SHA - 1 representation of rev


def rev_infos(rev, desired)
    info = {}
    desired.each_pair do |key, value|
      execute "git log -1 --format=#{value} #{rev} --" do |out, e|
        info[key] = out.strip if !e
      end
    end
    info
  end

returns some informations about a revision


def remote_branch_revs
    out = execute "git show-ref"
    out.split("\n").collect { |l|
      if l =~ /refs\/remotes\//
        l.split[0]
      else
        nil
      end
    }.compact
  end

def
remote_branch_revs
out
=
execute
"git show-ref"
out
.
split
(
"\n"
)
.
collect
{
|
l
|
if
l
=~
/
\/
\/
/
l
.
split
[
0
]
else
end
}
.
compact
end

returns the SHA-1 representations of the heads of all remote branches

returns the SHA - 1 representations of the heads of all remote branches


def export_rev(rev, dir, paths=[])
    paths = paths.dup
    loop do
      path_args = ""
      # max command line length on Windows XP and higher is 8191
      # consider the following extra characters which will be added:
      # up to 3 paths in execute, 1 path for tar, max path length 260 = 1040
      # plus some "glue" characters, plus the last path item with 260 max;
      # use 6000 to be on the safe side
      while !paths.empty? && path_args.size < 6000
        path_args << " "
        path_args << paths.shift
      end
      execute "git archive --format tar #{rev} #{path_args} | tar -C #{dir} -xf -"
      break if paths.empty?
    end
  end

export file contents of rev to dir
 if +paths+ is given and non-empty, checks out only those parts of the filesystem tree
 does not remove any files from dir which existed before

export file contents of rev to dir if + paths + is given and non - empty checks out only those parts of the filesystem tree does not remove any files from dir which existed before


def within_exported_rev(rev, paths=[])
    Dir.mktmpdir("rim") do |d|
      d = Dir.glob(d)[0]
      c = File.join(d, "content")
      FileUtils.mkdir(c)
      export_rev(rev, c, paths)
      # return contents of yielded block
      # mktmpdir returns value return by our block
      yield c
      FileUtils.rm_rf(c)
      # retry to delete if it hasn't been deleted yet
      # this could be due to Windows keeping the files locked for some time
      # this is especially a problem if the machine is at its limits
      retries = 600
      while File.exist?(c) && retries > 0
        sleep(0.1)
        FileUtils.rm_rf(c)
        retries -= 1
      end
      if File.exist?(c)
        @logger.warn "could not delete temp dir: #{c}"
      end
    end
  end

def
within_exported_rev
(
rev
,
paths
=
[
]
)
Dir
.
mktmpdir
(
"rim"
)
do
|
d
|
d
=
Dir
.
glob
(
d
)
[
0
]
c
=
File
.
join
(
d
,
"content"
)
FileUtils
.
mkdir
(
c
)
export_rev
(
rev
,
c
,
paths
)
yield
c
FileUtils
.
rm_rf
(
c
)
retries
=
600
while
File
.
exist?
(
c
)
&&
retries
>
0
sleep
(
0.1
)
FileUtils
.
rm_rf
(
c
)
retries
-=
1
end
if
File
.
exist?
(
c
)
@logger
.
warn
"could not delete temp dir: #{c}"
end
end
end

checks out rev to a temporary directory and yields this directory to the given block
 if +paths+ is given and non-empty, checks out only those parts of the filesystem tree
 returns the value returned by the block

checks out rev to a temporary directory and yields this directory to the given block if + paths + is given and non - empty checks out only those parts of the filesystem tree returns the value returned by the block


def upload
    # get the name of the current workspace branch
    RIM::git_session(@ws_root) do |s|
      branch = s.current_branch
      if branch.nil?
        raise RimException.new("Not on a git branch.")
      elsif !branch.start_with?("rim/")
        begin
          sha1 = s.rev_sha1(branch)
          @logger.info("Uploading modules...")
          upload_modules(get_upload_revisions(s, sha1))
        ensure
          s.execute("git checkout -B #{branch}")
        end
      else
        raise RimException.new("The current git branch '#{branch}' is a rim integration branch. Please switch to a non rim branch to proceed.")
      end
    end
  end

upload all module changes into corresponding remote repositories


def upload_modules(info)
    each_module_parallel("uploading", @module_helpers) do |m|
      m.upload(info.parent, info.sha1s)
    end
  end

def upload_modules ( info ) each_module_parallel ( "uploading" , @module_helpers ) do | m | m . upload ( info . parent , info . sha1s ) end end


def get_upload_revisions(session, rev)
    # remote revs are where we stop traversal
    non_remote_revs = {}
    session.all_reachable_non_remote_revs(rev).each do |r|
      non_remote_revs[r] = true
    end
    revisions = []
    # make sure we deal only with sha1s
    rev = session.rev_sha1(rev)
    while rev && non_remote_revs[rev]
      revisions.push(rev)
      parents = session.parent_revs(rev)
      rev = parents.size > 0 ? parents.first : nil
    end
    Struct.new(:parent, :sha1s).new(rev, revisions.reverse!)
  end

def get_upload_revisions ( session , rev ) non_remote_revs = { } session . all_reachable_non_remote_revs ( rev ) . each do | r | non_remote_revs [ r ] = true end revisions = [ ] rev = session . rev_sha1 ( rev ) while rev && non_remote_revs [ rev ] revisions . push ( rev ) parents = session . parent_revs ( rev ) rev = parents . size > 0 ? parents . first : nil end Struct . new ( :parent , :sha1s ) . new ( rev , revisions . reverse! ) end

get revisions to upload i.e. the revisions up to the last remote revision
 the function returns the revisions in order of appearal i.e. the oldest first

get revisions to upload i . e . the revisions up to the last remote revision the function returns the revisions in order of appearal i . e . the oldest first


def fetch_module
    FileUtils.mkdir_p git_path
    RIM::git_session(git_path) do |s|
      if !File.exist?(git_path + "/config")
        s.execute("git clone --mirror #{@remote_url} #{git_path}") do |out, e|
          raise RimException.new("Remote repository '#{@remote_url}' of module '#{@module_info.local_path}' not found.") if e
        end
      else
        s.execute("git remote update")
      end
    end
    git_path
  end

fetch module +mod+ into the .rim folder
 works both for initial fetch and updates

fetch module + mod + into the . rim folder works both for initial fetch and updates


def assign(attribute, value)
      unless value == :skip || attribute == :class
        if item.respond_to?("#{attribute}=")
          item.send("#{attribute}=", value)
        elsif item.is_a?(Hash)
          item[attribute] = value
        end
      end
    end

def assign ( attribute , value ) unless value == :skip || attribute == :class if item . respond_to? ( "#{attribute}=" ) item . send ( "#{attribute}=" , value ) elsif item . is_a? ( Hash ) item [ attribute ] = value end end end

Assign the value to the given attribute of the item


def debug(*args)
      item = build(*args)
      invalid_item = Array(item).find(&:invalid?)
      if invalid_item
        if invalid_item.errors.respond_to?(:messages)
          errors = invalid_item.errors.messages
        else
          errors = invalid_item.errors
        end
        raise "Oops, the #{invalid_item.class} created by the Factory has the following errors: #{errors}"
      end
      item
    end

Can be left in your tests as an alternative to build and to warn if your factory method
 ever starts producing invalid instances


def crank_it(what, overrides)
        if what.to_s =~ /(.*)_attrs$/
          what = $1
          overrides = overrides.merge(:_return_attributes => true)
        end
        item = "TBD"
        new_job(what, overrides) do
          item = self.send(what)        # Invoke the factory method
          item = apply_traits(what, item)
        end
        item
      end

def crank_it ( what , overrides ) if what . to_s =~ / / what = $1 overrides = overrides . merge ( :_return_attributes => true ) end item = "TBD" new_job ( what , overrides ) do item = self . send ( what ) item = apply_traits ( what , item ) end item end

Execute the requested factory method, crank out the target object!

Execute the requested factory method crank out the target object!


def method_missing(method, *args, &block)
      if view_context.respond_to?(method, true)
        view_context.send(method, *args, &block)
      else
        super
      end
    end

def method_missing ( method , * args , & block ) if view_context . respond_to? ( method , true ) view_context . send ( method , * args , & block ) else super end end

Send missing methods to view_context first


def present(object, presenter: nil, **args)
      if object.respond_to?(:to_ary)
        object.map { |item| present(item, presenter: presenter, **args) }
      else
        presenter ||= presenter_klass(object)
        wrapper = presenter.new(object, view_context, **args)
        block_given? ? yield(wrapper) : wrapper
      end
    end

def present ( object , presenter : nil , ** args ) if object . respond_to? ( :to_ary ) object . map { | item | present ( item , presenter : presenter , ** args ) } else presenter ||= presenter_klass ( object ) wrapper = presenter . new ( object , view_context , ** args ) block_given? ? yield ( wrapper ) : wrapper end end

Wrap an object or collection of objects with a presenter class.

 object    - A ruby object. May be nil.
 presenter - A Presenter class (optional)
 args      - optional hash / kwargs passed to the presenter

 An instance of a presenter class is created. The class is
 one of the following:
 - the `presenter` argument
 - `Pres::Presenter` if object is nil
 - object.presenter_class (if that method is defined)
 - the default presenter class for the object
   (for example: User -> UserPresenter)

 Examples

 user = User.new
 present(user, cool: true)
 => #<UserPresenter object: #<User> ...>

 user = User.new
 present(user) do |up|
   up.something
 end
 up => #<UserPresenter object: #<User> ...>

 user = User.new
 present(user, presenter: NiceUserPresenter, cool: true)
 => #<NiceUserPresenter object: #<User> ...>

 class User
   def presenter_class
     MyPresenter
   end
 end
 user = User.new
 present(user)
 => #<MyPresenter object: #<User> ...>

 present([user])
 => [#<UserPresenter object: #<User> ...>]

 present(nil)
 => [#<Presenter object: nil ...>]

 Returns a new Presenter object or array of new Presenter objects
 Yields a new Presenter object if a block is given

Wrap an object or collection of objects with a presenter class .


def push(gem, method, options = {})
      push_command = PUSH_METHODS[method.to_s] or raise "Unknown Gem push method #{method.inspect}."
      push_command += [gem]
      push_command += ["--as", options[:as]] if options[:as]
      @cli_facade.execute(*push_command)
    end

Publish the gem.

 Supported options:
   :as - specify a shared account to publish the gem (Gemfury only)


def interpolate interpolant
      case @opts[:type]
      when :linear
        for_each (interpolant) { |x| linear_interpolation(x)  }
      when :cubic
        cubic_spline_interpolation interpolant
      else
        raise ArgumentError, "1 D interpolation of type #{@opts[:type]} not supported"
      end
    end

Constructor for all One Dimensional interpolation operations.

 The function values to be supplied to this class are of the form y = f(x).

 Henceforth, y will be referred to as ordinate and x as absicca. If absicca
 and ordinate arrays are not of the same length, then the effective size used
 for interpolation will be MIN(x.size, y.size).

 ==== Arguments

 * +x+ -    The collection of absiccas. Must be a 1 D NMatrix or ruby Array.

 * +y+ -    The collection of ordinates corresponding to the absicca. 'y' can
            either be a 1D NMatrix or Array OR a 2D NMatrix. In case y contains
            multiple columns, the interpolation is carried out on each column,
            unless specified.

 * +opts+ - Various options for carrying out the interpolation.

 ==== Options

 * +:type+ - The kind of interpolation that the user wants to perform. Should be
             specified as a symbol. Defaults to linear. Only linear and cubic
             interpolation supported as of now. Cubic interpolation done with splines.

 * +:sorted+ - Set this option as *true* if the absicca collection is supplied in
             the arguments in a sorted manner. If not supplied, it will be assumed
             that absiccas are not sorted and they will sorted be sorted anyway.

 * +:axis+ - In case of a multidimensional ordinate matrix, specify the column over
 which interpolation must be performed. *axis* starts indexing from 0 and should be
 lower than the number of columns in the ordinate matrix.

 * +:precision+ - Specifies the precision of the interpolated values returned. Defaults
 to 3.

 * +:yp1+ - First derivative of the 0th point (cubic spline).

 * +:ypn+ - First derivative of the last (n-1)th point (cubic spline).

 == Usage

   x = (0..9).step(1).to_a
   y = x.map { |n| Math.exp(n) }
   f = Interpolation::OneDimensional.new x,y, type: :cubic
   f.interpolate 2.5
     #=> 12.287
 Performs the actual interpolation on the value passed as an argument. Kind of
 interpolation performed is determined according to what is specified in the
 constructor.

 ==== Arguments

 * +interpolant+ - The value for which the interpolation is to be performed. Can
                   either be a Numeric, Array of Numerics or NMatrix. If multidimensional
                   NMatrix is supplied then will flatten it and interpolate over
                   all its values. Will return answer in the form of an NMatrix if
                   *interpolant* is supplied as an NMatrix.

Constructor for all One Dimensional interpolation operations .


def lines_selector_for(target, attributes)
      if (klass = @selectors.find { |s| s.handles? target, attributes })
        klass.new(target, attributes, logger: logger)
      end
    end

def lines_selector_for ( target , attributes ) if ( klass = @selectors . find { | s | s . handles? target , attributes } ) klass . new ( target , attributes , logger : logger ) end end

Finds and initializes a lines selector that can handle the specified include.

 @param target (see #process)
 @param attributes (see #process)
 @return [#to_proc, nil] an instance of lines selector, or `nil` if not found.

Finds and initializes a lines selector that can handle the specified include .


def run
      client_ip = @ip
      key = "request_count:#{client_ip}"
      result = { status: Constants::SUCCESS_STATUS, message: Constants::OK_MESSAGE }
      requests_count = @storage.get(key)
      unless requests_count
        @storage.set(key, 0)
        @storage.expire(key, @limits["time_period_seconds"])
      end
      if requests_count.to_i >= @limits["max_requests_count"]
        result[:status] = Constants::EXPIRED_STATUS
        result[:message] = message(period(key))
      else
        @storage.incr(key)
      end
      result
    end

def run client_ip = @ip key = "request_count:#{client_ip}" result = { status : Constants :: SUCCESS_STATUS , message : Constants :: OK_MESSAGE } requests_count = @storage . get ( key ) unless requests_count @storage . set ( key , 0 ) @storage . expire ( key , @limits [ "time_period_seconds" ] ) end if requests_count . to_i >= @limits [ "max_requests_count" ] result [ :status ] = Constants :: EXPIRED_STATUS result [ :message ] = message ( period ( key ) ) else @storage . incr ( key ) end result end

Create a Core object.

 @param [String] ip A name to uniquely identify this rate limit. For example, '127.0.0.1'

 @return [Core] Core instance
 Run main logic initialization, set and read Redis keys and validation requests count and time limit.

 @return [Hash] Hash with :status and :message keys


def date_select(method, options = {})
      options[:include_blank] ||= false
      options[:start_year]    ||= 1801
      options[:end_year]      ||= Time.now.year
      options[:label_for]       = "#{object_name}_#{method}_1i"
      build_shell(method, options) { super }
    end

def date_select ( method , options = { } ) options [ :include_blank ] ||= false options [ :start_year ] ||= 1801 options [ :end_year ] ||= Time . now . year options [ :label_for ] = "#{object_name}_#{method}_1i" build_shell ( method , options ) { super } end


def label(method, text = nil, options = {})
      colon = false if options[:colon].nil?
      options[:for] = options[:label_for]
      required = options[:required]

      # remove special options
      options.delete :colon
      options.delete :label_for
      options.delete :required

      text = @template.send(:h, text.blank?? method.to_s.humanize : text.to_s)
      text << ':'.html_safe if colon
      text << @template.content_tag(:span, "*", :class => "required") if required
      super
    end

def label ( method , text = nil , options = { } ) colon = false if options [ :colon ] . nil? options [ :for ] = options [ :label_for ] required = options [ :required ] options . delete :colon options . delete :label_for options . delete :required text = @template . send ( :h , text . blank? ? method . to_s . humanize : text . to_s ) text << ':' . html_safe if colon text << @template . content_tag ( :span , "*" , :class => "required" ) if required super end


def read(raw, predecessors=nil)
        if raw.respond_to?(:read)
          raw = raw.read(self.sizeof())
        end
        if raw.size < self.sizeof()
          raise(ReadError, "Expected #{self.sizeof} bytes, but only got #{raw.size} bytes")
        end

        vals =
          if @unpack_cb
            @unpack_cb.call(raw, predecessors)
          else
            raw.unpack(self.format)
          end
        return(self.claim_value(vals, predecessors))
      end

Called when parsing. While you can override this in subclasses,
 in general it is probably better to use the 'on_unpack' method
 to define a proc to handle unpacking for special cases.

Called when parsing . While you can override this in subclasses in general it is probably better to use the on_unpack method to define a proc to handle unpacking for special cases .


def pack_value(val, obj=nil)
        begin
          if @pack_cb
            @pack_cb.call(val, obj)
          else
            varray = val.is_a?(Array) ? val : [val]
            varray.pack(self.format)
          end
        rescue => e
          raise(PackError, "Error packing #{val.inspect} as type #{self.name.inspect} -- #{e.class} -> #{e}")
        end
      end

Called when composing raw data. While you can override this in
 subclasses, in general it is probably better to use the 'on_pack'
 method to define a proc to handle packing for special cases.

Called when composing raw data . While you can override this in subclasses in general it is probably better to use the on_pack method to define a proc to handle packing for special cases .


def method_missing(sym, *args, &block)
      #
      # Note: Be sure that the symbol does not contain the word "test". test
      # is a private method on Ruby objects and will cause the Be and Has
      # matches to fail.
      #
      return Lebowski::RSpec::Matchers::Be.new(sym, *args) if sym.to_s =~ /^be_/
      return Lebowski::RSpec::Matchers::Has.new(sym, *args) if sym.to_s =~ /^have_/
      return Lebowski::RSpec::Operators::That.new(sym, *args) if sym.to_s =~ /^that_/
      super
    end

def method_missing ( sym , * args , & block ) return Lebowski :: RSpec :: Matchers :: Be . new ( sym , * args ) if sym . to_s =~ / / return Lebowski :: RSpec :: Matchers :: Has . new ( sym , * args ) if sym . to_s =~ / / return Lebowski :: RSpec :: Operators :: That . new ( sym , * args ) if sym . to_s =~ / / super end

Replacing RSpec's default method_missing implementation so that we can
 include our own special default hooks that allows spec tests to look
 more readable.

 Ideally it would have been better if RSpec provided some nice hooks to
 try other default pattern matchers

Replacing RSpec s default method_missing implementation so that we can include our own special default hooks that allows spec tests to look more readable .


def static_files
      source = File.dirname(ENGINE.assets_path)
      asset_files.map do |file|
        dir = File.dirname(file)
        file_name = File.basename(file)
        Jekyll::StaticFile.new @site, source, dir, file_name
      end
    end

def static_files source = File . dirname ( ENGINE . assets_path ) asset_files . map do | file | dir = File . dirname ( file ) file_name = File . basename ( file ) Jekyll :: StaticFile . new @site , source , dir , file_name end end

This method searches for folders and files in the assets root directory.
 After searching all files stores in an array and then copying to
 the folder "_site".

This method searches for folders and files in the assets root directory . After searching all files stores in an array and then copying to the folder _site .


def asset_files
      asset_files = []
      Find.find(ENGINE.assets_path).each do |path|
        next if File.directory?(path)
        next if path.include?(ENGINE.stylesheets_sass_path)
        asset_files << path.sub(ENGINE.assets_path, 'assets')
      end
      asset_files
    end

def asset_files asset_files = [ ] Find . find ( ENGINE . assets_path ) . each do | path | next if File . directory? ( path ) next if path . include? ( ENGINE . stylesheets_sass_path ) asset_files << path . sub ( ENGINE . assets_path , 'assets' ) end asset_files end


def daily(time = Date.today, page_size = 50)
      time      = time.strftime("%Y-%m-%d") unless time.is_a?(String)
      report_id = run_report_request('DailyActivityReport', {'report_date' => time}, page_size)

      meta_data = get_meta_data_request(report_id)

      data = []
      meta_data["numberOfPages"].to_i.times do |page_num|
        data += get_data_request(report_id, page_num + 1) #it's zero indexed
      end
      data
    end

def daily ( time = Date . today , page_size = 50 ) time = time . strftime ( "%Y-%m-%d" ) unless time . is_a? ( String ) report_id = run_report_request ( 'DailyActivityReport' , { 'report_date' => time } , page_size ) meta_data = get_meta_data_request ( report_id ) data = [ ] meta_data [ "numberOfPages" ] . to_i . times do | page_num | data += get_data_request ( report_id , page_num + 1 ) end data end


def run_report_request(report_name, report_params = {}, page_size = 50)
      response = request 'runReportRequest' do |xml|
        xml.reportName report_name
        report_params.each do |name, value|
          xml.reportParam do
            xml.paramName name
            xml.paramValue value
          end
        end
        xml.pageSize page_size
      end

      response.elements["runReportResponse/reportId"].get_text.value
    end

def run_report_request ( report_name , report_params = { } , page_size = 50 ) response = request 'runReportRequest' do | xml | xml . reportName report_name report_params . each do | name , value | xml . reportParam do xml . paramName name xml . paramValue value end end xml . pageSize page_size end response . elements [ "runReportResponse/reportId" ] . get_text . value end


def generate_unique(length = 32, &blk)
      unique = generate_random(length)
      unique = generate_random(length) until blk.call(unique)
      unique
    end

def generate_unique ( length = 32 , & blk ) unique = generate_random ( length ) unique = generate_random ( length ) until blk . call ( unique ) unique end


def draw_paperback(qr_code:, sixword_lines:, sixword_bytes:, labels:,
                     passphrase_sha: nil, passphrase_len: nil,
                     sixword_font_size: nil, base64_content: nil,
                     base64_bytes: nil)
    unless qr_code.is_a?(RQRCode::QRCode)
      raise ArgumentError.new('qr_code must be RQRCode::QRCode')
    end

    # Header & QR code page
    pdf.font('Times-Roman')

    debug_draw_axes

    draw_header(labels: labels, passphrase_sha: passphrase_sha,
                passphrase_len: passphrase_len)

    add_newline

    draw_qr_code(qr_modules: qr_code.modules)

    pdf.stroke_color '000000'
    pdf.fill_color '000000'

    # Sixword page

    pdf.start_new_page

    draw_sixword(lines: sixword_lines, sixword_bytes: sixword_bytes,
                 font_size: sixword_font_size,
                 is_encrypted: passphrase_len)

    if base64_content
      draw_base64(b64_content: base64_content, b64_bytes: base64_bytes,
                  is_encrypted: passphrase_len)
    end

    pdf.number_pages('<page> of <total>', align: :right,
                     at: [pdf.bounds.right - 100, -2])
  end

def
draw_paperback
(
qr_code
:
,
sixword_lines
:
,
sixword_bytes
:
,
labels
:
,
passphrase_sha
:
,
passphrase_len
:
,
sixword_font_size
:
,
base64_content
:
,
base64_bytes
:
)
unless
qr_code
.
is_a?
(
RQRCode
::
QRCode
)
raise
ArgumentError
.
new
(
'qr_code must be RQRCode::QRCode'
)
end
pdf
.
font
(
'Times-Roman'
)
debug_draw_axes
draw_header
(
labels
:
labels
,
passphrase_sha
:
passphrase_sha
,
passphrase_len
:
passphrase_len
)
add_newline
draw_qr_code
(
qr_modules
:
qr_code
.
modules
)
pdf
.
stroke_color
'000000'
pdf
.
fill_color
'000000'
pdf
.
start_new_page
draw_sixword
(
lines
:
sixword_lines
,
sixword_bytes
:
sixword_bytes
,
font_size
:
sixword_font_size
,
is_encrypted
:
passphrase_len
)
if
base64_content
draw_base64
(
b64_content
:
base64_content
,
b64_bytes
:
base64_bytes
,
is_encrypted
:
passphrase_len
)
end
pdf
.
number_pages
(
'<page> of <total>'
,
align
:
:right
,
at
:
[
pdf
.
bounds
.
right
100
,
2
]
)
end

High level method to draw the paperback content on the pdf document

 @param qr_code
 @param sixword_lines
 @param sixword_bytes
 @param labels
 @param passphrase_sha
 @param [Integer, nil] passphrase_len Length of the passphrase used to
   encrypt the original content. If this is not provided, then assume the
   original content was not encrypted and skip adding gpg -d instructions.
 @param [Integer] sixword_font_size The font size to use for Sixword text
 @param [String,nil] base64_content If provided, then append the original
   content (possibly encrypted) encoded using Base64.
 @param [Integer, nil] base64_bytes The length of the original content
   before encoding to base64. This is used for the informational header.


def produce_report(*args)
      # Check xcov availability, install it if needed
      `gem install xcov` unless xcov_available?
      unless xcov_available?
        puts "xcov is not available on this machine"
        return
      end

      require "xcov"
      require "fastlane_core"

      # Init Xcov
      config = FastlaneCore::Configuration.create(Xcov::Options.available_options, convert_options(args.first))
      Xcov.config = config
      Xcov.ignore_handler = Xcov::IgnoreHandler.new

      # Init project
      manager =  Xcov::Manager.new(config)

      # Parse .xccoverage
      report_json = manager.parse_xccoverage

      # Map and process report
      process_report(Xcov::Report.map(report_json))
    end

def
produce_report
(
*
args
)
`
`
unless
xcov_available?
unless
xcov_available?
puts
"xcov is not available on this machine"
return
end
require
"xcov"
require
"fastlane_core"
config
=
FastlaneCore
::
Configuration
.
create
(
Xcov
::
Options
.
available_options
,
convert_options
(
args
.
first
)
)
Xcov
.
config
=
config
Xcov
.
ignore_handler
=
Xcov
::
IgnoreHandler
.
new
manager
=
Xcov
::
Manager
.
new
(
config
)
report_json
=
manager
.
parse_xccoverage
process_report
(
Xcov
::
Report
.
map
(
report_json
)
)
end

Produces and processes a report for use in the report method
 It takes the same arguments as report, and returns the same
 object as process_report

Produces and processes a report for use in the report method It takes the same arguments as report and returns the same object as process_report


def output_report(report)
      # Create markdown
      report_markdown = report.markdown_value

      # Send markdown
      markdown(report_markdown)

      # Notify failure if minimum coverage hasn't been reached
      threshold = Xcov.config[:minimum_coverage_percentage].to_i
      if !threshold.nil? && (report.coverage * 100) < threshold
        fail("Code coverage under minimum of #{threshold}%")
      end
    end


def process_report(report)
      file_names = @dangerfile.git.modified_files.map { |file| File.basename(file) }
      file_names += @dangerfile.git.added_files.map { |file| File.basename(file) }
      report.targets.each do |target|
        target.files = target.files.select { |file| file_names.include?(file.name) }
      end

      report
    end

def process_report ( report ) file_names = @dangerfile . git . modified_files . map { | file | File . basename ( file ) } file_names += @dangerfile . git . added_files . map { | file | File . basename ( file ) } report . targets . each do | target | target . files = target . files . select { | file | file_names . include? ( file . name ) } end report end

Filters the files that haven't been modified in the current PR

Filters the files that haven t been modified in the current PR


def update(data)
      data.each_byte do |b|
        b = revert_byte(b) if REVERSE_DATA
        @crc = ((@table[((@crc >> 8) ^ b) & 0xff] ^ (@crc << 8)) & 0xffff)
      end

      return self
    end

def update ( data ) data . each_byte do | b | b = revert_byte ( b ) if REVERSE_DATA @crc = ( ( @table [ ( ( @crc >> 8 ) ^ b ) & 0xff ] ^ ( @crc << 8 ) ) & 0xffff ) end return self end

Updates the CRC16 checksum.

 @param [String] data
   The data to update the checksum with.


def request(http_verb, url, options = {})
      full_url = url + hash_to_params(options)
      handle(access_token.request(http_verb, full_url))
    end

def request ( http_verb , url , options = { } ) full_url = url + hash_to_params ( options ) handle ( access_token . request ( http_verb , full_url ) ) end


def string(opts = {})
      length, any, value = (opts[:length] || 8), opts[:any], opts[:value]
      if value
        string = value.to_s
        Proc.new { string }
      elsif any
        Proc.new { self.any(any) }
      else
        Proc.new { Array.new(length){@chars[rand(@chars.size-1)]}.join }
      end
    end

def string ( opts = { } ) length , any , value = ( opts [ :length ] || 8 ) , opts [ :any ] , opts [ :value ] if value string = value . to_s Proc . new { string } elsif any Proc . new { self . any ( any ) } else Proc . new { Array . new ( length ) { @chars [ rand ( @chars . size - 1 ) ] } . join } end end

belows are data types
 @return Proc object which returns a random generated value, or [formatted_value, raw_value]


def convert tag, val
      return val unless val.kind_of?(String)
      case tag
      when 'partofset', 'track'
        return val
      end
      case val
      when REGEXP_TIMESTAMP
        year, month, day, hour, minute = $~.captures[0,5].map {|cap| cap.to_i}
        if month == 0 || day == 0
          return nil
        end
        second = $6.to_f
        zone = $7
        zone = '+00:00' if zone == 'Z'
        Time.new(year, month, day, hour, minute, second, zone)
      when REGEXP_RATIONAL
        return val if $2.to_i == 0
        Rational($1, $2)
      else
        val
      end
    end

def convert tag , val return val unless val . kind_of? ( String ) case tag when 'partofset' , 'track' return val end case val when REGEXP_TIMESTAMP year , month , day , hour , minute = $~ . captures [ 0 , 5 ] . map { | cap | cap . to_i } if month == 0 || day == 0 return nil end second = $6 . to_f zone = $7 zone = '+00:00' if zone == 'Z' Time . new ( year , month , day , hour , minute , second , zone ) when REGEXP_RATIONAL return val if $2 . to_i == 0 Rational ( $1 , $2 ) else val end end

Converts values on the basis of unified tag name and value. It is called
 each time a value is fethed from a Values instance.
 @return (maybe) converted value

Converts values on the basis of unified tag name and value . It is called each time a value is fethed from a Values instance .


def to_h
      @values.inject(Hash.new) do |h, a|
        tag, val = a
        h[Values.tag_map[tag]] = convert(Values.unify_tag(tag), val)
        h
      end
    end

def to_h @values . inject ( Hash . new ) do | h , a | tag , val = a h [ Values . tag_map [ tag ] ] = convert ( Values . unify_tag ( tag ) , val ) h end end

Generates a hash representation of this instance
 with original tag names es keys and converted
 values as values


def n(msg, title='', image=nil)
      Compat::UI.notify(msg, :title => title, :image => image)
    end

def n ( msg , title = '' , image = nil ) Compat :: UI . notify ( msg , :title => title , :image => image ) end


def eager(command)
      require 'pty'

      begin
        PTY.spawn command do |r, w, pid|
          begin
            $stdout.puts
            r.each {|line| print line }
          rescue Errno::EIO
            # the process has finished
          end
        end
      rescue PTY::ChildExited
        $stdout.puts "The child process exited!"
      end
    end

def
eager
(
command
)
require
'pty'
begin
PTY
.
spawn
command
do
|
r
,
w
,
pid
|
begin
$stdout
.
puts
r
.
each
{
|
line
|
print
line
}
rescue
Errno
::
EIO
end
end
rescue
PTY
::
ChildExited
$stdout
.
puts
"The child process exited!"
end
end

Eager prints the result for stdout and stderr as it would be written when
 running the command from the terminal. This is useful for long running
 tasks.

Eager prints the result for stdout and stderr as it would be written when running the command from the terminal . This is useful for long running tasks .


def wrap_list(list, width)
      list.map do |text|
        wrap_text(text, width)
      end.flatten
    end

def wrap_list ( list , width ) list . map do | text | wrap_text ( text , width ) end . flatten end