Class: Sandbox::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/sandbox/context.rb

Overview

Context

Constant Summary collapse

INVALID_CHARS =
[
  '/',
  '.',
  '\s'
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, shell, **options) ⇒ Context

Creates a new context



18
19
20
21
22
23
24
25
26
# File 'lib/sandbox/context.rb', line 18

def initialize(name, shell, **options)
  @name = name.to_sym
  @shell = shell
  @description = options[:description]

  @contexts = []
  @commands = []
  @completion_proc = nil
end

Instance Attribute Details

#commandsObject (readonly)

Returns the value of attribute commands.



13
14
15
# File 'lib/sandbox/context.rb', line 13

def commands
  @commands
end

#completion_procObject (readonly)

Returns the value of attribute completion_proc.



13
14
15
# File 'lib/sandbox/context.rb', line 13

def completion_proc
  @completion_proc
end

#contextsObject (readonly)

Returns the value of attribute contexts.



13
14
15
# File 'lib/sandbox/context.rb', line 13

def contexts
  @contexts
end

#descriptionObject

Returns the value of attribute description.



14
15
16
# File 'lib/sandbox/context.rb', line 14

def description
  @description
end

#nameObject

Returns the value of attribute name.



14
15
16
# File 'lib/sandbox/context.rb', line 14

def name
  @name
end

Instance Method Details

#add_command(name, **options, &block) ⇒ Object

Adds a command to the current context

Raises:



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/sandbox/context.rb', line 52

def add_command(name, **options, &block)
  raise ContextError, "Command #{name} contains invalid characters" if invalid_chars?(name)

  name = name.downcase.to_sym
  raise ContextError, "Context #{name} already exists in context #{self}" if context?(name)
  raise ContextError, "Command #{name} already exists in context #{self}" if command?(name)

  command = Command.new(name, @shell, self, block, **options)
  @commands << command
  command
end

#add_context(name, **options) ⇒ Object

Adds a new context to the current context

Raises:



30
31
32
33
34
35
36
37
38
39
# File 'lib/sandbox/context.rb', line 30

def add_context(name, **options)
  raise ContextError, "Context #{name} contains invalid characters" if invalid_chars?(name)

  name = name.downcase.to_sym
  raise ContextError, "Context #{name} already exists in context #{self}" if context?(name)
  raise ContextError, "Command #{name} already exists in context #{self}" if command?(name)

  @contexts << Context.new(name, @shell, **options)
  @contexts.last
end

#command(*path) ⇒ Object

Returns a command by the path



149
150
151
152
153
154
# File 'lib/sandbox/context.rb', line 149

def command(*path)
  return if path.empty?

  context = context(*path[0..-2])
  context.commands.detect { |c| c.match?(path.last) }
end

#context(*path) ⇒ Object

Returns a context by the path



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/sandbox/context.rb', line 131

def context(*path)
  return self if path.empty?

  path.map!(&:downcase)
  path.map!(&:to_sym)
  context = nil
  current = self
  path.each do |p|
    context = current.contexts.detect { |c| c.name == p }
    break if context.nil?

    current = context
  end
  context
end

#exec(shell, tokens) ⇒ Object

Executes the command in the current context



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/sandbox/context.rb', line 75

def exec(shell, tokens)
  path = tokens.first.split('/')
  if path.empty?
    shell.path.clear
    return
  end

  path_prev = shell.path.clone
  shell.path.clear if tokens.first.start_with?('/')
  if path.length > 1
    path[0..-2].each do |p|
      if p == '..'
        shell.path.pop
        next
      end

      shell.path << p.to_sym unless p.empty?
    end
  end

  if path.last == '..'
    shell.path.pop
    return
  end

  current = shell.root.context(*shell.path)
  if current.nil?
    shell.puts("Unrecognized command: #{tokens.first}")
    shell.path = path_prev
    return
  end

  current.contexts.each do |context|
    next unless context.name.to_s == path.last

    shell.path << context.name
    return nil
  end

  commands = []
  commands += current.commands
  commands += shell.root.commands.select(&:global?)
  commands.each do |command|
    next unless command.match?(path.last)

    command.exec(tokens)
    shell.path = path_prev
    return nil
  end

  shell.puts("Unrecognized command: #{tokens.first}")
  shell.path = path_prev
end

#remove_command(name) ⇒ Object

Removes a command from the current context

Raises:



66
67
68
69
70
71
# File 'lib/sandbox/context.rb', line 66

def remove_command(name)
  name = name.downcase.to_sym
  raise ContextError, "Command #{name} doesn't exists in context #{self}" unless command?(name)

  @commands.delete_if { |c| c.match?(name) }
end

#remove_context(name) ⇒ Object

Removes a context from the current context

Raises:



43
44
45
46
47
48
# File 'lib/sandbox/context.rb', line 43

def remove_context(name)
  name = name.downcase.to_sym
  raise ContextError, "Context #{name} doesn't exists in context #{self}" unless context?(name)

  @contexts.delete_if { |c| c.name == name }
end

#to_sObject

Returns the string representation of the context



158
159
160
# File 'lib/sandbox/context.rb', line 158

def to_s
  @name.to_s
end