justprep 1.0.1 → 1.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4729fa9db5b45ee64efff9c7f0aaddbeddf6d654cfe031d1a7039a13c8deca0
4
- data.tar.gz: a2806b5e251bf062763aec4b5c1806919051a3251e42d7c03f61a557f53b9465
3
+ metadata.gz: fa284b4a811b6a6482c55b8fbb60e13e20833583d92d7b5d43672bf0dd9178a1
4
+ data.tar.gz: 592f588b3f165fa25e4fb0309f6763ceb625d8859cb6e1d80709a98bb3bd0eb8
5
5
  SHA512:
6
- metadata.gz: b27ccd199ac3f53759e0c07e039c3d5d3d4212166c5f4d6cec0fde22fb4f0281746ca7a61b690cb882280e4bdb0e45f7aee446a3696aadc40db20b9617a1117a
7
- data.tar.gz: 436b0657a5d2a66d1db74cdfb953f7a83f2b69889653bb0ad0204365a79117f8adcf086aabc7f256123adefcac8861db339362de7d46c4d4e271974e507a799f
6
+ metadata.gz: a5d250ba9b75361d51c0c756772a846199f8486b4ce2772b0c2d60e76550e9f3bde3b59ac2b3d77d249594bb30246a89de64d97e26e4089ba3dd711bacf2535d
7
+ data.tar.gz: 6dc5e9a051e6326a95decf12dae092fe9ca59d97f25344009818f784fdf47f12960ccbe007a921d46b12ff4264b6536b0a5257e5e92f7bda4dd708aafd9e27c7
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- justprep (1.0.1)
4
+ justprep (1.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,19 +1,28 @@
1
- # Justprep
1
+ # `justprep`
2
2
 
3
- A pre-processor to the "just" command-line utility packaged as a Ruby Gem.
3
+ Just a CLI pre-processor tool for task runners like "just" my current favorite.
4
4
 
5
- ## Installation
5
+ This directory is the codebase for the Ruby gem implementation. It also contains the common directory where \*.crb files are kept. These are the files that are shared between this Ruby gem implementation and the Crystal implementation.
6
6
 
7
- $ gem install justprep
7
+ ### Installation for the Ruby version
8
8
 
9
- ## Usage
9
+ gem install justprep
10
10
 
11
- See the top-level README.md file.
11
+ ### Installation for the Crystal version
12
12
 
13
- ## Contributing
13
+ brew install --build-from-source MadBomber/tap/justprep
14
+
15
+ ### Documentation
16
+
17
+ Since this capability is implemented in both Ruby and Crystal there is only one set of documentation. Both implementations act the same way. See the [repository's Wiki](https://github.com/MadBomber/justprep/wiki) for details.
18
+
19
+
20
+ ### Contributing
14
21
 
15
22
  Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/justprep.
16
23
 
24
+ If you have a different CLI task runner than what justprep currently supports, let me know so we can add it to the support list.
25
+
17
26
  ## License
18
27
 
19
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
28
+ justprep is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/bin/justprep CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'justprep'
3
+ require_relative '../lib/justprep.rb'
4
4
 
5
- Justprep.execute
5
+ Justprep.new.execute
data/justfile CHANGED
@@ -1,6 +1,5 @@
1
1
  # github.com/MadBomber/justprep/**/ruby/justfile
2
2
  #
3
- # gem install bump
4
3
 
5
4
  set positional-arguments := true
6
5
 
@@ -14,6 +13,10 @@ set positional-arguments := true
14
13
  just -l --list-prefix 'just ' --list-heading ''
15
14
  echo
16
15
 
16
+ # Run the minitest examples on the Ruby code
17
+ test: build
18
+ rake test
19
+
17
20
 
18
21
  # Build the current gem
19
22
  @build:
@@ -24,26 +27,3 @@ set positional-arguments := true
24
27
  @install:
25
28
  rake install:local
26
29
 
27
-
28
- #################################################
29
- ## Recipes that deal with the source code version
30
- ## Version manager is handled by the "bump" gem
31
-
32
- # Set the version: major . minor . patch
33
- @set version:
34
- bump set {{version}} --no-commit --replace-in ../crystal/version.cr
35
-
36
-
37
- # Show current version
38
- @show:
39
- bump current
40
-
41
-
42
- # Bump the level: major . minor . patch
43
- bump level='patch':
44
- #!/bin/bash
45
- if [[ "{{level}}" =~ ^(major|minor|patch)$ ]]; then
46
- bump {{level}} --no-commit --replace-in ../crystal/version.cr
47
- else
48
- echo "ERROR: level must be one of: major, minor, patch"
49
- fi
data/justprep.gemspec CHANGED
@@ -1,25 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "lib/justprep/version"
3
+ load "lib/justprep/common/constants.crb"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "justprep"
7
- spec.version = Justprep::VERSION
7
+ spec.version = VERSION
8
8
  spec.authors = ["Dewayne VanHoozer"]
9
9
  spec.email = ["dvanhoozer@gmail.com"]
10
10
 
11
- spec.summary = "A pre-processor for the 'just' command line utility"
11
+ spec.summary = "Just a pre-processor for CLI task runners like 'just'"
12
12
  spec.description = <<~EOS
13
- allows a "justfile" to be auto-generated from a seperate source file
14
- that contains inclusionary keywords such as include, import, require
15
- and with. These keywords are followed by a path to a file. If the
16
- file exists, the contents of the file are inserted into the file
17
- at the position of the keyword command. After all keywords have
18
- been process a new "justfile" is created which can then be used by
19
- the 'just' tool.
13
+ justprep is a CLI tool implemented as a Ruby gem AND a
14
+ compiled Crystal binary. It allows a task file to be
15
+ auto-generated from seperate source files that contain
16
+ inclusionary keywords such as include, import, require
17
+ and with.
20
18
  EOS
21
19
 
22
- spec.homepage = "http://github.com/MadBomber/justprep/tree/main/ruby"
20
+ spec.homepage = "http://github.com/MadBomber/justprep"
23
21
  spec.license = "MIT"
24
22
  spec.required_ruby_version = ">= 2.4.0"
25
23
 
@@ -0,0 +1,53 @@
1
+ VERSION = "1.2.4"
2
+
3
+ class Justprep
4
+
5
+ # define class variables used for configuration
6
+ # This helps Crystal know what the type of the varibles are.
7
+
8
+ @@justprep_for = "String"
9
+ @@justprep_module_keyword = "String"
10
+ @@justprep_keywords = ["String", "String"]
11
+ @@justprep_filename_in = "String"
12
+ @@justprep_filename_out = "String"
13
+ @@filename_option = "String"
14
+
15
+
16
+ # defining all these instance methods for Ruby's unit tests
17
+
18
+ def justprep_for ; @@justprep_for end
19
+ def justprep_module_keyword; @@justprep_module_keyword end
20
+ def justprep_keywords ; @@justprep_keywords end
21
+ def justprep_filename_in ; @@justprep_filename_in end
22
+ def justprep_filename_out ; @@justprep_filename_out end
23
+ def filename_option ; @@filename_option end
24
+
25
+
26
+ def using_just?
27
+ "just" == @@justprep_for
28
+ end
29
+
30
+
31
+ # Sets the configuration class variables from their cooresponding
32
+ # system environment variables. Any configuration coming from the
33
+ # command-line parameters are set in the handle_command_line_parameters()
34
+ # method.
35
+ #
36
+ def set_configuration
37
+ @@justprep_for = ENV.fetch("JUSTPREP_FOR", "just")
38
+ @@justprep_module_keyword = ENV.fetch("JUSTPREP_MODULE_KEYWORD", "module")
39
+ @@justprep_keywords = ENV.fetch("justprep_keywords", "import include require with").split
40
+
41
+ if using_just?
42
+ @@justprep_filename_in = ENV.fetch("JUSTPREP_FILENAME_IN", "main.just")
43
+ @@justprep_filename_out = ENV.fetch("JUSTPREP_FILENAME_OUT", "justfile")
44
+ @@filename_option = "-f"
45
+
46
+ else
47
+ @@justprep_filename_in = ENV.fetch("JUSTPREP_FILENAME_IN")
48
+ @@justprep_filename_out = ENV.fetch("JUSTPREP_FILENAME_OUT")
49
+ @@filename_option = ""
50
+ end
51
+ end
52
+
53
+ end # class Justprep
@@ -0,0 +1,71 @@
1
+ # common/error_messages.crb
2
+
3
+ class Justprep
4
+
5
+ # Parameters:
6
+ # line_number .. Integer (zero-based index)
7
+ # a_line ....... String
8
+ #
9
+ # Returns:
10
+ # nil
11
+ #
12
+ def error_file_does_not_exist(line_number, a_line)
13
+ STDERR.puts
14
+ STDERR.puts "ERROR: File Does Not Exist"
15
+
16
+ # Crystal types thinks line_number can be nil or Int32
17
+ line_out = sprintf("% d ", line_number.nil? ? 0 : line_number)
18
+ STDERR.puts (" "*line_out.size)+"|"
19
+ STDERR.puts "#{line_out}| #{a_line}"
20
+ STDERR.print (" "*line_out.size)+"|"
21
+
22
+ x = a_line.index(" ")
23
+
24
+ if a_line.starts_with?(@@justprep_module_keyword.to_s)
25
+ x = a_line.index(" ", x.nil? ? 0 : x + 1) # because Crystal thinks x could be nil
26
+ end
27
+
28
+ begin_filename = x.nil? ? a_line.size + 2 : x + 2
29
+ end_filename = a_line.size
30
+ len_filename = end_filename - begin_filename + 1
31
+
32
+ len_filename = 13 if len_filename < 0
33
+
34
+ STDERR.puts (" "*begin_filename) + ("^"*len_filename)
35
+ STDERR.puts
36
+
37
+ return nil
38
+ end
39
+
40
+
41
+ def error_syntax(line_number, a_line)
42
+ STDERR.puts
43
+ STDERR.puts "ERROR: Syntax Problem"
44
+
45
+ # Crystal types thinks line_number can be nil or Int32
46
+ line_out = sprintf("% d ", line_number.nil? ? 0 : line_number)
47
+ STDERR.puts (" "*line_out.size)+"|"
48
+ STDERR.puts "#{line_out}| #{a_line}"
49
+ STDERR.print (" "*line_out.size)+"| "
50
+ STDERR.puts "^"*(a_line.size)
51
+ STDERR.puts
52
+
53
+ return nil
54
+ end
55
+
56
+
57
+ def error_keyword_conflict
58
+ comma_space = ", "
59
+ STDERR.puts "
60
+
61
+ ERROR: There is a conflict between the environment variables
62
+ $JUSTPREP_MODULE_KEYWORD _cannot_ be in $JUSTPREP_KEYWORDS
63
+
64
+ $JUSTPREP_KEYWORDS => #{@@justprep_keywords.join(comma_space)}
65
+ $JUSTPREP_MODULE_KEYWORD => #{@@justprep_module_keyword}
66
+
67
+ "
68
+ return nil
69
+ end
70
+
71
+ end # class Justprep
@@ -0,0 +1,18 @@
1
+ # common/expand_file_path.crb
2
+
3
+ class Justprep
4
+
5
+ # use an external shell to expand system environment variables
6
+ def expand_file_path(a_path_string)
7
+ a_path_string = a_path_string.strip
8
+
9
+ if a_path_string.to_s.starts_with? "~"
10
+ a_path_string = "${HOME}" + a_path_string.to_s[1, a_path_string.to_s.size-1]
11
+ end
12
+
13
+ a_path_string = `echo "#{a_path_string}"`.chomp
14
+
15
+ return a_path_string
16
+ end
17
+
18
+ end # class Justprep
@@ -0,0 +1,61 @@
1
+ # .../ruby/lib/justprep/common/generate_module_tasks.crb
2
+
3
+ class Justprep
4
+
5
+ # Given an Array of Strings representing the fake
6
+ # module names it returns a String to be appended
7
+ # to the generated justfile.
8
+ #
9
+ # Input:
10
+ # module_names .... Array(String) fake module names
11
+ #
12
+ # Output:
13
+ # tasks ... String
14
+ #
15
+ def generate_module_tasks(module_names)
16
+ if self.using_just?
17
+ tasks = create_just_tasks(module_names)
18
+ else
19
+ tasks = "# Do not know how to make modules for #{@@justprep_for}"
20
+ end
21
+
22
+ return tasks
23
+ end
24
+
25
+
26
+ def create_just_tasks(module_names)
27
+ tasks = ""
28
+
29
+ module_names.each do |mod_name|
30
+ tasks += "
31
+
32
+ # Module #{mod_name}
33
+ @#{mod_name} what='' args='':
34
+ #{@@justprep_for} #{@@filename_option} {{module_#{mod_name}}} {{what}} {{args}}
35
+
36
+ "
37
+ end
38
+
39
+ return tasks
40
+ end
41
+
42
+
43
+ def create_run_tasks(module_names)
44
+ tasks = ""
45
+
46
+ module_names.each do |mod_name|
47
+ tasks += "
48
+
49
+ ##
50
+ # Module #{mod_name}
51
+ # Encapsulates additional tasks
52
+ #{mod_name}:
53
+ #{JUSTPREP_FOR} #{FILENAME_OPTION} ${module_#{mod_name}} ${@}
54
+
55
+ "
56
+ end
57
+
58
+ return tasks
59
+ end
60
+
61
+ end # class Justprep
@@ -0,0 +1,38 @@
1
+ # common/handle_command_line_parameters.crb
2
+
3
+ class Justprep
4
+
5
+ # take care of ARGV
6
+ #
7
+ # Returns
8
+ # nil when there are no command line parameters
9
+ # otherwise it terminates the process
10
+ #
11
+ def handle_command_line_parameters
12
+ # When true, header/footer wrappers around include content are excluded
13
+ @@no_brag = false
14
+
15
+ if ARGV.size > 0
16
+ ARGV.each do |param|
17
+ if "--version" == param
18
+ puts "jusrprep v#{VERSION} (#{IMPLEMENTATION})"
19
+ exit(1)
20
+ elsif ["-h", "--help"].includes?(param)
21
+ usage
22
+ exit(1)
23
+ elsif "--no-brag" == param
24
+ @@no_brag = true
25
+ else
26
+ STDERR.puts "justprep does not support: #{param}"
27
+ exit(1)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+ def no_brag?
35
+ @@no_brag
36
+ end
37
+
38
+ end # class Justprep
@@ -0,0 +1,26 @@
1
+ # .../ruby/lib/justprep/common/def include_content_from.crb
2
+
3
+ class Justprep
4
+
5
+ # single-level inclusion
6
+ #
7
+ # Input:
8
+ # out_file .......... A File pointer for String output
9
+ # module_filename ... String The name of the file to be included
10
+ #
11
+ # Output:
12
+ # nil .... This is a function without specific return value
13
+ #
14
+ def include_content_from(out_file, module_filename)
15
+ out_file.puts "\n# >>> #{module_filename}" unless no_brag?
16
+
17
+ File.read_lines(module_filename).each do |m_line|
18
+ out_file.puts m_line
19
+ end
20
+
21
+ out_file.puts "# <<< #{module_filename}\n" unless no_brag?
22
+
23
+ return nil
24
+ end
25
+
26
+ end # class Justprep
@@ -0,0 +1,18 @@
1
+ # common/just_find_it.crb
2
+
3
+ class Justprep
4
+
5
+ # look for first occurace of mainfile
6
+ # returns nil when none are found.
7
+ def just_find_it(here = FileUtils.pwd)
8
+ mainfile_path = here + "/" + @@justprep_filename_in.to_s
9
+ return mainfile_path if File.exists?(mainfile_path)
10
+
11
+ parts = here.to_s.split("/")
12
+ parts.pop
13
+
14
+ return nil if parts.empty?
15
+ return just_find_it(parts.join('/'))
16
+ end
17
+
18
+ end # class Justprep
@@ -0,0 +1,54 @@
1
+ # .../ruby/lig/justprep/common/replacement_for_module_line.crb
2
+
3
+ class Justprep
4
+
5
+ # Inserts the module_name into the Array of module_names
6
+ # Returns a string that defines the variable for the path to the module
7
+ #
8
+ # This method replaces a source line that looks like this:
9
+ #
10
+ # module aaa path/to/modules/justfile
11
+ #
12
+ # with a line that looks like this:
13
+ #
14
+ # module_aaa := "path/to/modules/justfile"
15
+ #
16
+ # where "aaa" is the module name.
17
+ #
18
+ # Limitations:
19
+ #
20
+ # module_name can not have a space. Only :alphanumberic: characters
21
+ # and the underscore character are valid.
22
+ #
23
+ # The "path/to/modules/justfile" must exist. Otherwise an error
24
+ # message is generated.
25
+ #
26
+ # Input:
27
+ # line_numer .... Integer the line number in the source file
28
+ # a_string ...... String the line from the source file
29
+ #
30
+ # Output:
31
+ # an Array(String) of size 2 where
32
+ # .first is the fake module_name
33
+ # .last is the replacement string that defines the module variable
34
+ #
35
+ def replacement_for_module_line(line_number, a_string)
36
+ parts = a_string.split(" ")
37
+
38
+ if parts.size < 3
39
+ error_syntax(line_number, a_string)
40
+ exit(1)
41
+ end
42
+
43
+ module_name = parts[1]
44
+ path_to_module = parts[2..].join(" ")
45
+
46
+ unless File.exists?(path_to_module)
47
+ error_file_does_not_exist(line_number, a_string)
48
+ exit(1)
49
+ end
50
+
51
+ return [module_name, "module_#{module_name} := \"#{path_to_module}\""]
52
+ end
53
+
54
+ end # class Justprep
@@ -0,0 +1,71 @@
1
+ # common/usage.crb
2
+
3
+ class Justprep
4
+
5
+ def usage
6
+ usage_text = "
7
+ justprep v#{VERSION} (#{IMPLEMENTATION})
8
+
9
+ Just a pre-processor to CLI task runners such as 'just'
10
+ By Dewayne VanHoozer <dvanhoozer@gmail.com>
11
+
12
+ USAGE:
13
+ justprep [flags]
14
+ justprep && #{@@justprep_for}
15
+
16
+ FLAGS:
17
+ --version Shows the current version
18
+ -h, --help Displays this usage message
19
+ --no-brag Do not add header/footer around included content
20
+
21
+ DESCRIPTION:
22
+ Looks for a file named #{@@justprep_filename_in} in the current
23
+ directory hierarchy. If found it replaces all lines that
24
+ have the keywords (#{@@justprep_keywords.join(", ")}) followed
25
+ by a file path with the contents of the specified file.
26
+
27
+ if it finds a line that begins with the module keyword
28
+ (#{@@justprep_module_keyword}) in sets up a fake module
29
+ system consistent with the target CLI task runner #{@@justprep_for}.
30
+
31
+ SYSTEM ENVIRONMENT VARIABLES:
32
+ Default / Current Value
33
+ JUSTPREP_FOR ............ 'just'
34
+ '#{@@justprep_for}'
35
+
36
+ JUSTPREP_FILENAME_IN .... 'main.just'
37
+ '#{@@justprep_filename_in}'
38
+
39
+ JUSTPREP_FILENAME_OUT ... 'justfile'
40
+ '#{@@justprep_filename_out}'
41
+
42
+ JUSTPREP_KEYWORDS ....... 'import include require with'
43
+ '#{@@justprep_keywords.join(' ')}'
44
+
45
+ JUSTPREP_MODULE_KEYWORD . 'module'
46
+ '#{@@justprep_module_keyword}'
47
+
48
+ DOCUMENTATION:
49
+ A full set of documentation can be found in the project's
50
+ wiki: https://github.com/MadBomber/justprep/wiki
51
+
52
+ SUGGESTION:
53
+ Create an alias for your command shell. For example
54
+ alias jj='justprep && just'
55
+
56
+ THANKS TO:
57
+ Casey Rodarmor <casey@rodarmor.com>
58
+ for Just because just is just a handy utility with just an
59
+ odd name but an extreamly useful product. :)
60
+
61
+ Greg Lutostanski <greg.luto@gmail.com>
62
+ for the homebrew formula and the github actions to compile
63
+ a new Crystal release.
64
+
65
+ "
66
+ puts usage_text
67
+
68
+ return usage_text
69
+ end
70
+
71
+ end # class Justprep
@@ -0,0 +1,26 @@
1
+ # common/crystal_methods.rb
2
+
3
+ # Monkey oatch Ruby classes to match method names
4
+ # used by Crystal
5
+
6
+ # TODO: find other classes in which Ruby/Crystal differ
7
+
8
+ module Enumerable
9
+ alias_method :includes?, :include?
10
+ end
11
+
12
+ class Pathname
13
+ alias_method :exists?, :exist?
14
+ end
15
+
16
+ class String
17
+ alias_method :starts_with?, :start_with?
18
+ alias_method :ends_with?, :end_with?
19
+ alias_method :includes?, :include?
20
+ end
21
+
22
+ class File
23
+ class << self
24
+ alias_method :read_lines, :readlines
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Justprep
4
- VERSION = "1.0.1"
4
+ VERSION = "1.0.2"
5
5
  end
data/lib/justprep.rb CHANGED
@@ -10,185 +10,118 @@
10
10
  #
11
11
  # variable name default value
12
12
  # --------------------- -------------
13
- # JUSTPREP_FILENAME_IN ... main.just
14
- # JUSTPREP_FILENAME_OUT ... justfile
13
+ # JUSTPREP_FOR ............ 'just'
14
+ # JUSTPREP_FILENAME_IN ... 'main.just'
15
+ # JUSTPREP_FILENAME_OUT ... 'justfile'
15
16
  # JUSTPREP_KEYWORDS ... 'import include require with'
17
+ # JUSTPREP_MODULE_KEYWORD . 'module'
18
+ #
19
+ # NOTE:
20
+ # JUSTPREP_KEYWORDS ** CANNOT ** include the value for
21
+ # JUSTPREP_MODULE_KEYWORD
16
22
  #
17
23
 
18
- require "pathname"
19
- require_relative "justprep/version"
20
-
21
- module Justprep
22
- class << self
23
- JUSTPREP_FILENAME_IN = ENV.fetch('JUSTPREP_FILENAME_IN', 'main.just')
24
- JUSTPREP_FILENAME_OUT = ENV.fetch('JUSTPREP_FILENAME_OUT', 'justfile')
25
- JUSTPREP_KEYWORDS = ENV.fetch('JUSTPREP_KEYWORDS', 'import include require with').split
24
+ IMPLEMENTATION = "Ruby"
26
25
 
26
+ require "fileutils"
27
+ require "pathname"
28
+ require_relative "justprep/crystal_methods"
27
29
 
28
- # review the text looking for module references
29
- def find_modules(text)
30
- modules = []
30
+ # The common directory contains files which are usable in
31
+ # both the Ruby gem and compiled Crystal implementations
32
+ # The files have the extension ".crb"
33
+ #
34
+ COMMON_DIR = Pathname.new(__FILE__) + '../justprep/common'
35
+
36
+ # Loading these common methods as global kernel-level
37
+ load COMMON_DIR + "constants.crb"
38
+ load COMMON_DIR + "error_messages.crb"
39
+ load COMMON_DIR + "expand_file_path.crb"
40
+ load COMMON_DIR + "handle_command_line_parameters.crb"
41
+ load COMMON_DIR + "just_find_it.crb"
42
+ load COMMON_DIR + "usage.crb"
43
+ load COMMON_DIR + "generate_module_tasks.crb"
44
+ load COMMON_DIR + "replacement_for_module_line.crb"
45
+ load COMMON_DIR + "include_content_from.crb"
46
+
47
+ class Justprep
48
+ attr_accessor :module_names
49
+
50
+ def initialize
51
+ set_configuration # sets class vars from envars
52
+ handle_command_line_parameters # may terminate the process
53
+ @module_names = []
54
+ end
55
+
56
+
57
+ # Main function called from executable
58
+ def execute
59
+ # SMELL: for some reason the crystal_methods alias_method of
60
+ # includes? for include? is not working.
61
+
62
+ if @@justprep_keywords.include?(@@justprep_module_keyword)
63
+ error_keyword_conflict
64
+ exit(1)
65
+ end
31
66
 
32
- JUSTPREP_KEYWORDS.each do |keyword|
33
- modules << text.select{|x| x.start_with?("#{keyword} ") || x.strip == keyword}
34
- end
67
+ in_filename = just_find_it
35
68
 
36
- return modules.flatten!
69
+ if in_filename.nil?
70
+ STDERR.puts "WARNING: $JUSTPREP_FILENAME_IN Not Found: #{@@justprep_filename_in}"
71
+ exit(0)
37
72
  end
38
73
 
74
+ out_filename = File.dirname(in_filename) + "/" + @@justprep_filename_out
39
75
 
40
- # somg;e-level inclusion
41
- def include_content_from(file_path)
42
- content = []
43
- content << "\n# >>> #{file_path}"
44
- content << file_path.readlines.map{|x| x.chomp} # TODO: support recursion??
45
- content << "# <<< #{file_path}\n"
76
+ in_file = File.open(in_filename, "r")
77
+ out_file = File.open(out_filename, "w")
46
78
 
47
- return content.flatten
48
- end
79
+ line_number = 0
49
80
 
81
+ in_file.readlines.map{|x| x.chomp}.each do |a_line|
82
+ line_number += 1
50
83
 
51
- # look for first occurace of mainfile
52
- def just_find_it(here=Pathname.pwd)
53
- mainfile = here + JUSTPREP_FILENAME_IN
54
- return mainfile if mainfile.exist?
55
- return nil if here == here.parent
56
- return just_find_it(here.parent)
57
- end
58
-
84
+ parts = a_line.to_s.split(" ")
59
85
 
60
- # use an external shell to expand system environment variables
61
- def expand_file_path(a_path_string)
62
- if a_path_string.start_with? '~'
63
- a_path_string = "${HOME}" + a_path_string[1, a_path_string.size-1]
86
+ if 0 == parts.size
87
+ out_file.puts
88
+ next
64
89
  end
65
90
 
66
- a_path_string = `echo "#{a_path_string}"`.chomp
91
+ # NOTE: Leading spaces are not allowed. The keywords
92
+ # MUST be complete left-justified.
93
+ #
94
+ if @@justprep_keywords.include?(parts.first.downcase)
95
+ out_file.puts "# #{a_line}" unless no_brag?
67
96
 
68
- return a_path_string
69
- end
97
+ glob_filename = expand_file_path(parts[1..parts.size].join(" "))
70
98
 
71
- # Print usage text
72
- def usage
73
- puts <<~EOS
74
- justprep v#{VERSION} (ruby)
75
- A pre-processor to the just command line utility
76
- By Dewayne VanHoozer <dvanhoozer@gmail.com>
77
-
78
- USAGE:
79
- justprep [flags] && just
80
-
81
- FLAGS:
82
- --version Shows the current version
83
- -h, --help Displays this usage message
84
-
85
- DESCRIPTION:
86
- Looks for a file named #{JUSTPREP_FILENAME_IN} in the current
87
- directory hierarchy. If found it replaces all lines that
88
- have the keywords (#{JUSTPREP_KEYWORDS.join(", ")}) followed
89
- by file path with the contents of the specified file.
90
-
91
- SYSTEM ENVIRONMENT VARIABLES:
92
- Default Value
93
- JUSTPREP_FILENAME_IN .... main.just
94
- JUSTPREP_FILENAME_OUT ... justfile
95
- JUSTPREP_KEYWORDS ....... 'import include require with'
96
-
97
- SUGGESTION:
98
- Create an alias for your command shell. For example
99
- alias jj='justprop && just'
100
-
101
- THANKS TO:
102
- Casey Rodarmor <casey@rodarmor.com>
103
- Just because just is just a handy utility with just an odd name. :)
104
-
105
- EOS
106
- end
99
+ module_filenames = Dir.glob(glob_filename)
107
100
 
101
+ if 0 == module_filenames.size
102
+ error_file_does_not_exist(line_number, a_line)
103
+ exit(1)
104
+ end
108
105
 
109
- # take care of ARGV processing
110
- def handle_command_line_parameters
111
- if ARGV.size > 0
112
- ARGV.each do |param|
113
- if "--version" == param
114
- puts "jusrprep v#{VERSION} (ruby)"
115
- elsif ["-h", "--help"].include?(param)
116
- usage
106
+ module_filenames.each do |module_filename|
107
+ if File.exist?(module_filename)
108
+ include_content_from(out_file, module_filename)
117
109
  else
118
- STDERR.puts "justprep does not support: #{param}"
110
+ error_file_does_not_exist(line_number, a_line)
119
111
  exit(1)
120
112
  end
121
113
  end
114
+ elsif @@justprep_module_keyword == parts.first.downcase
115
+ result_array = replacement_for_module_line(line_number, a_line)
116
+ @module_names << result_array.first
117
+ out_file.puts result_array.last
118
+ else
119
+ out_file.puts a_line
122
120
  end
123
- end
124
-
125
-
126
- # Main function called from executable
127
- def execute
128
- handle_command_line_parameters
129
-
130
- mainfile = just_find_it
131
-
132
- if mainfile.nil?
133
- STDERR.puts "WARNING: JUSTPREP_FILENAME_IN Not Found: #{JUSTPREP_FILENAME_IN}"
134
- exit(0)
135
- end
136
-
137
- basefile = mainfile.parent + JUSTPREP_FILENAME_OUT
138
-
139
- text = mainfile.readlines.map{|x| x.chomp} # drop the line ending from each line
140
-
141
- modules = find_modules text
142
-
143
- if modules.empty?
144
- basefile.write text
145
- exit(0)
146
- end
147
-
148
- modules.each do |a_line|
149
- an_index = text.index a_line
150
- begin_filename = a_line.index(' ')
121
+ end # in_file.readlines ...
151
122
 
152
- if begin_filename.nil?
153
- module_filename = ""
154
- else
155
- module_filename = a_line[begin_filename, a_line.size - begin_filename].chomp.strip
156
- end
157
-
158
- if module_filename.empty?
159
- STDERR.puts "ERROR: No path/to/file was provided"
160
- line_out = sprintf('% d ', an_index+1)
161
- STDERR.puts (" "*line_out.size)+"|"
162
- STDERR.puts "#{line_out}| #{a_line}"
163
- STDERR.print (" "*line_out.size)+"|"
164
- STDERR.puts (" "*(a_line.size+2)) + "^"
165
- exit(1)
166
- end
167
-
168
- if module_filename.include?('~') || module_filename.include?('$')
169
- module_filename = expand_file_path(module_filename)
170
- end
171
-
172
- module_path = Pathname.new(module_filename)
173
-
174
- if module_path.relative?
175
- module_path = mainfile.parent + module_path
176
- end
177
-
178
- if module_path.exist?
179
- text[an_index] = include_content_from(module_path)
180
- else
181
- STDERR.puts "ERROR: File Does Not Exist - #{module_path}"
182
- line_out = sprintf('% d ', an_index+1)
183
- STDERR.puts (" "*line_out.size)+"|"
184
- STDERR.puts "#{line_out}| #{a_line}"
185
- STDERR.print (" "*line_out.size)+"|"
186
- STDERR.puts (" "*(a_line.index(module_filename)+1)) + "^"
187
- exit(1)
188
- end
189
- end # modules.each do |a_line|
123
+ out_file.puts generate_module_tasks(@module_names)
190
124
 
191
- basefile.write text.flatten!.join "\n"
192
- end # def execute
193
- end # class << self
194
- end # module Justprep
125
+ out_file.close
126
+ end # def
127
+ end # class Justprep
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: justprep
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-18 00:00:00.000000000 Z
11
+ date: 2022-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bump
@@ -24,14 +24,9 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- description: |
28
- allows a "justfile" to be auto-generated from a seperate source file
29
- that contains inclusionary keywords such as include, import, require
30
- and with. These keywords are followed by a path to a file. If the
31
- file exists, the contents of the file are inserted into the file
32
- at the position of the keyword command. After all keywords have
33
- been process a new "justfile" is created which can then be used by
34
- the 'just' tool.
27
+ description: "justprep is a CLI tool implemented as a Ruby gem AND a \ncompiled Crystal
28
+ binary. It allows a task file to be \nauto-generated from seperate source files
29
+ that contain \ninclusionary keywords such as include, import, require \nand with.\n"
35
30
  email:
36
31
  - dvanhoozer@gmail.com
37
32
  executables:
@@ -50,9 +45,18 @@ files:
50
45
  - justfile
51
46
  - justprep.gemspec
52
47
  - lib/justprep.rb
48
+ - lib/justprep/common/constants.crb
49
+ - lib/justprep/common/error_messages.crb
50
+ - lib/justprep/common/expand_file_path.crb
51
+ - lib/justprep/common/generate_module_tasks.crb
52
+ - lib/justprep/common/handle_command_line_parameters.crb
53
+ - lib/justprep/common/include_content_from.crb
54
+ - lib/justprep/common/just_find_it.crb
55
+ - lib/justprep/common/replacement_for_module_line.crb
56
+ - lib/justprep/common/usage.crb
57
+ - lib/justprep/crystal_methods.rb
53
58
  - lib/justprep/version.rb
54
- - prototype.rb
55
- homepage: http://github.com/MadBomber/justprep/tree/main/ruby
59
+ homepage: http://github.com/MadBomber/justprep
56
60
  licenses:
57
61
  - MIT
58
62
  metadata:
@@ -72,8 +76,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
76
  - !ruby/object:Gem::Version
73
77
  version: '0'
74
78
  requirements: []
75
- rubygems_version: 3.2.24
79
+ rubygems_version: 3.3.18
76
80
  signing_key:
77
81
  specification_version: 4
78
- summary: A pre-processor for the 'just' command line utility
82
+ summary: Just a pre-processor for CLI task runners like 'just'
79
83
  test_files: []
data/prototype.rb DELETED
@@ -1,125 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
- # frozen_string_literal: true
4
- # warn_indent: true
5
- ##########################################################
6
- ###
7
- ## File: justprep.rb
8
- ## Desc: A preprocessor for justfiles using "main.just"
9
- ## Looks for keywords: import include require with
10
- ## followed by a file name or path.
11
- ##
12
- ## It looks for a file "main.just" in the current directory.
13
- ## If it does not exist, does nothing. Otherwise it reviews
14
- ## the file for the KEYWORDS. When found it inserts the
15
- ## content of the specified file into that position. The
16
- ## final text is written out to the "justfile" for processing
17
- ## with the "just" tool.
18
- ##
19
- ## There is NO ERROR checking. including file names/paths
20
- ## are assume to have to space characters.
21
- ##
22
- ## By: Dewayne VanHoozer (dvanhoozer@gmail.com)
23
- #
24
-
25
- KEYWORDS = %w[ import include require with ]
26
- BASEFILE = 'justfile'
27
- MAINFILE = 'main.just'
28
-
29
- require 'pathname'
30
-
31
- ######################################################
32
- # Local methods
33
-
34
- # review the text looking for module references
35
- def find_modules(text)
36
- modules = []
37
-
38
- KEYWORDS.each do |keyword|
39
- modules << text.select{|x| x.start_with? "#{keyword} "}
40
- end
41
-
42
- return modules.flatten!
43
- end
44
-
45
-
46
- # somg;e-level inclusion
47
- def include_content_from(file_path)
48
- content = []
49
- content << "\n# >>> #{file_path}"
50
- content << file_path.readlines.map{|x| x.chomp} # TODO: support recursion??
51
- content << "# <<< #{file_path}\n"
52
-
53
- return content.flatten
54
- end
55
-
56
-
57
- # look for first occurace of mainfile
58
- def just_find_it(here=Pathname.pwd)
59
- mainfile = here + MAINFILE
60
- return mainfile if mainfile.exist?
61
- return nil if here == here.parent
62
- return just_find_it(here.parent)
63
- end
64
-
65
-
66
- # use an external shell to expand system environment variables
67
- def expand_file_path(a_path_string)
68
- if a_path_string.start_with? '~'
69
- a_path_string = "${HOME}" + a_path_string[1, a_path_string.size-1]
70
- end
71
-
72
- a_path_string = `echo "#{a_path_string}"`.chomp
73
-
74
- return a_path_string
75
- end
76
-
77
-
78
- ######################################################
79
- # Main
80
-
81
- mainfile = just_find_it
82
-
83
- exit(0) if mainfile.nil?
84
-
85
- basefile = mainfile.parent + BASEFILE
86
-
87
- text = mainfile.readlines.map{|x| x.chomp} # drop the line ending from each line
88
-
89
- modules = find_modules text
90
-
91
- if modules.empty?
92
- basefile.write text
93
- exit(0)
94
- end
95
-
96
- modules.each do |a_line|
97
- an_index = text.index a_line
98
- begin_filename = a_line.index(' ')
99
- module_filename = a_line[begin_filename, a_line.size - begin_filename].strip
100
-
101
- if module_filename.empty?
102
- STDERR.puts "#{an_index}: #{a_line}"
103
- STDERR.puts "ERROR: No path/to/file was provided"
104
- next
105
- end
106
-
107
- if module_filename.include?('~') || module_filename.include?('$')
108
- module_filename = expand_file_path(module_filename)
109
- end
110
-
111
- module_path = Pathname.new(module_filename)
112
-
113
- if module_path.relative?
114
- module_path = mainfile.parent + module_path
115
- end
116
-
117
- if module_path.exist?
118
- text[an_index] = include_content_from(module_path)
119
- else
120
- STDERR.puts "#{an_index}: #{a_line}"
121
- STDERR.puts "| ERROR: File Does Not Exist - #{module_path}"
122
- end
123
- end
124
-
125
- basefile.write text.flatten!.join "\n"