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 +7 -0
- data/lib/FileInfo.rb +51 -0
- data/lib/alias.rb +35 -0
- data/lib/beaver.rb +60 -0
- data/lib/command.rb +105 -0
- data/lib/file_change.rb +62 -0
- data/lib/file_exists.rb +22 -0
- data/lib/file_matches.rb +26 -0
- metadata +49 -0
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
|
data/lib/file_change.rb
ADDED
@@ -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
|
data/lib/file_exists.rb
ADDED
@@ -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
|
data/lib/file_matches.rb
ADDED
@@ -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: []
|