go_script 0.0.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a33d0f56a637c8da9a53652adc002a7a9f1b58a
4
- data.tar.gz: c696612e2b13fd0188cdfdd4262aaf46ebd35f58
3
+ metadata.gz: f496bded6c9673222755b3041dba2248c74a1b8f
4
+ data.tar.gz: f9181e7c59e91011b17a3d05b4ea241f254a0a0a
5
5
  SHA512:
6
- metadata.gz: 256d24a8a8c2a325dda36883717296185664c91e9d4a619bb56504f54467ddae3906db7e8303881f9fd6d95cd6273e73b1e6d830717221d1df47cf26e09b870e
7
- data.tar.gz: 136735601a89dd6c735a0393663f505f46a004f3ab4383ea5409eb58273653ae168b5cafd13b722b0dffd33f6510191fa3102bfdfc0b1e953ce0c522cef9c9a8
6
+ metadata.gz: 1c69760ad3ab8269f1f61204e9291d275b4cd07f737d3962f77e5f193bfd570d093d5dcbfb509d64520c31a2c9f5b1b19d7d87fbab6c6d562f869721a1e2f717
7
+ data.tar.gz: cc918316e22269bca1e7a1a527464999bad3a6fafda21cd50eeaeddabcb0fddb9e92b05acf80cd8bb18c6a7fa468ae8893e4095483a4a33bcbaa34494b56d267
data/README.md CHANGED
@@ -20,20 +20,20 @@ language](https://golang.org). This convention is completely unrelated,
20
20
  though it does bear a great deal of resemblance to the Go language's `go`
21
21
  command.
22
22
 
23
- ### Installation
23
+ ### Everyone: install Ruby
24
24
 
25
25
  Install [the Ruby programming language](https://www.ruby-lang.org/) if it
26
26
  isn't already present on your system. We recommend using a Ruby version
27
27
  manager such as [rbenv](https://github.com/sstephenson/rbenv) or
28
28
  [rvm](https://rvm.io/) to do this.
29
29
 
30
- Install [Bundler](http://bundler.io/) via `gem install bundler`.
30
+ ### Project authors: creating a `./go` script
31
31
 
32
- Finally, install the `go_script` gem via `gem install go_script`. You may also
33
- wish to add it to the [`Gemfile`](http://bundler.io/gemfile.html) of your
34
- project to ensure version consistency.
32
+ Install the `go_script` gem via `gem install go_script`.
35
33
 
36
- ### Creating a `./go` script
34
+ To ensure version consistency for all developers, install
35
+ [Bundler](http://bundler.io/) via `gem install bundler` and add `gem
36
+ 'go_script'` to your project's [`Gemfile`](http://bundler.io/gemfile.html).
37
37
 
38
38
  To create a fresh new `./go` script for your project, run:
39
39
 
@@ -49,6 +49,17 @@ $ bundle exec go-script-template > ./go
49
49
  $ chmod 700 ./go
50
50
  ```
51
51
 
52
+ As a bonus, if the project only needs to initialize itself by installing Ruby
53
+ gems from a `Gemfile`, there is no need to define an `init` command. The
54
+ `./go` script will automatically install Bundler and run `bundle install`.
55
+
56
+ ### Project contributors: bootstrapping
57
+
58
+ If the project already has a `./go` script, you do not need to install
59
+ anything first other than Ruby. Just run the `./go` script. It will
60
+ automatically install the `go_script` gem, either via Bundler (if a `Gemfile`
61
+ is present) or directly using `gem install`.
62
+
52
63
  ### Listing commands
53
64
 
54
65
  To see the list of available commands for a script: run `./go help` (or one of
@@ -63,9 +74,7 @@ options:
63
74
  -v,--version Show the version of the go_script gem
64
75
 
65
76
  Development commands
66
- init Set up the development environment
67
77
  update_gems Update Ruby gems
68
- update_js Update JavaScript components
69
78
  test Execute automated tests
70
79
  lint Run style-checking tools
71
80
  ci_build Execute continuous integration build
@@ -80,7 +89,6 @@ comprise the `./go` script interface. Its arguments are:
80
89
  - *id*: A [Ruby symbol](http://ruby-doc.org/core-2.2.3/Symbol.html)
81
90
  (basically, a string starting with `:` with no quotes around it) defining
82
91
  the name of the command.
83
- - *command_group*: A `CommandGroup` instance associated with the command.
84
92
  - *description*: A very brief description of the command that appears in the
85
93
  usage text.
86
94
 
@@ -90,13 +98,27 @@ directives from [`lib/go_script/go.rb`](lib/go_script/go.rb) that may be used
90
98
  to define commands, and commands may be built up from other commands defined
91
99
  in the `./go` script itself.
92
100
 
101
+ **Note:** Command names must be unique. Defining a command with a name already
102
+ used elsewhere will cause the `./go` script to exit with an error message.
103
+
93
104
  #### Command groups
94
105
 
95
- A `CommandGroup` instance clusters a set of commands together.
96
- `go-script-template` generates a default `CommandGroup` instance called
97
- `dev_commands`; you are free to edit this definition, or to add additional
98
- `CommandGroup` instances to organize your individual command definitions and
99
- affect how they are displayed in the help/usage message.
106
+ Each `command_group` invocation marks the beginning of a set of related
107
+ commands. These groupings organize how commands are displayed in the
108
+ help/usage message.
109
+
110
+ `go-script-template` generates a default `command_group` called `:dev`. You
111
+ are free to edit this definition, or to add additional `command_group`
112
+ definitions.
113
+
114
+ **Note:** Command group names must be unique, and command groups cannot be
115
+ re-opened after their initial definition. Defining a command group with a name
116
+ already used elsewhere will cause the `./go` script to exit with an error
117
+ message.
118
+
119
+ Also, command names must be unique across all command groups. Defining a
120
+ command with the same name as that in another command group will also cause
121
+ the `./go` script to exit with an error message.
100
122
 
101
123
  #### Command arguments
102
124
 
@@ -104,18 +126,17 @@ Commands may take command-line arguments, which are passed in as block
104
126
  variables. In the following example, the `./go init` command takes no
105
127
  arguments, and the `./go test` command takes an argument list that is appended
106
128
  as additional command line arguments to `rake test`. For example, `./go test`
107
- runs `bundle exec rate test` without any further arguments, while running
129
+ runs `bundle exec rake test` without any further arguments, while running
108
130
  `./go test TEST=_test/go_test.rb` ultimately runs `bundle exec rake test
109
131
  TEST=_test/go_test.rb`.
110
132
 
111
133
  ```ruby
112
- dev_commands = GoScript::CommandGroup.add_group 'Development commands'
134
+ command_group :dev, 'Development commands'
113
135
 
114
- def_command :init, dev_commands, 'Set up the development environment' do
115
- install_bundle
136
+ def_command :init, 'Set up the development environment' do
116
137
  end
117
138
 
118
- def_command :test, dev_commands, 'Execute automated tests' do |args|
139
+ def_command :test, 'Execute automated tests' do |args = []|
119
140
  exec_cmd "bundle exec rake test #{args.join ' '}"
120
141
  end
121
142
  ```
@@ -8,37 +8,48 @@ puts <<END_OF_TEMPLATE
8
8
 
9
9
  require 'English'
10
10
 
11
+ Dir.chdir File.dirname(__FILE__)
12
+
13
+ def try_command_and_restart(command)
14
+ exit $CHILD_STATUS.exitstatus unless system command
15
+ exec $PROGRAM_NAME, *ARGV
16
+ end
17
+
11
18
  begin
12
- require 'go_script'
19
+ require 'bundler/setup' if File.exist? 'Gemfile'
13
20
  rescue LoadError
14
- puts 'Installing go_script gem...'
15
- exit $CHILD_STATUS.exitstatus unless system 'gem install go_script'
21
+ try_command_and_restart 'gem install bundler'
22
+ rescue SystemExit
23
+ try_command_and_restart 'bundle install'
16
24
  end
17
25
 
18
- GoScript::Version.check_ruby_version '#{RUBY_VERSION}'
26
+ begin
27
+ require 'go_script'
28
+ rescue LoadError
29
+ try_command_and_restart 'gem install go_script'
30
+ end
19
31
 
20
32
  extend GoScript
33
+ check_ruby_version '#{RUBY_VERSION}'
21
34
 
22
- BASEDIR = File.dirname(__FILE__)
23
- dev_commands = GoScript::CommandGroup.add_group 'Development commands'
35
+ command_group :dev, 'Development commands'
24
36
 
25
- def_command :init, dev_commands, 'Set up the development environment' do
26
- install_bundle
37
+ def_command :init, 'Set up the development environment' do
27
38
  end
28
39
 
29
- def_command :update_gems, dev_commands, 'Update Ruby gems' do |gems|
40
+ def_command :update_gems, 'Update Ruby gems' do |gems|
30
41
  update_gems gems
31
42
  end
32
43
 
33
- def_command :update_js, dev_commands, 'Update JavaScript components' do
44
+ def_command :update_js, 'Update JavaScript components' do
34
45
  update_node_modules
35
46
  end
36
47
 
37
- def_command :test, dev_commands, 'Execute automated tests' do |args|
48
+ def_command :test, 'Execute automated tests' do |args|
38
49
  exec_cmd "bundle exec rake test \#{args.join ' '}"
39
50
  end
40
51
 
41
- def_command :lint, dev_commands, 'Run style-checking tools' do |files|
52
+ def_command :lint, 'Run style-checking tools' do |files|
42
53
  files = files.group_by { |f| File.extname f }
43
54
  lint_ruby files['.rb']
44
55
  lint_javascript BASEDIR, files['.js']
data/lib/go_script.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  # @author Mike Bland (michael.bland@gsa.gov)
2
2
 
3
3
  require_relative './go_script/go'
4
- require_relative './go_script/command_group'
5
4
  require_relative './go_script/version'
@@ -1,36 +1,84 @@
1
1
  # Author: Mike Bland <michael.bland@gsa.gov>
2
2
 
3
+ require 'English'
4
+ require 'pathname'
5
+
3
6
  module GoScript
7
+ class Command
8
+ attr_reader :description, :path, :lineno
9
+
10
+ def initialize(description, path, lineno)
11
+ @description = description
12
+ @path = path
13
+ @lineno = lineno
14
+ end
15
+ end
16
+
4
17
  # Groups a set of commands by common function.
5
18
  class CommandGroup
6
- attr_accessor :description, :commands
19
+ attr_reader :description, :path, :lineno
20
+ attr_accessor :commands
7
21
  private_class_method :new
8
22
 
9
- # @param description [String] short description of the group
10
- def initialize(description)
23
+ def initialize(description, path, lineno)
11
24
  @description = description
25
+ @path = path
26
+ @lineno = lineno
12
27
  @commands = {}
13
28
  end
14
29
 
15
30
  def to_s
16
31
  padding = (commands.keys.max_by(&:size) || '').size + 2
17
- command_descriptions = commands.map do |name, desc|
18
- format " %-#{padding}s#{desc}", name
32
+ command_descriptions = commands.map do |name, command|
33
+ format " %-#{padding}s#{command.description}", name
19
34
  end
20
35
  ["\n#{@description}"].concat(command_descriptions).join("\n")
21
36
  end
22
37
 
38
+ def include_command?(command_symbol)
39
+ commands.keys.include? command_symbol
40
+ end
41
+
23
42
  class <<self
24
- attr_reader :groups
25
- def add_group(description)
26
- (@groups ||= []).push(new(description)).last
43
+ def groups
44
+ @groups ||= {}
27
45
  end
28
46
 
29
- def command(command_sym)
30
- if (groups || []).flat_map { |g| g.commands.keys }.include? command_sym
31
- return command_sym
47
+ def location_path(target_path)
48
+ @base_path ||= Pathname.new(
49
+ File.dirname(File.expand_path $PROGRAM_NAME))
50
+ Pathname.new(File.expand_path target_path).relative_path_from @base_path
51
+ end
52
+
53
+ def check_not_defined(collection, label, key, path, lineno)
54
+ return unless (existing = collection[key])
55
+ previous = location_path existing.path
56
+ current = location_path path
57
+ prefix = previous == current ? 'line ' : previous + ':'
58
+ abort "#{current}:#{lineno}: #{label} \"#{key}\" " \
59
+ "already defined at #{prefix}#{existing.lineno}"
60
+ end
61
+
62
+ def add_group(group_symbol, description, path, lineno)
63
+ check_not_defined groups, 'Command group', group_symbol, path, lineno
64
+ groups[group_symbol] = new description, path, lineno
65
+ end
66
+
67
+ def command_defined?(command)
68
+ groups.values.each { |g| return true if g.include_command? command }
69
+ end
70
+
71
+ def add_command(command, group_symbol, description, path, lineno)
72
+ groups.values.each do |group|
73
+ check_not_defined group.commands, 'Command', command, path, lineno
32
74
  end
33
- puts "Unknown option or command: #{command_sym}"
75
+ groups[group_symbol].commands[command] = Command.new(
76
+ description, path, lineno)
77
+ end
78
+
79
+ def command(command_sym)
80
+ return command_sym if command_defined? command_sym
81
+ $stderr.puts "Unknown option or command: #{command_sym}"
34
82
  usage exitstatus: 1
35
83
  end
36
84
 
@@ -43,7 +91,7 @@ options:
43
91
  -h,--help Show this help
44
92
  -v,--version Show the version of the go_script gem
45
93
  END_OF_USAGE
46
- (groups || []).each { |group| output_stream.puts group }
94
+ (groups.values || []).each { |group| output_stream.puts group }
47
95
  exit exitstatus
48
96
  end
49
97
  end
data/lib/go_script/go.rb CHANGED
@@ -5,17 +5,32 @@ require_relative './version'
5
5
  require 'English'
6
6
 
7
7
  module GoScript
8
- def def_command(id, command_group, description, &command_block)
8
+ attr_reader :current_group
9
+
10
+ def check_ruby_version(min_version)
11
+ Version.check_ruby_version min_version
12
+ end
13
+
14
+ def command_group(group_symbol, description)
15
+ location = caller_locations(1, 1).first
16
+ CommandGroup.add_group(group_symbol, description,
17
+ location.path, location.lineno)
18
+ @current_group = group_symbol
19
+ end
20
+
21
+ def def_command(id, description, &command_block)
22
+ abort "#{$PROGRAM_NAME}: No command_groups defined" unless current_group
9
23
  abort "Command ID must be a symbol: #{id}" unless id.instance_of? Symbol
10
- self.class.send :define_method, id, ->(argv) { command_block.call argv }
11
- command_group.commands[id] = description
24
+ self.class.send :define_method, id, ->(*argv) { command_block.call(*argv) }
25
+ path, lineno = command_block.source_location
26
+ CommandGroup.add_command id, @current_group, description, path, lineno
12
27
  end
13
28
 
14
29
  def execute_command(argv)
15
30
  command = argv.shift
16
31
  CommandGroup.usage exitstatus: 1 if command.nil?
17
32
  CommandGroup.usage if ['-h', '--help', '-help', 'help'].include? command
18
- send version if ['-v', '--version', 'version'].include? command
33
+ send :version if ['-v', '--version', 'version'].include? command
19
34
  send CommandGroup.command(command.to_sym), argv
20
35
  end
21
36
 
@@ -32,9 +47,7 @@ module GoScript
32
47
  begin
33
48
  require 'bundler'
34
49
  rescue LoadError
35
- puts 'Installing Bundler gem...'
36
50
  exec_cmd 'gem install bundler'
37
- puts 'Bundler installed; installing gems'
38
51
  end
39
52
  exec_cmd 'bundle install'
40
53
  end
@@ -63,9 +76,11 @@ module GoScript
63
76
  exec_cmd "#{JEKYLL_BUILD_CMD} #{extra_args}"
64
77
  end
65
78
 
66
- def git_sync_and_deploy(commands)
79
+ def git_sync_and_deploy(commands, branch: nil)
67
80
  exec_cmd 'git stash'
81
+ exec_cmd "git checkout -b #{branch}" unless branch.nil?
68
82
  exec_cmd 'git pull'
83
+ exec_cmd 'bundle install' if File.exist? 'Gemfile'
69
84
  commands.each { |command| exec_cmd command }
70
85
  end
71
86
 
@@ -1,7 +1,7 @@
1
1
  # @author Mike Bland (michael.bland@gsa.gov)
2
2
 
3
3
  module GoScript
4
- VERSION = '0.0.0'
4
+ VERSION = '0.1.0'
5
5
 
6
6
  class Version
7
7
  def self.check_ruby_version(min_version)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: go_script
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Bland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-21 00:00:00.000000000 Z
11
+ date: 2015-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler