scripto 0.0.3 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 682b3b4d477f4c653c2f4f28b650eeb539d7c7fd
4
- data.tar.gz: 1b9e0f393c6d9666f6cb374ca2c485ca95272fc6
2
+ SHA256:
3
+ metadata.gz: 7cdd03bc1a558ff5c9f151d972205bde0816ad6feb89de992ae141bd637ebc54
4
+ data.tar.gz: b5c45a7c274391597e1c6dcd2e91579cdb09cc028bda6179a1762f010d005a73
5
5
  SHA512:
6
- metadata.gz: 2780520e158ddcf2843a38361c1fd64a9d041c7c215901ad6fe95e5932c43acca75fbda8bf2af8bb6c3928b795e41edf46e2ef3e7cd913d758558d7d8428bcd2
7
- data.tar.gz: de8a0e1eb329fddfe4ff9e86efc65ecbaacc2765c6bbaed3877492b5e58f97b5f89af5d9d5f719fd4743a5171c9c31632c52b2fc63311b460f692bcfb50f5f32
6
+ metadata.gz: a2b6883573f231fe24d7c6566d62510e95d4672842f0c580fb29e2634877e3020db88fe71b9d683e571ca23a2ef4e1479a0f0cf2de9f52d3d1faab0137d88001
7
+ data.tar.gz: 5934be60e97a589d0099a136027ee3888a6d7c3d7a7f3589df70fe76a525f5286ee3aad2812a0e373f6b7248371aabece0d7c68c2256329ca3eb7e092709b934
@@ -0,0 +1,22 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ paths-ignore:
6
+ - "**.md"
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ test:
11
+ strategy:
12
+ matrix:
13
+ ruby-version: [3.4]
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v5
17
+ - uses: taiki-e/install-action@just
18
+ - uses: ruby/setup-ruby@v1
19
+ with:
20
+ bundler-cache: true
21
+ ruby-version: ${{ matrix.ruby-version }}
22
+ - run: just check
data/.gitignore CHANGED
@@ -1,18 +1 @@
1
1
  *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .vagrant
6
- .yardoc
7
- Gemfile.lock
8
- InstalledFiles
9
- _yardoc
10
- coverage
11
- doc/
12
- lib/bundler/man
13
- pkg
14
- rdoc
15
- spec/reports
16
- test/tmp
17
- test/version_tmp
18
- tmp
data/.rubocop.yml ADDED
@@ -0,0 +1,15 @@
1
+ require:
2
+ - standard
3
+
4
+ inherit_gem:
5
+ standard: config/base.yml
6
+
7
+ AllCops:
8
+ Exclude:
9
+ - vendor/**/* # for ci - https://github.com/rubocop/rubocop/issues/9832
10
+ NewCops: enable
11
+ SuggestExtensions: false
12
+ TargetRubyVersion: 3.1
13
+
14
+ # tweaks
15
+ Style/HashSyntax: { EnforcedShorthandSyntax: always }
@@ -0,0 +1,3 @@
1
+ {
2
+ "recommendations": ["Shopify.ruby-lsp"]
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "editor.formatOnSave": true
3
+ }
data/Gemfile CHANGED
@@ -1,4 +1,12 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in scripto.gemspec
4
3
  gemspec
4
+
5
+ group :development, :test do
6
+ gem "minitest", "~> 5.0"
7
+ gem "mocha"
8
+ gem "pry", require: false
9
+ gem "rake", require: false
10
+ gem "ruby-lsp", require: false
11
+ gem "standard", require: false
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,97 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ scripto (1.0.0)
5
+ csv (~> 3.3)
6
+ ostruct (~> 0.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ ast (2.4.3)
12
+ coderay (1.1.3)
13
+ csv (3.3.5)
14
+ io-console (0.8.2)
15
+ json (2.18.0)
16
+ language_server-protocol (3.17.0.5)
17
+ lint_roller (1.1.0)
18
+ logger (1.7.0)
19
+ method_source (1.1.0)
20
+ minitest (5.27.0)
21
+ mocha (3.0.1)
22
+ ruby2_keywords (>= 0.0.5)
23
+ ostruct (0.6.3)
24
+ parallel (1.27.0)
25
+ parser (3.3.10.1)
26
+ ast (~> 2.4.1)
27
+ racc
28
+ prism (1.9.0)
29
+ pry (0.16.0)
30
+ coderay (~> 1.1)
31
+ method_source (~> 1.0)
32
+ reline (>= 0.6.0)
33
+ racc (1.8.1)
34
+ rainbow (3.1.1)
35
+ rake (13.3.1)
36
+ rbs (3.10.2)
37
+ logger
38
+ regexp_parser (2.11.3)
39
+ reline (0.6.3)
40
+ io-console (~> 0.5)
41
+ rubocop (1.82.1)
42
+ json (~> 2.3)
43
+ language_server-protocol (~> 3.17.0.2)
44
+ lint_roller (~> 1.1.0)
45
+ parallel (~> 1.10)
46
+ parser (>= 3.3.0.2)
47
+ rainbow (>= 2.2.2, < 4.0)
48
+ regexp_parser (>= 2.9.3, < 3.0)
49
+ rubocop-ast (>= 1.48.0, < 2.0)
50
+ ruby-progressbar (~> 1.7)
51
+ unicode-display_width (>= 2.4.0, < 4.0)
52
+ rubocop-ast (1.49.0)
53
+ parser (>= 3.3.7.2)
54
+ prism (~> 1.7)
55
+ rubocop-performance (1.26.1)
56
+ lint_roller (~> 1.1)
57
+ rubocop (>= 1.75.0, < 2.0)
58
+ rubocop-ast (>= 1.47.1, < 2.0)
59
+ ruby-lsp (0.26.5)
60
+ language_server-protocol (~> 3.17.0)
61
+ prism (>= 1.2, < 2.0)
62
+ rbs (>= 3, < 5)
63
+ ruby-progressbar (1.13.0)
64
+ ruby2_keywords (0.0.5)
65
+ standard (1.53.0)
66
+ language_server-protocol (~> 3.17.0.2)
67
+ lint_roller (~> 1.0)
68
+ rubocop (~> 1.82.0)
69
+ standard-custom (~> 1.0.0)
70
+ standard-performance (~> 1.8)
71
+ standard-custom (1.0.2)
72
+ lint_roller (~> 1.0)
73
+ rubocop (~> 1.50)
74
+ standard-performance (1.9.0)
75
+ lint_roller (~> 1.1)
76
+ rubocop-performance (~> 1.26.0)
77
+ unicode-display_width (3.2.0)
78
+ unicode-emoji (~> 4.1)
79
+ unicode-emoji (4.2.0)
80
+
81
+ PLATFORMS
82
+ arm64-darwin-20
83
+ arm64-darwin-21
84
+ arm64-darwin-24
85
+ x86_64-linux
86
+
87
+ DEPENDENCIES
88
+ minitest (~> 5.0)
89
+ mocha
90
+ pry
91
+ rake
92
+ ruby-lsp
93
+ scripto!
94
+ standard
95
+
96
+ BUNDLED WITH
97
+ 2.5.21
data/README.md CHANGED
@@ -1,13 +1,15 @@
1
- # Scripto
1
+ [![Build Status](https://github.com/gurgeous/scripto/actions/workflows/ci.yml/badge.svg)](https://github.com/gurgeous/scripto/actions/workflows/ci.yml)
2
+
3
+ ![logo](logo.svg)
2
4
 
3
- Scripto is a framework for writing command line applications. It fills in many of the blanks that Ruby's standard library is missing:
5
+ # Scripto
4
6
 
5
- * **print to $stderr** - Colored banners and a verbose mode to make your scripts louder.
6
- * **file operations** - Mkdir, cp, mv, ln. These operations can take care of common edge cases, like creating the target directory before copying a file.
7
- * **run commands** - Run external commands and raise errors on failure.
8
- * **csv** - Read and write CSV files from hashes, Structs, or OpenStructs.
7
+ Scripto is a framework for writing Ruby command line applications. It fills in many of the blanks that Ruby's standard library is missing:
9
8
 
10
- Rdoc at [rdoc.info](http://rdoc.info/github/gurgeous/scripto/). Thanks!
9
+ - **printing** - Colored banners and a verbose mode to make your scripts louder.
10
+ - **file operations** - Mkdir, cp, mv, ln. These operations can take care of common edge cases, like creating the target directory before copying a file.
11
+ - **run commands** - Run external commands and raise errors on failure.
12
+ - **csv** - Read and write CSV files from hashes, Structs, or OpenStructs.
11
13
 
12
14
  ## Getting Started
13
15
 
@@ -41,7 +43,7 @@ require "scripto"
41
43
 
42
44
  class Install < Scripto::Main
43
45
  def initialize(options = {})
44
- verbose! if options[:verbose]
46
+ super
45
47
 
46
48
  banner("Starting installation...")
47
49
  cp("here.txt", "there.txt")
@@ -65,17 +67,18 @@ Install.new(verbose: true)
65
67
 
66
68
  ## Methods
67
69
 
68
- ### Print to $stderr
70
+ ### Printing
71
+
72
+ Scripto has a built-in logger that wraps $stdout. The logger runs in INFO mode
73
+ by default, but will switch to DEBUG if options[:verbose] is true. Or you can
74
+ quiet it down to ERROR if options[:quiet] is true. `banner`, `warning` and
75
+ `fatal` use Scripto's logger.
69
76
 
70
77
  ```
71
78
  banner(str) - print a banner in green
72
79
  warning(str) - print a warning in yellow
73
80
  fatal(str) - print a fatal error in red, then exit(1)
74
-
75
- verbose! - turn on verbose mode
76
- vbanner(str) - print a colored banner in green if verbose is on
77
- vprintf(str) - printf if verbose is on
78
- vputs(str) - puts if verbose is on
81
+ verbose! - force verbose
79
82
  ```
80
83
 
81
84
  ### File operations
@@ -151,3 +154,17 @@ md5_string(str) - calculate md5 for a string
151
154
  prompt?(question) - ask the user a question, return true if they say yes
152
155
  random_string(len) - calculate a random alphanumeric string
153
156
  ```
157
+
158
+ # Changelog
159
+
160
+ ### 1.0.0 (early 2026)
161
+
162
+ - banner and friends use Logger (breaking)
163
+ - only support Ruby 3.4+ (breaking)
164
+ - [standardrb](https://github.com/testdouble/standard) and a [justfile](https://github.com/casey/just)
165
+ - update deps, switch to Github actions, etc.
166
+
167
+ ### 0.0.4 (late 2020)
168
+
169
+ - Added support for reading CSV with BOM.
170
+ - Only support Ruby 2.3+, since we moved to modern Bundler
data/Rakefile CHANGED
@@ -1,16 +1,5 @@
1
- require "bundler/gem_tasks"
1
+ require "bundler/setup"
2
2
  require "rake/testtask"
3
- require "rdoc/task"
4
3
 
5
- Rake::TestTask.new(:test) do |test|
6
- test.libs << "test"
7
- end
4
+ Rake::TestTask.new(:test)
8
5
  task default: :test
9
-
10
- RDoc::Task.new do |rdoc|
11
- rdoc.rdoc_dir = "rdoc"
12
- rdoc.title = "scripto #{Scripto::VERSION}"
13
- rdoc.main = "README.md"
14
- rdoc.rdoc_files.include("lib/**/*.rb")
15
- rdoc.rdoc_files.include("README.md")
16
- end
data/justfile ADDED
@@ -0,0 +1,54 @@
1
+
2
+ # read gem version
3
+ gemver := `cat lib/scripto/version.rb | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+"`
4
+
5
+ set quiet := true
6
+
7
+ #
8
+ # dev
9
+ #
10
+
11
+ default: test
12
+
13
+ check: lint test
14
+
15
+ fmt:
16
+ bundle exec rubocop -a
17
+
18
+ lint:
19
+ just banner lint...
20
+ bundle exec rubocop
21
+
22
+ pry:
23
+ bundle exec pry -I lib -r scripto.rb
24
+
25
+ test:
26
+ just banner test...
27
+ bundle exec rake test
28
+
29
+ watch:
30
+ watchexec --watch lib --watch test --clear bundle exec rake test
31
+
32
+ #
33
+ # gem tasks
34
+ #
35
+
36
+ gem-push: # check-git-status
37
+ just banner gem build...
38
+ gem build scripto.gemspec
39
+ just banner tag...
40
+ # git tag -a "v{{gemver}}" -m "Tagging {{gemver}}"
41
+ # git push --tags
42
+ just banner gem push...
43
+ gem push "scripto-{{gemver}}.gem"
44
+
45
+ #
46
+ # util
47
+ #
48
+
49
+ GREEN := '\e[1;38;2;255;255;255;48;2;64;160;43m'
50
+ banner *ARGS:
51
+ printf '{{GREEN}}[%s] %-72s \e[m\n' "$(date +%H:%M:%S)" "{{ARGS}}"
52
+
53
+ check-git-status:
54
+ if [ ! -z "$(git status --porcelain)" ]; then echo "git status is dirty, bailing."; exit 1; fi
@@ -1,4 +1,5 @@
1
1
  require "csv"
2
+ require "tempfile"
2
3
  require "zlib"
3
4
 
4
5
  module Scripto
@@ -6,16 +7,17 @@ module Scripto
6
7
  # Read a csv from +path+. Returns an array of Structs, using the keys from
7
8
  # the csv header row.
8
9
  def csv_read(path)
9
- lines = if path =~ /\.gz$/
10
- Zlib::GzipReader.open(path) do |f|
11
- CSV.new(f).read
10
+ rows = if /\.gz$/.match?(path)
11
+ Zlib::GzipReader.open(path) do
12
+ CSV.new(_1).read
12
13
  end
13
14
  else
14
- CSV.read(path)
15
+ CSV.read(path, encoding: "bom|utf-8")
15
16
  end
16
- keys = lines.shift.map(&:to_sym)
17
+
18
+ keys = rows.shift.map(&:to_sym)
17
19
  klass = Struct.new(*keys)
18
- lines.map { |i| klass.new(*i) }
20
+ rows.map { klass.new(*_1) }
19
21
  end
20
22
 
21
23
  # Write +rows+ to +path+ as csv. Rows can be an array of hashes, Structs,
@@ -23,26 +25,22 @@ module Scripto
23
25
  # first row are used as the csv header. If +cols+ is specified, it will be
24
26
  # used as the column keys instead.
25
27
  def csv_write(path, rows, cols: nil)
26
- begin
27
- tmp = "/tmp/_scripto_csv.csv"
28
- CSV.open(tmp, "wb") { |f| csv_write0(f, rows, cols: cols) }
29
- mv(tmp, path)
30
- ensure
31
- rm_if_necessary(tmp)
28
+ atomic_write(path) do |tmp|
29
+ CSV.open(tmp.path, "wb") { csv_write0(_1, rows, cols:) }
32
30
  end
33
31
  end
34
32
 
35
33
  # Write +rows+ to $stdout as a csv. Similar to csv_write.
36
34
  def csv_to_stdout(rows, cols: nil)
37
- CSV($stdout) { |f| csv_write0(f, rows, cols: cols) }
35
+ CSV($stdout) { csv_write0(_1, rows, cols:) }
38
36
  end
39
37
 
40
38
  # Returns a string containing +rows+ as a csv. Similar to csv_write.
41
39
  def csv_to_s(rows, cols: nil)
42
- string = ""
43
- f = CSV.new(StringIO.new(string))
44
- csv_write0(f, rows, cols: cols)
45
- string
40
+ StringIO.new.tap do
41
+ f = CSV.new(_1)
42
+ csv_write0(f, rows, cols:)
43
+ end.string
46
44
  end
47
45
 
48
46
  protected
@@ -56,8 +54,8 @@ module Scripto
56
54
  # rows
57
55
  rows.each do |row|
58
56
  row = row.to_h
59
- csv << cols.map { |i| row[i] }
57
+ csv << cols.map { row[_1] }
60
58
  end
61
59
  end
62
60
  end
63
- end
61
+ end
@@ -36,13 +36,11 @@ module Scripto
36
36
  # Like ln -sf +src+ +dst. The command will be printed out if
37
37
  # verbose?.
38
38
  def ln(src, dst)
39
- begin
40
- FileUtils.ln_sf(src, dst, verbose: verbose?)
41
- rescue Errno::EEXIST => e
42
- # It's a race - this can occur because ln_sf removes the old
43
- # dst, then creates the symlink. Raise if they don't match.
44
- raise e if !(File.symlink?(dst) && src == File.readlink(dst))
45
- end
39
+ FileUtils.ln_sf(src, dst, verbose: verbose?)
40
+ rescue Errno::EEXIST => e
41
+ # It's a race - this can occur because ln_sf removes the old
42
+ # dst, then creates the symlink. Raise if they don't match.
43
+ raise e if !(File.symlink?(dst) && src == File.readlink(dst))
46
44
  end
47
45
 
48
46
  # Like rm -f +file+. Like all file commands, the operation will be printed
@@ -55,45 +53,43 @@ module Scripto
55
53
  # directory had to be created. This is useful with verbose?, to get an
56
54
  # exact changelog.
57
55
  def mkdir_if_necessary(dir, owner: nil, mode: nil)
58
- if !(File.exist?(dir) || File.symlink?(dir))
59
- mkdir(dir, owner: owner, mode: mode)
60
- true
61
- end
56
+ return if File.exist?(dir) || File.symlink?(dir)
57
+
58
+ mkdir(dir, owner:, mode:)
59
+ true
62
60
  end
63
61
 
64
62
  # Runs #cp, but ONLY if +dst+ doesn't exist or differs from +src+. Returns
65
63
  # true if the file had to be copied. This is useful with verbose?, to get
66
64
  # an exact changelog.
67
65
  def cp_if_necessary(src, dst, mkdir: false, owner: nil, mode: nil)
68
- if !(File.exist?(dst) && FileUtils.compare_file(src, dst))
69
- cp(src, dst, mkdir: mkdir, owner: owner, mode: mode)
70
- true
71
- end
66
+ return if File.exist?(dst) && FileUtils.compare_file(src, dst)
67
+
68
+ cp(src, dst, mkdir:, owner:, mode:)
69
+ true
72
70
  end
73
71
 
74
72
  # Runs #ln, but ONLY if +dst+ isn't a symlink or differs from +src+.
75
73
  # Returns true if the file had to be symlinked. This is useful with
76
74
  # verbose?, to get an exact changelog.
77
75
  def ln_if_necessary(src, dst)
78
- ln = if !File.symlink?(dst)
79
- true
80
- elsif File.readlink(dst) != src
76
+ if File.symlink?(dst)
77
+ return if src == File.readlink(dst)
78
+
81
79
  rm(dst)
82
- true
83
- end
84
- if ln
85
- ln(src, dst)
86
- true
87
80
  end
81
+
82
+ ln(src, dst)
83
+ true
88
84
  end
89
85
 
90
86
  # Runs #rm, but ONLY if +file+ exists. Return true if the file had to be
91
87
  # removed. This is useful with verbose?, to get an exact changelog.
92
88
  def rm_if_necessary(file)
93
- if File.exist?(file)
94
- rm(file)
95
- true
96
- end
89
+ return if !File.exist?(file)
90
+
91
+ rm(file)
92
+ true
97
93
  end
98
94
 
99
95
  # Like chown user:user file. Like all file commands, the operation will be printed
@@ -103,23 +99,24 @@ module Scripto
103
99
  @scripto_uids ||= {}
104
100
  @scripto_uids[user] ||= Etc.getpwnam(user).uid
105
101
  uid = @scripto_uids[user]
106
- if File.stat(file).uid != uid
107
- FileUtils.chown(uid, uid, file, verbose: verbose?)
108
- end
102
+ return if File.stat(file).uid == uid
103
+
104
+ FileUtils.chown(uid, uid, file, verbose: verbose?)
109
105
  end
110
106
 
111
107
  # Like chmod mode file. Like all file commands, the operation will be
112
108
  # printed out if verbose?.
113
109
  def chmod(file, mode)
114
- if File.stat(file).mode != mode
115
- FileUtils.chmod(mode, file, verbose: verbose?)
116
- end
110
+ return if File.stat(file).mode == mode
111
+
112
+ FileUtils.chmod(mode, file, verbose: verbose?)
117
113
  end
118
114
 
119
115
  # Like rm -rf && mkdir -p. Like all file commands, the operation will be
120
116
  # printed out if verbose?.
121
117
  def rm_and_mkdir(dir)
122
118
  raise "don't do this" if dir == ""
119
+
123
120
  FileUtils.rm_rf(dir, verbose: verbose?)
124
121
  mkdir(dir)
125
122
  end
@@ -131,5 +128,16 @@ module Scripto
131
128
  File.chmod(stat.mode, dst)
132
129
  File.utime(stat.atime, stat.mtime, dst)
133
130
  end
131
+
132
+ # Atomically write to +path+. An open temp file is yielded.
133
+ def atomic_write(path)
134
+ tmp = Tempfile.new(File.basename(path))
135
+ yield(tmp)
136
+ tmp.close
137
+ chmod(tmp.path, 0o644)
138
+ mv(tmp.path, path)
139
+ ensure
140
+ rm_if_necessary(tmp.path)
141
+ end
134
142
  end
135
- end
143
+ end
@@ -0,0 +1,112 @@
1
+ require "logger"
2
+
3
+ module Scripto
4
+ module LogCommands
5
+ # https://catppuccin.com/palette/
6
+ RESET = "\e[0m"
7
+ GREEN = "\e[1;38;2;255;255;255;48;2;64;160;43m"
8
+ YELLOW = "\e[1;38;2;255;255;255;48;2;251;100;11m"
9
+ RED = "\e[1;38;2;255;255;255;48;2;210;15;57m"
10
+
11
+ #
12
+ # logger
13
+ #
14
+
15
+ # Returns the built-in logger. If none has been set, create a new one
16
+ # wrapped around $stdout. Used by banner/warning/fatal.
17
+ def logger
18
+ @logger ||= begin
19
+ level = if options[:verbose]
20
+ Logger::DEBUG
21
+ elsif options[:quiet]
22
+ Logger::ERROR
23
+ else
24
+ Logger::INFO
25
+ end
26
+ Logger.new($stdout, level:, formatter: Formatter.new)
27
+ end
28
+ end
29
+
30
+ # Set the built-in logger.
31
+ def logger=(value)
32
+ @logger = value
33
+ @log_with_color = false
34
+ end
35
+
36
+ #
37
+ # options
38
+ #
39
+
40
+ # Get options
41
+ def options
42
+ @options ||= {}
43
+ end
44
+
45
+ # Set options
46
+ def options=(value)
47
+ @options = value.dup
48
+ end
49
+
50
+ # Should we log in verbose mode?
51
+ def verbose?
52
+ logger.level == Logger::DEBUG
53
+ end
54
+
55
+ # Should we log in quiet mode?
56
+ def quiet?
57
+ logger.level == Logger::ERROR
58
+ end
59
+
60
+ # Set logging to verbose (DEBUG)
61
+ def verbose!
62
+ logger.level = Logger::DEBUG
63
+ end
64
+
65
+ # Set logging to quiet (ERROR)
66
+ def quiet!
67
+ logger.level = Logger::ERROR
68
+ end
69
+
70
+ # Should we use color? Inferred from $stdout.tty? if not set.
71
+ def log_with_color?
72
+ return @log_with_color if defined?(@log_with_color)
73
+ $stdout.tty?
74
+ end
75
+
76
+ # Set whether we should use color.
77
+ def log_with_color=(value)
78
+ @log_with_color = value
79
+ end
80
+
81
+ #
82
+ # banner/warning/fatal
83
+ #
84
+
85
+ # Log a colored banner in green.
86
+ def banner(str, log_level: Logger::INFO, color: GREEN)
87
+ s = "#{str} ".ljust(72, " ")
88
+ s = "[#{Time.new.strftime("%H:%M:%S")}] #{s}"
89
+ s = "#{color}#{s}#{RESET}" if log_with_color?
90
+ logger.add(log_level, s)
91
+ nil
92
+ end
93
+
94
+ # Log a yellow warning banner.
95
+ def warning(str)
96
+ banner("Warning: #{str}", log_level: Logger::WARN, color: YELLOW)
97
+ end
98
+
99
+ # Log a red error banner, then exit.
100
+ def fatal(str)
101
+ banner(str, log_level: Logger::FATAL, color: RED)
102
+ exit(1)
103
+ end
104
+
105
+ # Simple log formatter with no timestamp.
106
+ class Formatter < Logger::Formatter
107
+ def call(_severity, _time, _progname, msg)
108
+ "#{msg}\n"
109
+ end
110
+ end
111
+ end
112
+ end
data/lib/scripto/main.rb CHANGED
@@ -4,15 +4,12 @@ module Scripto
4
4
  class Main
5
5
  include CsvCommands
6
6
  include FileCommands
7
+ include LogCommands
7
8
  include MiscCommands
8
- include PrintCommands
9
9
  include RunCommands
10
10
 
11
- attr_accessor :options
12
-
13
11
  def initialize(options = {})
14
12
  self.options = options
15
- self.verbose = options[:verbose]
16
13
  end
17
14
  end
18
- end
15
+ end