Module: C

Defined in:
lib/rub/c.rb,
lib/rub/r/i/runner.rb

Overview

Core Module

Defined Under Namespace

Classes: Tag, TargetTag

Class Method Summary collapse

Class Method Details

.add_dir(dir) ⇒ Object

Add a directory to the build.

This will run the “dir.rub” file in that directory synchronously. Any values that that directory defines will be available when this call returns.

This function only runs scripts once, if the script has already run this function will return success without running the script, and as the script has already been run the exported values should be available.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rub/r/i/runner.rb', line 63

def self.add_dir(dir)
	dir = C.path(dir)
	
	if not dir.directory?
		raise "\"#{dir}\" is not a directory!"
	end
	
	dir += 'dir.rub'
	if not dir.exist?
		raise "\"#{dir}\" does not exist!"
	end
	dir = dir.realpath
	
	R::I::Runner.do_file(dir)
end

.chash(o) ⇒ Object

Get a consistant hash of an object.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rub/c.rb', line 62

def self.chash(o)
	if o.is_a? Array
		return o.map{|i| chash i}.join
	end
	
	# Super hacky, strip out object-ids, because they change every
	# invocation, but use inspect.  It works alright.
	r = o.inspect.gsub(/(?<!:):0x[0-9a-f]*/, '')
	
	# Modules don't print themselfs meaningfully.
	if o.is_a? Module
		r << o.pretty_print_instance_variables.map{|k| [k, o.instance_variable_get(k)] }.inspect
	end

	r	
end

.find_command(cmd) ⇒ Pathname?

Find an executable on the system.

This searches the system for execrable in the appropriate locations (example $PATH on UNIX).

This function caches its result both in memory and between Rub runs. Feel free to call it often.

Examples:

C::find_command 'true'    #=> #<Pathname:/usr/bin/true>
C::find_command 'cc'      #=> #<Pathname:/home/kevincox/.local/bin/cc>
C::find_command 'sl'      #=> #<Pathname:/usr/bin/sl>
C::find_command 'python'  #=> #<Pathname:/usr/bin/python>
C::find_command 'explode' #=> nil

Parameters:

  • cmd (String)

    The name of the command (basename only).

Returns:

  • (Pathname, nil)

    Pathname, or nil if not found.



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/rub/c.rb', line 243

def self.find_command(cmd)
	pn = Pathname.new(cmd)
	if pn.absolute?
		#return pn.executable? ? pn : nil
		return pn
	end
	
	exe = R.spersistant["C.find_command.#{cmd}"]
	
	exe and exe.executable? and return exe
	
	exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
	names = exts.map{|e| cmd+e}
	ENV['PATH'].split(File::PATH_SEPARATOR)
	           .map{|d|Pathname.new(d)}
	           .each do |d|
		names.each do |n|
			e = d + n
			#p e
			
			if e.executable?
				exe = e
				break
			end
		end
		
		exe and break
	end
	
	R.spersistant["C.find_command.#{cmd}"] = exe
end

.generator(src, cmd, out, desc: nil) ⇒ Array<Pathname>

Add a generator to the build

This function provides a simple api for creating R::TargetGenerator targets. It creates a target that simply runs one or more commands to transform it’s inputs into outputs. This interface handles all build caching and parallelization.

Parameters:

  • src (Array<Pathname,String>, Pathname, String)

    The source file or list of source files.

  • cmd (Array<Array<Pathname,String>>, Array<Pathname,String>)

    The command or list of commands to run. Commands will run in order.

  • out (Array<Pathname,String>, Pathname, String)

    The output files of the command.

  • desc (defaults to: nil)

    The verb for this step in the process. (See R::TargetGenerator#action)

Returns:

  • (Array<Pathname>)

    The output files. This will represent the same values passed in to the out parameter but it will be a new Array and all the values will be Pathnames.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/rub/c.rb', line 208

def self.generator(src, cmd, out, desc: nil)
	t = R::TargetGenerator.new
	
	desc and t.action = desc
	
	src = R::Tool.make_set_paths(src)
	out = R::Tool.make_set_paths(out)
	cmd[0].is_a?(Array) or cmd = [cmd]
	
	t.input .merge(src)
	t.output.merge(out)
	t.add_cmds cmd
	
	t.register
	
	out
end

.glob(glob) ⇒ Set<Pathname>

Glob pathnames.

Parameters:

  • glob (String)

Returns:

  • (Set<Pathname>)

See Also:

  • Dir.glob


57
58
59
# File 'lib/rub/c.rb', line 57

def self.glob(glob)
	Set.new Dir.glob(glob).map{|e| C.path(e) }
end

.path(p) ⇒ Pathname

Expand a path.

Returns:

  • (Pathname)


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rub/c.rb', line 32

def self.path(p)
	p.is_a? Symbol   and return p
	p.is_a? Pathname and return p.expand_path
	p = p.to_s
	
	#p = case p[0]
	#	when '!'
	#		Pathname.new(p[1..-1])
	#	when '>'
	#		R::Env.out_dir + p[1..-1]
	#	when '<'
	#		R::Env.src_dir + p[1..-1]
	#	else
	#		Pathname.new(p)
	#end
	
	Pathname.new(p).expand_path
end

.tag(t) ⇒ Tag

Get a tag.

If the tag already exists it returns the existing Tag object otherwise it creates and returns a new Tag instance.

Parameters:

  • t (Symbol)

    The tag name.

Returns:

  • (Tag)

    The tag object.



179
180
181
# File 'lib/rub/c.rb', line 179

def self.tag(t)
	R.find_target(t) || Tag.new(t)
end

.unique_path(base, seed) ⇒ Object

Return a probably unique file name.

This file can be used as a build target.

Parameters:

  • base (String)

    The basename of the file.

  • seed (Object)

    A value to use for the folder name, keeping this the same across invocations allows predictable names, preventing unnecessary rebuilds.



100
101
102
# File 'lib/rub/c.rb', line 100

def self.unique_path(base, seed)
	R::Env.out_dir + 'c/unique/' + unique_segment(seed) + base
end

.unique_segment(*seed) ⇒ Object

Create a probably unique path segment.

Creates a string in the form ‘$stuff/’ that will probably be unique.

Parameters:

  • seed (Object)

    A value to use for the folder name, keeping this the same across invocations allows predictable names, preventing unnecessary rebuilds.



86
87
88
89
90
# File 'lib/rub/c.rb', line 86

def self.unique_segment(*seed)
	seed ||= caller_locations(1,1)
	
	return Digest::SHA1.hexdigest(chash(seed))
end