inmake 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []