Class: GemIgnore::Main

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/gemignore/main.rb

Overview

This is where the core functionality of GemIgnore lies

Instance Method Summary collapse

Methods included from Util

#error, #msg, #notice, #prefix, #success, #table

Constructor Details

#initializeMain

Set the repository and branch where we want to retrieve the snippets from



16
17
18
19
20
21
22
23
24
# File 'lib/gemignore/main.rb', line 16

def initialize
  trap("INT") do
    error "Interrupt Signal caught. Exiting!"
    exit 1
  end

  @snippetRepository = 'github/gitignore'
  @snippetBranch = 'master'
end

Instance Method Details

#add(args) ⇒ Object

Adds the snippet to the .gitignore file in the current working directory in case it exists and the given snippet identifier matched exactly one snippet.



152
153
154
# File 'lib/gemignore/main.rb', line 152

def add(args)
  findSnippets(args) { |s| performAdd(s) }
end

#dispatch(arguments) ⇒ Object

Invokes the correct method according to the command line options that were given

Raises:



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/gemignore/main.rb', line 47

def dispatch(arguments)
  raise CommandError.new("Not enough arguments given.") if arguments.empty?

  cmd = arguments.shift # get the sub-command
  case cmd
    when "list", "l"
      list
    when "peek", "p"
      raise CommandError.new("No arguments given for 'peek' command.") if arguments.empty?
      view(arguments)
    when "search", "s"
      raise CommandError.new("No arguments given for 'search' command.") if arguments.empty?
      search(arguments)
    when "add", "a"
      raise CommandError.new("No arguments given for 'add' command.") if arguments.empty?
      add(arguments)
    when "help"
      help
    else
      raise CommandError.new("Unknown gemignore command '#{cmd}'.")
      help
  end
end

#dispatchWithErrorHandlingObject

Default entry point when running from command line



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/gemignore/main.rb', line 28

def dispatchWithErrorHandling
  debugMode = (not ARGV.delete("-d").nil?)

  begin
    dispatch(ARGV.dup)
  rescue CommandError => e
    raise e if debugMode
    error e.message
    help
    exit
  rescue Exception => e
    raise e if debugMode
    error "An error occured (are you connected to the internet?)"
    error "For more information run gemignore with the '-d' option."
  end
end

#fetch(search = nil) ⇒ Object

Fetches the list of available snippets via the GitHub API



212
213
214
215
216
217
218
219
220
221
# File 'lib/gemignore/main.rb', line 212

def fetch(search = nil)
  search = regexpForInput(search)

  files = GitHub.fileList(@snippetRepository, @snippetBranch).keys
  files.map! do |f|
    t = f.split('.')
    (t.pop; t.join('.') =~ search; $1) if t.last === 'gitignore'
  end
  files.compact
end

#fetchFile(snippet) ⇒ Object

Fetches a snippet file from GitHub

Raises:

  • (ArgumentError)


226
227
228
229
230
231
232
233
# File 'lib/gemignore/main.rb', line 226

def fetchFile(snippet)
  files = GitHub.fileList(@snippetRepository, @snippetBranch)
  sha = files["#{snippet}.gitignore"]

  raise ArgumentError.new("No gitignore snippet matching '#{snippet}' found") if sha.nil?

  GitHub.getFile(@snippetRepository, sha)
end

#findSnippets(args, &block) ⇒ Object

Searches for snippets matching the given keywords (an individual search is performed for every array element. The passed block is called with the name of every found snippet (excluding the '.gitignore' suffix)



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/gemignore/main.rb', line 160

def findSnippets(args, &block)
  keyword = args.shift
  snippets = fetch(keyword)
  snippets = searchExactMatch(snippets, keyword)

  if snippets.length < 1
    error "No snippets found for '#{keyword}'", 1
  elsif snippets.length > 1
    error "Multiple possible snippets found for '#{keyword}'.", 1
    error "Please be more specific.", 1
    snippets.each do |f|
      notice f, 2
    end
  else
    block.call snippets.first
  end

  findSnippets(args, &block) if not args.empty?
end

#gitignoreCommentForSnippet(snippet) ⇒ Object

Returns the comment that is added before a gitignore snippet



112
113
114
# File 'lib/gemignore/main.rb', line 112

def gitignoreCommentForSnippet(snippet)
  "\n\n# Added by gemignore. Snippet '#{snippet}'\n"
end

#helpObject

Displays some usage information



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/gemignore/main.rb', line 73

def help
  msg <<-BANNER
gemignore - .gitignore snippet utility
usage: gemignore <command> <input>

Available commands are (shortcut in parentheses):
  (l)ist      Lists all available snippets
  (p)eek      Show contents of given snippets
  (s)earch    Searches for snippets containing <input>
  (a)dd       Add a snippet identified by <input> to the .gitignore file in your working directory
  help        Display this message

You may use the either the full command or the shortcut, e.g.:

  gemignore add linux osx

is equivalent to

  gemignore a linux osx

BANNER
end

#listObject

Displays a list of available .gitignore snippets



118
119
120
121
# File 'lib/gemignore/main.rb', line 118

def list
  msg "Available .gitignore snippets:", 1
  puts table(fetch())
end

#performAdd(snippet) ⇒ Object

Adds the given snippet in case the .gitignore file exists.



182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/gemignore/main.rb', line 182

def performAdd(snippet)
  if not File.exists?(".gitignore")
    error "No .gitignore file found in working directory.", 1
  else
    notice "Adding Snippet '#{snippet}'.", 1

    f = File.new(".gitignore", "a")
    snippetData = fetchFile(snippet)
    f.write(gitignoreCommentForSnippet(snippet) + snippetData)
    f.close

    msg "Successfully added snippet.", 1
  end
end

#regexpForInput(input) ⇒ Object

Creates a Regexp for the given string. Will be case-insensitive if the input does not contain any uppercase characters. Wildcards are added before and after the input, so the regex will match anything containing the input, or the input itself.



202
203
204
205
206
207
# File 'lib/gemignore/main.rb', line 202

def regexpForInput(input)
  return (/(.*)/) if not input
  input = Regexp.escape(input)
  opt = input =~ /[A-Z]/ ? nil : Regexp::IGNORECASE;
  Regexp.new("(.*#{input}.*)", opt)
end

#search(args) ⇒ Object

Searches for a given snippet name



134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/gemignore/main.rb', line 134

def search(args)
  keyword = args.shift
  results = fetch(keyword)

  if(results.length < 1)
    error "No snippets found for '#{keyword}'", 1
  else
    msg "Snippets found for '#{keyword}':", 1
    puts table(results)
  end

  search(args) if not args.empty?
end

#searchExactMatch(snippets, keyword) ⇒ Object

Check if there is an case insensitive match in the fetched snippet list, in which case a list containing only that snippet is returned. Otherwise, the entire list of snippets is retuned unmodified.



100
101
102
103
104
105
106
107
108
# File 'lib/gemignore/main.rb', line 100

def searchExactMatch(snippets, keyword)
  keyword = keyword.downcase
  index = snippets.find_index { |x| x.downcase == keyword }
  if index.nil?
    snippets
  else
    [ snippets[index] ]
  end
end

#view(args) ⇒ Object

Displays the contents of the matched snippets



125
126
127
128
129
130
# File 'lib/gemignore/main.rb', line 125

def view(args)
  findSnippets(args) do |s|
    notice "Displaying snippet '#{s}'", 2
    puts fetchFile(s)
  end
end