beaver-build 0.1.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
+ SHA256:
3
+ metadata.gz: a00331b274e731341ca50bccc73fa013c5449673ee30a9beea5b0a01259ffac7
4
+ data.tar.gz: 209d69ad346136143bbc4c612f10fd22e04db7eb55b602dd02d189ef48bd6947
5
+ SHA512:
6
+ metadata.gz: 5580ebbb545b2e2a45d05db57827aaacb3bd4fd712f4f45adece1bcf8bc6600c32f207c32de0edb8c90c66286fb827052aef1fe47652f5962af34a502c19c985
7
+ data.tar.gz: 98a08e5c318ad7700b49a5362bd7f891363538f12230db73cac35eec0496a7a54d4345c04345906a97ec398cb9ab8ce095e527c7c96007046227c4839e597ba3
data/lib/FileInfo.rb ADDED
@@ -0,0 +1,51 @@
1
+ require 'json'
2
+ require 'fileutils'
3
+
4
+ # date: last modified
5
+ FileInfo = Struct.new(:date)
6
+
7
+ class FileInfoRW
8
+ # file_loc = cache file location
9
+ # file_path = path of the file that represents the cache file
10
+ def initialize(file_loc, file_path)
11
+ @file_loc = file_loc
12
+ @file_path = file_path
13
+ end
14
+
15
+ # Read the info file and write a new one if needed
16
+ # Report back if the file has changed
17
+ def file_has_changed?()
18
+ cache_file = File.open(@file_loc)
19
+
20
+ file_info = JSON.parse(cache_file.read, object_class: OpenStruct)
21
+ last_modified = File.mtime(@file_path).to_i
22
+ if last_modified > file_info.date
23
+ json = self._json
24
+ File.write(@file_loc, json)
25
+ return true
26
+ else
27
+ return false
28
+ end
29
+ end
30
+
31
+ # Create the cache file
32
+ def create_cache()
33
+ json = self._json
34
+
35
+ dirnames = File.dirname(@file_loc)
36
+ unless File.directory?(dirnames)
37
+ # Directories do not exist, create them
38
+ FileUtils.mkdir_p(dirnames)
39
+ end
40
+
41
+ File.write(@file_loc, json)
42
+ end
43
+
44
+ private
45
+ # FileInfo as json
46
+ def _json
47
+ return FileInfo.new(
48
+ File.mtime(@file_path).to_i
49
+ ).to_h.to_json
50
+ end
51
+ end
data/lib/alias.rb ADDED
@@ -0,0 +1,35 @@
1
+ # Aliases for default ruby commands for easier access by beaver users
2
+
3
+ # Execute system command
4
+ def §(cmd)
5
+ puts cmd
6
+ system cmd
7
+ end
8
+
9
+ # Execute system command
10
+ def sys(cmd)
11
+ puts cmd
12
+ system cmd
13
+ end
14
+
15
+ String.prepend(Module.new do
16
+ # The directory a file resides in
17
+ def dirname
18
+ return File.dirname self
19
+ end
20
+
21
+ # Basename of a file
22
+ def basename
23
+ return File.basename(self, ".*")
24
+ end
25
+
26
+ # File's basename with extension
27
+ def basename_ext
28
+ return File.basenam self
29
+ end
30
+
31
+ # The file's extension
32
+ def ext
33
+ return File.extname self
34
+ end
35
+ end)
data/lib/beaver.rb ADDED
@@ -0,0 +1,60 @@
1
+ require 'fileutils'
2
+
3
+ # Export functions
4
+ require 'file_change'
5
+ require 'file_exists'
6
+ require 'command'
7
+ require 'alias'
8
+
9
+ class Beaver
10
+ # The location where Beaver caches
11
+ attr_accessor :cache_loc
12
+
13
+ # Initializer should not be used outside of this module
14
+ def initialize
15
+ # Contains all commands
16
+ # [commandName: String => command: Function]
17
+ @commands = Hash.new
18
+ # Contains the main command name
19
+ @mainCommand = nil
20
+ @cache_loc = "./.beaver"
21
+ end
22
+
23
+ # Appends a command to the global beaver
24
+ def __appendCommand(name, func)
25
+ if @commands.size == 0
26
+ @mainCommand = name.to_sym
27
+ end
28
+
29
+ @commands[name.to_sym] = func
30
+ end
31
+
32
+ def __appendCommandCB(name, &func)
33
+ self.__appendCommand(name, func)
34
+ end
35
+
36
+ # Call a command
37
+ def call(cmd)
38
+ _cmd = @commands[cmd.to_sym]
39
+ if _cmd.nil?
40
+ puts "No command called #{cmd} found"
41
+ exit 1
42
+ end
43
+
44
+ _cmd.call
45
+ end
46
+
47
+ # Put this at the end of a file
48
+ def end
49
+ command = ARGV[0] || @mainCommand
50
+ self.call command
51
+ end
52
+
53
+ # Clean beaver
54
+ def clean
55
+ FileUtils.rm_r @cache_loc
56
+ end
57
+ end
58
+
59
+ # Global beaverr object@
60
+ $beaver = Beaver.new
data/lib/command.rb ADDED
@@ -0,0 +1,105 @@
1
+ require 'pathname'
2
+ require 'file_matches'
3
+
4
+ # register a new beaver command
5
+ #
6
+ # - Possible combinations
7
+ # Register a normal command
8
+ # command :name do end
9
+ # Register a command that executes if a source file changed, or the target file does not exist (one target file per source file)
10
+ # command :name, src: "", target_dir: "", target_ext: "", do end
11
+ # Register a command that executes if a source file changed, or the single target file does not exist (multiple sources into one target file)
12
+ # The callback will receive a files variables, which is a string containing all paths, separated by spaces
13
+ # command :name, src: "", target: "" do end
14
+ def command(name, src:nil, target_dir:nil, target_ext:nil, target:nil, &func)
15
+ if !src.nil? && !target_dir.nil? && !target_ext.nil?
16
+ _command_oto name, src:src, target_dir:target_dir, target_ext:target_ext do |src, trg|
17
+ func.call src, trg
18
+ end
19
+ elsif !src.nil? && !target.nil?
20
+ _command_mto name, src:src, target:target do |files, target|
21
+ func.call files, target
22
+ end
23
+ else
24
+ _command name do ||
25
+ func.call
26
+ end
27
+ end
28
+ end
29
+
30
+ # Register a new beaver command
31
+ def _command(name, &func)
32
+ $beaver.__appendCommand(name, func)
33
+ end
34
+
35
+ # Defines a dependency from source file to target file
36
+ OneWayDependency = Struct.new(:src, :target)
37
+
38
+ # - Example:
39
+ # ```ruby
40
+ # command_oto :command_name, src: "src/**/*.c", target_dir: "build", target_ext: ".o" do |source_file, target_file|
41
+ #
42
+ # end
43
+ # ```
44
+ def _command_oto(name, src: nil, target_dir: nil, target_ext: nil, &func)
45
+ $beaver.__appendCommandCB name do
46
+ src_files = get_matches(src)
47
+
48
+ abs_cd = File.dirname(File.expand_path($0))
49
+
50
+ # Contains all files with (source and target)
51
+ files = []
52
+ src_files.each do |srcfile|
53
+ file_name = File.basename(srcfile, ".*")
54
+
55
+ # path of the source file relative to the current directory
56
+ path_ext = File.dirname(
57
+ Pathname.new(File.expand_path(srcfile))
58
+ .relative_path_from(abs_cd)
59
+ )
60
+
61
+ files << OneWayDependency.new(
62
+ srcfile,
63
+ File.join(target_dir, path_ext, "#{file_name}#{target_ext}")
64
+ )
65
+ end
66
+
67
+ for file in files
68
+ should_execute = false
69
+ if file_changed?(file.src)
70
+ # If source file has changed, then the function should be called
71
+ should_execute = true
72
+ elsif !File.file?(file.target)
73
+ # If the target file does not exist, then the function should be called
74
+ should_execute = true
75
+ elsif __beaver_file_changed?
76
+ # If the beaver config file changed, then the function should be called
77
+ should_execute = true
78
+ end
79
+
80
+ if should_execute
81
+ func.call file.src, file.target
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+
88
+ def _command_mto(name, src:nil, target:nil, &func)
89
+ $beaver.__appendCommandCB name do
90
+ should_execute = false
91
+
92
+ if_any_changed src do |_|
93
+ should_execute = true
94
+ end
95
+
96
+ if !File.file?(target)
97
+ should_execute = true
98
+ end
99
+
100
+ if should_execute
101
+ src_files = get_matches(src)
102
+ func.call src_files.join(" "), target
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,62 @@
1
+ require 'file_matches'
2
+ require 'FileInfo'
3
+
4
+ # Execute a function if the specified files have changed since last execution
5
+ # Also executes the function if the config file has changed
6
+ #
7
+ # # Parameters
8
+ # - files: either an array of files (or file patterns), or a file pattern as a string or regexp
9
+ # - func: the body of the if statement
10
+ def if_changed(files, &func)
11
+ matches = get_matches(files)
12
+
13
+ # Execute for each match if either no cache exists, or
14
+ # if the cache indicates a older file version
15
+ matches.each do |file|
16
+ if file_changed?(file) || __beaver_file_changed?
17
+ func.call file
18
+ end
19
+ end
20
+ end
21
+
22
+ # Executes if any file changed
23
+ # The callback receives a list of changed files
24
+ def if_any_changed(files, &func)
25
+ changed_files = []
26
+ if_changed files do |file|
27
+ changed_files << file
28
+ end
29
+
30
+ unless changed_files.empty?
31
+ func.call changed_files
32
+ end
33
+ end
34
+
35
+ # check if a single file has changed
36
+ # returns true if it has been changed
37
+ def file_changed?(file)
38
+ cache_file_loc = "#{$beaver.cache_loc}/#{file}.info"
39
+ info_rw = FileInfoRW.new(cache_file_loc, file)
40
+ if !File.file?(cache_file_loc)
41
+ # File does not exist, so create it and call the function
42
+ info_rw.create_cache()
43
+
44
+ return true
45
+ else
46
+ # File exists, so read it
47
+ if info_rw.file_has_changed?
48
+ return true
49
+ else
50
+ return false
51
+ end
52
+ end
53
+ end
54
+
55
+ $__beaver_file = nil
56
+ def __beaver_file_changed?
57
+ if $__beaver_file == nil
58
+ $__beaver_file = file_changed?($0)
59
+ end
60
+
61
+ return $__beaver_file
62
+ end
@@ -0,0 +1,22 @@
1
+ # Executes a function if a file exists, passing in the existing file
2
+ def if_exists(files, &func)
3
+ files.each do |file|
4
+ if File.file?(file)
5
+ func.call file
6
+ end
7
+ end
8
+ end
9
+
10
+ # Executes a function if a file does not exists, passing in the non-existing file
11
+ def if_not_exists(files, &func)
12
+ files.each do |file|
13
+ unless File.file?(file)
14
+ func.call file
15
+ end
16
+ end
17
+ end
18
+
19
+ # Executes a function if a file exists, passing in the existing file
20
+ def unless_exists(files, &func)
21
+ if_not_exists(files, func)
22
+ end
@@ -0,0 +1,26 @@
1
+ def get_matches(files)
2
+ # All file patterns to process
3
+ patterns_to_process = []
4
+
5
+ # Check if array or string
6
+ if files.respond_to? :each
7
+ # is an array
8
+ patterns_to_process = file
9
+ else
10
+ patterns_to_process << files
11
+ end
12
+
13
+ # Contains all files that match the expressions
14
+ matches = nil
15
+
16
+ patterns_to_process.each do |pattern|
17
+ if pattern.is_a?(Regexp)
18
+ matches = Find.find("./").grep(pattern)
19
+ else
20
+ # is a string
21
+ matches = Dir.glob(pattern)
22
+ end
23
+ end
24
+
25
+ return matches
26
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beaver-build
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jonas Everaert
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-08-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/FileInfo.rb
20
+ - lib/alias.rb
21
+ - lib/beaver.rb
22
+ - lib/command.rb
23
+ - lib/file_change.rb
24
+ - lib/file_exists.rb
25
+ - lib/file_matches.rb
26
+ homepage: https://github.com/jomy10/beaver
27
+ licenses:
28
+ - MIT
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubygems_version: 3.3.3
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: Ruby-powered build tool
49
+ test_files: []