inmake 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c37126d894a3decaab96aee33fd26d3ee070ce37
4
+ data.tar.gz: ede65f7ae76d41696c33b3be97f0b3fdc53b12b2
5
+ SHA512:
6
+ metadata.gz: bee4047a60a0f4e645fedc5554090fa9e46de37abb9a422413253f5b950aa5dc2bc86e237f6f404a6a872599053fb5073bea1209f1f4ff098cafd8e6e174f9a7
7
+ data.tar.gz: add2a6a9c6baaaf90f5901469657cc84d8ddaa7a2afb835bf76f22c3029664f698d94035fb3561713d454d83c11e74554adce77f1decdb0b884e554298cb724d
data/bin/inmake ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'inmake'
4
+
5
+
6
+ begin
7
+ # Generate a config from command-line arguments and resolve all files to
8
+ # absolute paths
9
+ cfg = Inmake::Config.fromArguments
10
+ cfg = Inmake::Config.resolveFiles cfg
11
+
12
+ # Run inmake on all files found
13
+ runner = Inmake::Runner.new cfg
14
+
15
+ runner.run
16
+ rescue Inmake::NoFilesGiven => e
17
+ abort e.message
18
+ rescue Inmake::InvalidDirMode => e
19
+ abort e.message
20
+ rescue Inmake::InvalidVarDefinition => e
21
+ abort e.message
22
+ rescue Inmake::MultipleModeException => e
23
+ abort e.message
24
+ rescue Inmake::CommandNotFound => e
25
+ abort e.message
26
+ end
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env ruby
2
+ # echo hi from Inmake::Config!
3
+ require 'inmake/version'
4
+ module Inmake
5
+
6
+ ##
7
+ # Stores inmake configuration options.
8
+ #
9
+ class Config
10
+ attr_reader :dirMode, :searchMode, :searchArgument, :stripMatched,
11
+ :variables, :files, :variablesDisabled, :ignoreNonmatches
12
+ attr_writer :variables, :files
13
+ def initialize opts
14
+ # How we treat directories that have been passed to the file list.
15
+ # Possible values are :acceptDirs, :ignoreDirs
16
+ # :acceptDirs => directories are accepted and recursed into
17
+ # :ignoreDirs => directories are ignored
18
+ @dirMode = opts[:dirMode]
19
+ # A list of all the files that inmake will act on.
20
+ # This may include directories or relative paths.
21
+ @files = opts[:files]
22
+ # How inmake looks for the build command inside the file. Possible values
23
+ # are :prefix, :suffix, :regex, :secondLine
24
+ # :prefix => search each line start for a prefix
25
+ # :suffix => search each line ending for a suffix
26
+ # :regex => search each line via an actual regex
27
+ # :secondLine => use the second line (or third if the second looks like an
28
+ # encoding line like Python)
29
+ @searchMode = opts[:searchMode]
30
+ # An additional argument to specify the thing that the search mode uses
31
+ # to look for the build command. AKA, the actual prefix string or suffix
32
+ # string or the regex object.
33
+ @searchArgument = opts[:searchArgument]
34
+ # Do we strip all found parts of the regex from the build command?
35
+ @stripMatched = opts[:stripMatched]
36
+ # Hash of variables that can be replaced in the build command
37
+ @variables = opts[:variables]
38
+ # Are variables disabled overall? Even the builtins that is...
39
+ @variablesDisabled = opts[:variablesDisabled]
40
+ # Do we stop when a file didn't have a command inside?
41
+ @ignoreNonmatches = opts[:ignoreNonmatches]
42
+ end
43
+
44
+ def self.fromArguments
45
+ require 'optparse'
46
+
47
+ opts = {}
48
+ opts[:files] = []
49
+ opts[:variables] = {}
50
+
51
+ # Parse special arguments
52
+ OptionParser.new do |parser|
53
+ parser.banner = INMAKE_BANNER
54
+
55
+ parser.on('-f', '--file FILENAME', 'Specify a target file.') do |filename|
56
+ opts[:files] << filename
57
+ end
58
+
59
+ parser.on('-p', '--prefix PREFIX', 'Find the build command by a prefix.') do |prefix|
60
+ unless opts[:searchMode]
61
+ opts[:searchMode] = :prefix
62
+ opts[:searchArgument] = prefix
63
+ else
64
+ raise MultipleModeException, "Multiple search mode definitions!"
65
+ end
66
+ end
67
+
68
+ parser.on('-s', '--suffix SUFFIX', 'Find the build command by a suffix.') do |suffix|
69
+ unless opts[:searchMode]
70
+ opts[:searchMode] = :suffix
71
+ opts[:searchArgument] = suffix
72
+ else
73
+ raise MultipleModeException, "Multiple search mode definitions!"
74
+ end
75
+ end
76
+
77
+
78
+ okDirModes = [:acceptDirs, :ignoreDirs]
79
+ parser.on('-d', '--dir-mode MODE', "Define behavior when dealing with a directory. (default: acceptDirs) Accepted values are: #{okDirModes.join ', '}") do |dm|
80
+ dm = dm.to_sym
81
+ raise InvalidDirMode, "Not a valid directory mode: #{dm}" unless okDirModes.include? dm
82
+ opts[:dirMode] = dm
83
+ end
84
+
85
+ parser.on('-x', '--regex REGEX', 'Specify a regular expression to match the build command.') do |rx|
86
+ unless opts[:searchMode]
87
+ re = Regexp.compile rx
88
+ opts[:searchMode] = :regex
89
+ opts[:searchArgument] = re
90
+ else
91
+ raise MultipleModeException, "Multiple search mode definitions!"
92
+ end
93
+ end
94
+
95
+ parser.on('--[no-]strip-matched', 'Strip all found matches on a regex search (default: false)') do |f|
96
+ opts[:stripMatched] = f
97
+ end
98
+
99
+ parser.on('--[no-]ignore-nonmatched', 'Silently continue if a file does not seem to have a build command (default: true)') do |f|
100
+ opts[:ignoreNonmatches] = f
101
+ end
102
+
103
+ parser.on('--no-vars', 'Disable all replacement variables, even the builtin ones (default: false)') do |v|
104
+ opts[:variablesDisabled] = v
105
+ end
106
+
107
+ parser.on('-a', '--add-var KEY=VALUE', 'Add a replacement from {{KEY}} (always allcaps!) to VALUE, much like a C preprocessor definition') do |var|
108
+ key, value = var.split '='
109
+ raise InvalidVarDefinition, "Invalid variable definition syntax: `#{var}`" unless key and value
110
+
111
+ opts[:variables][key.upcase] = value
112
+ end
113
+
114
+ end.parse!
115
+
116
+ # any arguments that weren't flags are just treated as file names
117
+ unless ARGV.empty?
118
+ opts[:files].concat ARGV
119
+ end
120
+
121
+ # The default search mode is to find the build command on the second line of
122
+ # the source code.
123
+ opts[:searchMode] ||= :secondLine
124
+
125
+ # The default file mode means that if a directory is encountered, we recurse
126
+ # on all its files.
127
+ opts[:dirMode] ||= :acceptDirs
128
+
129
+ # Variables are enabled by default.
130
+ opts[:variablesDisabled] ||= false
131
+
132
+ # By default, we do not strip the matched string.
133
+ opts[:stripMatched] ||= false
134
+
135
+ opts[:ignoreNonmatched] = true unless defined? opts[:ignoreNonmatched]
136
+
137
+ # Can't run without ANY files...
138
+ raise NoFilesGiven, "No input files specified! Use #{$0} --help for how to add input files." if opts[:files].empty?
139
+
140
+ # return a new Config object
141
+ return Config.new opts
142
+ end
143
+
144
+
145
+ def self.resolveFiles cfg
146
+ newFiles = []
147
+ cfg.files.each do |f|
148
+ if File.exist? f
149
+ if File.file? f
150
+ newFiles << f
151
+ elsif File.directory? f and cfg.dirMode == :acceptDirs
152
+ newFiles.concat Dir[File.join(f, '**/*.*')].select {|x| File.file? x }
153
+ end
154
+ end
155
+ end
156
+
157
+ cfg.files = newFiles.map { |x| File.expand_path x }
158
+ cfg
159
+ end
160
+ end
161
+
162
+ ##
163
+ # Multiple search modes were defined when reading definitions from the
164
+ # command line (eg regex and prefix at the same time)
165
+ class MultipleModeException < StandardError; end
166
+ ##
167
+ # A variable was defined with wrong syntax when on the command line!
168
+ # (not something=something)
169
+ class InvalidVarDefinition < StandardError; end
170
+ ##
171
+ # No files added
172
+ class NoFilesGiven < StandardError; end
173
+ ##
174
+ # The directory handling mode was invalid!
175
+ class InvalidDirMode < StandardError; end
176
+ end
177
+
178
+ INMAKE_BANNER = <<-EOF
179
+ inmake v#{Inmake::VERSION} - the inline build command runner
180
+ Runs commands directly embedded inside your source code.
181
+ Usage: #{$0} [options...] [files]
182
+ Options:
183
+
184
+ EOF
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env ruby
2
+ # echo Hi from Inmake::Runner!
3
+ module Inmake
4
+ ##
5
+ # = Inmake Command Runner
6
+ #
7
+ # Finds and runs the commands inside all of the files.
8
+ # The same search mode is used for every file.
9
+ class Runner
10
+
11
+ # Set up a runner with a configuration object defined earlier.
12
+ def initialize cfg
13
+ @config = cfg
14
+ end
15
+
16
+ # Run inmake on each of the files defined in the configuration
17
+ def run
18
+ @config.files.each do |x|
19
+ begin
20
+ dispatch x
21
+ rescue CommandNotFound => e
22
+ raise unless @config.ignoreNonmatches
23
+ end
24
+ end
25
+ end
26
+
27
+ # Find and run a command in a given file, depending on the search mode
28
+ def dispatch file
29
+ File.open(file) do |fd|
30
+ fd.flock File::LOCK_EX
31
+ if @config.searchMode == :prefix
32
+ runPrefix fd
33
+ elsif @config.searchMode == :suffix
34
+ runSuffix fd
35
+ elsif @config.searchMode == :regex
36
+ runRegex fd
37
+ elsif @config.searchMode == :secondLine
38
+ runSecondLine fd
39
+ end
40
+ end
41
+ end
42
+
43
+ # Apply variables and then run the found build command
44
+ def applyCommand cmd, fd
45
+
46
+ unless @config.variablesDisabled
47
+ @config.variables.each do |k, v|
48
+ cmd.gsub! '{{'+k.to_s+'}}', v
49
+ end
50
+
51
+ cmd.gsub! '{{f}}', fd.path
52
+ cmd.gsub! '{{bn}}', File.basename(fd.path)
53
+ cmd.gsub! '{{bn1}}', File.basename(fd.path, '.*')
54
+ cmd.gsub! '{{ext}}', File.extname(fd.path)
55
+ cmd.gsub! '{{dn}}', File.dirname(fd.path)
56
+ st = fd.stat
57
+ cmd.gsub! '{{mode}}', st.mode.to_s
58
+ cmd.gsub! '{{mtime}}', st.mtime.to_i.to_s
59
+ cmd.gsub! '{{ctime}}', st.ctime.to_i.to_s
60
+ cmd.gsub! '{{size}}', st.size.to_s
61
+ end
62
+ fd.flock File::LOCK_UN
63
+ system cmd
64
+ puts cmd
65
+ end
66
+
67
+ # Find a given prefix in a file and apply the build command on match
68
+ def runPrefix fd
69
+ rx = /^\s*#{Regexp.escape @config.searchArgument}\s*/
70
+ command = fd.each_line.detect do |line|
71
+ rx.match line
72
+ end
73
+ raise CommandNotFound, "Did not find a prefixed command in file `#{fd.path}`" unless command
74
+ command.gsub!(rx, '')
75
+
76
+ applyCommand command, fd
77
+ end
78
+
79
+ # Find a given suffix in a file and apply the build command when matched
80
+ # Raises CommandNotFound if no command was found in a file
81
+ def runSuffix fd
82
+ rx = /#{Regexp.escape @config.searchArgument}\s*$/
83
+ command = fd.each_line.detect do |line|
84
+ rx.match line
85
+ end
86
+ raise CommandNotFound, "Did not find a suffixed command in file `#{fd.path}`" unless command
87
+ command.gsub!(rx, '') if @config.stripMatched
88
+
89
+ applyCommand command, fd
90
+ end
91
+
92
+ # Find a given regex in a file and apply the build command when matched
93
+ # Raises CommandNotFound if no command was found in a file
94
+ def runRegex fd
95
+ rx = @config.searchArgument
96
+ command = fd.each_line.detect do |line|
97
+ rx.match line
98
+ end
99
+ raise CommandNotFound, "Did not find a regex-ed command in file `#{fd.path}`" unless command
100
+ command.gsub!(rx, '') if @config.stripMatched
101
+
102
+ applyCommand command, fd
103
+ end
104
+
105
+ # Run the second line of code. This is the default option.
106
+ def runSecondLine fd
107
+ isEncodingLine = /coding[:=]\s*([-\w.]+)/
108
+ fd.gets
109
+ secondLine = fd.gets
110
+
111
+ raise CommandNotFound, "There wasn't enough data in the file `#{fd.path}` for two lines!" if $_.nil?
112
+
113
+ if isEncodingLine =~ secondLine
114
+ secondLine = fd.gets
115
+ raise CommandNotFound, "There wasn't enough data in the file `#{fd.path}` for three lines!" if $_.nil?
116
+ end
117
+
118
+ # Strip stuff until the first whitespace
119
+ command = secondLine[(secondLine =~ /\s/)...secondLine.length].strip
120
+
121
+ applyCommand command, fd
122
+ end
123
+ end
124
+ class CommandNotFound < StandardError; end
125
+ end
data/lib/inmake.rb ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ # echo Hi from inmake.rb!
3
+ require 'inmake/config'
4
+ require 'inmake/runner'
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inmake
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - boxmein
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Inline build command runner for any kind of projects.
14
+ email: boxmein@boxmein.net
15
+ executables:
16
+ - inmake
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/inmake
21
+ - lib/inmake.rb
22
+ - lib/inmake/config.rb
23
+ - lib/inmake/runner.rb
24
+ homepage: https://github.com/boxmein/inmake
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.4.1
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: Inline Build Commands
48
+ test_files: []