git_tree 0.2.2 → 0.3.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
  SHA256:
3
- metadata.gz: 45ac579ee8e240d6c78bd782b40b1ca473ffd5e7f1d87a1fb81b53012516465c
4
- data.tar.gz: 32b342b9e45b35a64beca464cf9a0e3af514ea5867cd864916ff551425f3dcd7
3
+ metadata.gz: fbe9b3cc4ea586c939cc994ddf433fe11a3ae801ebb4d414d26203969272e35e
4
+ data.tar.gz: a73a4c53e64d9cf8c3a9ac9f82cca966a469585a39c8d2df19f62d99d5d6bc9b
5
5
  SHA512:
6
- metadata.gz: 7ecfa103809f6cd8d63bbd76b69cbbf5d7af5c746b16a7d533d7bfc9a269687413413b98b7fa5aab27028f37a7d8e2ef4df40decd49a07828549cedfb072c47a
7
- data.tar.gz: 1dc61521613c96dbb776de98b02b269a3dc0d0aa2605e534fdc19d4facf103c8e4a9fa6dddef143720b841e672b9fc5072c74b81b643cc1fd6ea4ba502a1a821
6
+ metadata.gz: 28bffd85905de74df607377f3db64588d1697ef7acbaace6ddc5ca410d6ba71aca2aaa293f1620fac87d9175618f2068ccd759080e4a803fc56ff57aa798c8d4
7
+ data.tar.gz: 963acbcdac77069745e6cc009b653fdb779e6f97e192d5bd937efb0c6bb9e4dfbb34d8796a00c48108e655239b41322baaa5f4751652f0f228cde1aec939cf76
data/.rubocop.yml CHANGED
@@ -7,12 +7,11 @@ require:
7
7
  AllCops:
8
8
  Exclude:
9
9
  - demo/_site/**/*
10
- - exe/**/*
10
+ - binstub/**/*
11
11
  - vendor/**/*
12
12
  - Gemfile*
13
13
  - git_tree.gemspec
14
14
  NewCops: enable
15
- TargetRubyVersion: 2.6
16
15
 
17
16
  Gemspec/DeprecatedAttributeAssignment:
18
17
  Enabled: false
@@ -20,6 +19,9 @@ Gemspec/DeprecatedAttributeAssignment:
20
19
  Gemspec/RequireMFA:
21
20
  Enabled: false
22
21
 
22
+ Gemspec/RequiredRubyVersion:
23
+ Enabled: false
24
+
23
25
  Layout/HashAlignment:
24
26
  EnforcedColonStyle: table
25
27
  EnforcedHashRocketStyle: table
data/CHANGELOG.md CHANGED
@@ -1,25 +1,59 @@
1
+ # Change Log
2
+
3
+ ## 0.3.1 (in progress)
4
+
5
+ * Added spec.platform to `.gemspec` because `RubyGems.org` now requires it
6
+
7
+
8
+ ## 0.3.0 / 2023-06-01
9
+
10
+ * Added `git-tree-exec` command.
11
+
12
+
13
+ ## 0.2.3 / 2023-05-26
14
+
15
+ * Improved help messages.
16
+ * Renamed executables to `git-tree-replicate` and `git-tree-evars`.
17
+
18
+
1
19
  ## 0.2.2 / 2023-05-23
2
- * `git_tree_evars` now checks for previous definitions and issues warnings.
20
+
21
+ * `git_tree_evars` now checks for previous definitions and issues warnings.
22
+
23
+
3
24
  ## 0.2.1 / 2023-05-03
4
- * Removed the here document wrapper from the output of `git_tree_evars`.
25
+
26
+ * Removed the here document wrapper from the output of `git_tree_evars`.
27
+
5
28
 
6
29
  ## 0.2.0 / 2023-05-03
7
- * Renamed gem to `git_tree`
8
- * Renamed `replicate_git_tree` command to `git_tree_replicate`.
9
- * Added `.evars` support with new executable: `git_tree_evars`
10
- * Added support for a symlinked root directory
30
+
31
+ * Renamed gem to `git_tree`
32
+ * Renamed `replicate_git_tree` command to `git_tree_replicate`.
33
+ * Added `.evars` support with new executable: `git_tree_evars`
34
+ * Added support for a symlinked root directory
35
+
11
36
 
12
37
  ## 0.1.3 / 2023-05-01
13
- * Fussing with directory path (works!!!)
38
+
39
+ * Fussing with directory path (works!!!)
40
+
14
41
 
15
42
  ## 0.1.2 / 2023-05-01
16
- * Fussing with gem executable (did not work)
43
+
44
+ * Fussing with gem executable (did not work)
45
+
17
46
 
18
47
  ## 0.1.1 / 2023-05-01
19
- * Added missing file (did not work)
48
+
49
+ * Added missing file (did not work)
50
+
20
51
 
21
52
  ## 0.1.0 / 2023-05-01
22
- * Published as a gem (did not work)
53
+
54
+ * Published as a gem (did not work)
55
+
23
56
 
24
57
  ## 2021-04-10
25
- * Initial version published at https://www.mslinn.com/git/1100-git-tree.html
58
+
59
+ * Initial version published at https://www.mslinn.com/git/1100-git-tree.html
data/README.md CHANGED
@@ -1,37 +1,41 @@
1
- `Git_tree`
2
- [![Gem Version](https://badge.fury.io/rb/git_tree.svg)](https://badge.fury.io/rb/git_tree)
3
- ===========
1
+ # `Git_tree` [![Gem Version](https://badge.fury.io/rb/git_tree.svg)](https://badge.fury.io/rb/git_tree)
4
2
 
5
- This Ruby gem installs two commands that scan a git directory tree and write out scripts.
3
+ This Ruby gem installs 3 commands that scan a git directory tree;
4
+ 2 of the commands write out scripts and the third executes an arbitrary bash command for each repository.
6
5
  Directories containing a file called `.ignore` are ignored.
7
6
 
8
- - The `git_tree_replicate` command writes a script that clones the repos in the tree,
9
- and adds any defined remotes.
10
- - Any git repos that have already been cloned into the target directory tree are skipped.
11
- This means you can rerun `git_tree_replicate` as many times as you want, without ill effects.
12
- - All remotes in each repo are replicated.
7
+ - The `git-tree-replicate` command writes a script that clones the repos in the tree,
8
+ and adds any defined remotes.
9
+ - Any git repos that have already been cloned into the target directory tree are skipped.
10
+ This means you can rerun `git-tree-replicate` as many times as you want, without ill effects.
11
+ - All remotes in each repo are replicated.
13
12
 
14
- - The `git_tree_evars` command writes a script that defines environment variables pointing to git repos.
13
+ - The `git-tree-evars` command writes a script that defines environment variables pointing to git repos.
14
+
15
+ - The `git-tree-exec` command executes an arbitrary bash command for each repository.
15
16
 
16
17
 
17
18
  ## Usage
18
- Both commands require one environment variable reference to be passed to them.
19
+
20
+ All commands require one environment variable reference to be passed to them.
19
21
  Enclose the name of the environment variable within single quotes,
20
22
  which will prevent the shell from expanding it before invoking the command.
21
23
 
22
24
 
23
- ## `Git_tree_replicate` Usage
25
+ ## `git-tree-replicate` Usage
26
+
24
27
  The following creates a script in the current directory called `work.sh`,
25
28
  that replicates the desired portions of the directory tree of git repos pointed to by `$work`:
29
+
26
30
  ```shell
27
- $ git_tree_replicate '$work' > work.sh
31
+ $ git-tree-replicate '$work' > work.sh
28
32
  ```
29
33
 
30
34
  The generated environment variables will all be relative to the
31
35
  path pointed to by the expanded environment variable that you provided.
32
36
  You will understand what this means once you look at the generated script.
33
37
 
34
- When `git_tree_replicate` completes,
38
+ When `git-tree-replicate` completes,
35
39
  edit the generated script to suit, then
36
40
  copy it to the target machine and run it.
37
41
  The following example copies the script to `machine2` and runs it:
@@ -43,7 +47,8 @@ $ ssh machine2 work.sh
43
47
  ```
44
48
 
45
49
 
46
- ### Generated Script from `git_tree_replicate`
50
+ ### Generated Script from `git-tree-replicate`
51
+
47
52
  Following is a sample of one section, which is repeated for every git repo that is processed:
48
53
  You can edit them to suit.
49
54
 
@@ -57,22 +62,25 @@ if [ ! -d "sinatra/sinatras-skeleton/.git" ]; then
57
62
  fi
58
63
  ```
59
64
 
60
- ## `Git_tree_evars` Usage
61
- The `git_tree_evars` command should be run on the target computer.
65
+ ## `git-tree-evars` Usage
66
+
67
+ The `git-tree-evars` command should be run on the target computer.
62
68
  The command requires only one parameter:
63
69
  an environment variable reference, pointing to the top-level directory to replicate.
64
70
  The environment variable reference must be contained within single quotes to prevent expansion by the shell.
65
71
 
66
72
  The following appends to any script in the `$work` directory called `.evars`.
67
73
  The script defines environment variables that point to each git repos pointed to by `$work`:
74
+
68
75
  ```shell
69
- $ git_tree_evars '$work' >> $work/.evars
76
+ $ git-tree-evars '$work' >> $work/.evars
70
77
  ```
71
78
 
72
79
 
73
- ### Generated Script from `git_tree_evars`
80
+ ### Generated Script from `git-tree-evars`
81
+
74
82
  Following is a sample of environment variable definitions.
75
- You can edit it to suit.
83
+ You are expected to edit it to suit.
76
84
 
77
85
  ```shell
78
86
  export work=/mnt/c/work
@@ -89,12 +97,14 @@ The environment variable definitions are meant to be saved into a file that is `
89
97
  While you could place them in a file like `~/.bashrc`,
90
98
  the author's preference is to instead place them in `$work/.evars`,
91
99
  and add the following to `~/.bashrc`:
100
+
92
101
  ```shell
93
102
  source "$work/.evars"
94
103
  ```
95
104
 
96
105
  Thus each time you log in, the environment variable definitions will have been re-established.
97
106
  You can therefore change directory to any of the cloned projects, like this:
107
+
98
108
  ```shell
99
109
  $ cd $git_root
100
110
 
@@ -102,29 +112,162 @@ $ cd $my_project
102
112
  ```
103
113
 
104
114
 
115
+ ## `git-tree-exec` Usage
116
+
117
+ The `git-tree-exec` command can be run on any computer.
118
+ The command requires two parameters.
119
+ The first parameter indicates the directory or directories to process.
120
+ 3 forms are accepted:
121
+
122
+ 1. A directory name, which may be relative or absolute.
123
+ 2. An environment variable reference,
124
+ which must be contained within single quotes to prevent expansion by the shell.
125
+ 3. A list of directory names, which may be relative or absolute, and may contain environment variables.
126
+
127
+ ### Example 1
128
+
129
+ For all subdirectories of current directory,
130
+ update `Gemfile.lock` and install a local copy of the gem:
131
+
132
+ ```shell
133
+ $ git-tree-exec '
134
+ $jekyll_plugin_logger
135
+ $jekyll_draft
136
+ $jekyll_plugin_support
137
+ $jekyll_all_collections
138
+ $jekyll_plugin_template
139
+ $jekyll_flexible_include_plugin
140
+ $jekyll_href
141
+ $jekyll_img
142
+ $jekyll_outline
143
+ $jekyll_plugin_template
144
+ $jekyll_pre
145
+ $jekyll_quote
146
+ ' 'bundle && bundle update && rake install'
147
+ ```
148
+
149
+ ### Example 2
150
+
151
+ This example shows how to display the version of projects that
152
+ create gems under the directory pointed to by `$my_plugins`.
153
+
154
+ An executable script is required on the `PATH`, so `git-tree-exec`
155
+ can invoke it as it loops through the subdirectories.
156
+ I call this script `version`, and it is written in `bash`,
157
+ although the language used is not significant:
158
+
159
+ ```shell
160
+ #!/bin/bash
161
+
162
+ x="$( ls lib/**/version.rb 2> /dev/null )"
163
+ if [ -f "$x" ]; then
164
+ v="$(
165
+ cat "$x" | \
166
+ grep '=' | \
167
+ sed -e s/.freeze// | \
168
+ tr -d 'VERSION =\"' | \
169
+ tr -d \'
170
+ )"
171
+ echo "$(basename $PWD) v$v"
172
+ fi
173
+ ```
174
+
175
+ Call it like this:
176
+
177
+ ```shell
178
+ $ git-tree-exec '$my_plugins' version
179
+ jekyll_all_collections v0.3.3
180
+ jekyll_archive_create v1.0.2
181
+ jekyll_archive_display v1.0.1
182
+ jekyll_auto_redirect v0.1.0
183
+ jekyll_basename_dirname v1.0.3
184
+ jekyll_begin_end v1.0.1
185
+ jekyll_bootstrap5_tabs v1.1.2
186
+ jekyll_context_inspector v1.0.1
187
+ jekyll_download_link v1.0.1
188
+ jekyll_draft v1.1.2
189
+ jekyll_flexible_include_plugin v2.0.20
190
+ jekyll_from_to_until v1.0.3
191
+ jekyll_href v1.2.5
192
+ jekyll_img v0.1.5
193
+ jekyll_nth v1.1.0
194
+ jekyll_outline v1.2.0
195
+ jekyll_pdf v0.1.0
196
+ jekyll_plugin_logger v2.1.1
197
+ jekyll_plugin_support v0.7.0
198
+ jekyll_plugin_template v0.3.0
199
+ jekyll_pre v1.4.1
200
+ jekyll_quote v0.4.0
201
+ jekyll_random_hex v1.0.0
202
+ jekyll_reading_time v1.0.0
203
+ jekyll_revision v0.1.0
204
+ jekyll_run v1.0.1
205
+ jekyll_site_inspector v1.0.0
206
+ jekyll_sort_natural v1.0.0
207
+ jekyll_time_since v0.1.3
208
+ ```
209
+
210
+ ### Example 3
211
+
212
+ List the projects under the directory pointed to by `$my_plugins`
213
+ that have a `demo/` subdirectory:
214
+
215
+ ```shell
216
+ $ git-tree-exec '$my_plugins' \
217
+ 'if [ -d demo ]; then realpath demo; fi'
218
+ /mnt/c/work/jekyll/my_plugins/jekyll-hello/demo
219
+ /mnt/c/work/jekyll/my_plugins/jekyll_all_collections/demo
220
+ /mnt/c/work/jekyll/my_plugins/jekyll_archive_create/demo
221
+ /mnt/c/work/jekyll/my_plugins/jekyll_download_link/demo
222
+ /mnt/c/work/jekyll/my_plugins/jekyll_draft/demo
223
+ /mnt/c/work/jekyll/my_plugins/jekyll_flexible_include_plugin/demo
224
+ /mnt/c/work/jekyll/my_plugins/jekyll_from_to_until/demo
225
+ /mnt/c/work/jekyll/my_plugins/jekyll_href/demo
226
+ /mnt/c/work/jekyll/my_plugins/jekyll_img/demo
227
+ /mnt/c/work/jekyll/my_plugins/jekyll_outline/demo
228
+ /mnt/c/work/jekyll/my_plugins/jekyll_pdf/demo
229
+ /mnt/c/work/jekyll/my_plugins/jekyll_plugin_support/demo
230
+ /mnt/c/work/jekyll/my_plugins/jekyll_plugin_template/demo
231
+ /mnt/c/work/jekyll/my_plugins/jekyll_pre/demo
232
+ /mnt/c/work/jekyll/my_plugins/jekyll_quote/demo
233
+ /mnt/c/work/jekyll/my_plugins/jekyll_revision/demo
234
+ /mnt/c/work/jekyll/my_plugins/jekyll_time_since/demo
235
+ ```
236
+
237
+
105
238
  ## Installation
106
- Type the following at a shell prompt:
239
+
240
+ Type the following at a shell prompt on the machine you are copying the git tree from,
241
+ and on the machine that you are copying the git tree to:
107
242
 
108
243
  ```shell
244
+ $ yes | sudo apt install cmake libgit2-dev libssh2-1-dev pkg-config
245
+
109
246
  $ gem install git_tree
110
247
  ```
111
248
 
249
+ To register the new commands, either log out and log back in, or open a new console.
250
+
112
251
 
113
252
  ## Additional Information
253
+
114
254
  More information is available on
115
255
  [Mike Slinn’s website](https://www.mslinn.com/git/1100-git-tree.html)
116
256
 
117
257
 
118
258
  ## Development
259
+
119
260
  After checking out the repo, run `bin/setup` to install dependencies.
120
261
 
121
262
  Run the following to create a directory tree for testing.
263
+
122
264
  ```shell
123
265
  $ ruby bin/make_test_directory.rb
124
266
  ```
125
267
 
126
268
  You can run `bin/console` for an interactive prompt that will allow you to experiment.
127
- ```
269
+
270
+ ```shell
128
271
  $ bin/console
129
272
  irb(main):001:0> GitTree.command_replicate 'demo'
130
273
 
@@ -133,13 +276,16 @@ irb(main):002:0> GitTree.command_evars 'demo'
133
276
 
134
277
 
135
278
  ### Build and Install Locally
279
+
136
280
  To build and install this gem onto your local machine, run:
281
+
137
282
  ```shell
138
283
  $ bundle exec rake install
139
284
  ```
140
285
 
141
286
  Examine the newly built gem:
142
- ```
287
+
288
+ ```shell
143
289
  $ gem info git_tree
144
290
 
145
291
  *** LOCAL GEMS ***
@@ -153,14 +299,18 @@ git_tree (0.2.0)
153
299
 
154
300
 
155
301
  ### Build and Push to RubyGems
156
- To release a new version,
302
+
303
+ To release a new version:
304
+
157
305
  1. Update the version number in `version.rb`.
158
306
  2. Commit all changes to git; if you don't the next step might fail with an
159
307
  unexplainable error message.
160
308
  3. Run the following:
309
+
161
310
  ```shell
162
311
  $ bundle exec rake release
163
312
  ```
313
+
164
314
  The above creates a git tag for the version, commits the created tag,
165
315
  and pushes the new `.gem` file to [RubyGems.org](https://rubygems.org).
166
316
 
@@ -174,4 +324,5 @@ To release a new version,
174
324
 
175
325
 
176
326
  ## License
327
+
177
328
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'git_tree_exec'
4
+
5
+ GitTree.command_exec
data/git_tree.gemspec CHANGED
@@ -3,17 +3,21 @@ require_relative 'lib/git_tree/version'
3
3
  Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
4
4
  github = 'https://github.com/mslinn/git_tree'
5
5
 
6
- spec.authors = ['Mike Slinn']
7
- spec.bindir = 'bindir'
6
+ spec.authors = ['Mike Slinn']
7
+ spec.bindir = 'bindir'
8
8
  spec.description = <<~END_OF_DESC
9
- Installs two commands that scan a git directory tree and write out scripts.
9
+ Installs 3 commands that process a git directory tree.
10
10
  Directories containing a file called .ignore are ignored.
11
- The git_tree_replicate command writes a script that clones the repos in the tree,
11
+
12
+ The git-tree-replicate command writes a script that clones the repos in the tree,
12
13
  and adds any defined remotes.
13
- The git_tree_evars command writes a script that defines environment variables pointing to git repos.
14
+
15
+ The git-tree-evars command writes a script that defines environment variables pointing to git repos.
16
+
17
+ The git-tree-exec command executes a bash expression on children of a directory, or a list of directories.
14
18
  END_OF_DESC
15
- spec.email = ['mslinn@mslinn.com']
16
- spec.executables = %w[git_tree_evars git_tree_replicate]
19
+ spec.email = ['mslinn@mslinn.com']
20
+ spec.executables = %w[git-tree-exec git-tree-evars git-tree-replicate]
17
21
  spec.files = Dir[
18
22
  '{bindir,lib}/**/*',
19
23
  '.rubocop.yml',
@@ -23,7 +27,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
23
27
  '*.md'
24
28
  ]
25
29
  spec.homepage = 'https://www.mslinn.com/git/1100-git-tree.html'
26
- spec.license = 'MIT'
30
+ spec.license = 'MIT'
27
31
  spec.metadata = {
28
32
  'allowed_push_host' => 'https://rubygems.org',
29
33
  'bug_tracker_uri' => "#{github}/issues",
@@ -31,15 +35,16 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
31
35
  'homepage_uri' => spec.homepage,
32
36
  'source_code_uri' => github,
33
37
  }
34
- spec.name = 'git_tree'
38
+ spec.name = 'git_tree'
39
+ spec.platform = Gem::Platform::RUBY
35
40
  spec.post_install_message = <<~END_MESSAGE
36
41
 
37
42
  Thanks for installing #{spec.name}!
38
43
 
39
44
  END_MESSAGE
40
45
  spec.required_ruby_version = '>= 2.6.0'
41
- spec.summary = 'Installs two commands that scan a git directory tree and write out scripts for replication.'
42
- spec.version = GitUrlsVersion::VERSION
46
+ spec.summary = 'Installs two commands that scan a git directory tree and write out scripts for replication.'
47
+ spec.version = GitUrlsVersion::VERSION
43
48
 
44
49
  spec.add_dependency 'rainbow'
45
50
  spec.add_dependency 'rugged'
@@ -1,3 +1,3 @@
1
1
  module GitUrlsVersion
2
- VERSION = '0.2.2'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
@@ -1,4 +1,3 @@
1
- require 'shellwords'
2
1
  require_relative 'git_tree'
3
2
 
4
3
  module GitTree
@@ -6,13 +5,16 @@ module GitTree
6
5
 
7
6
  # @param root might be "$envar" or a fully qualified directory name ("/a/b/c")
8
7
  def self.command_evars(root = ARGV[0])
9
- abort "Error: Argument must start with a dollar sign ($)".red unless root.start_with? '$'
8
+ help_evars "Environment variable reference was missing. Please enclose it within single quotes." if root.to_s.empty?
9
+ help_evars "Environment variable reference must start with a dollar sign ($)." unless root.start_with? '$'
10
10
 
11
11
  base = MslinnUtil.expand_env root
12
- dirs = directories_to_process base
12
+ help_evars "Environment variable '#{root}' is undefined." if base.strip.empty?
13
+ help_evars "Environment variable '#{root}' points to a non-existant directory (#{base})." unless File.exist?(base)
14
+ help_evars "Environment variable '#{root}' points to a file (#{base}), not a directory." unless Dir.exist?(base)
13
15
 
14
- # puts "# root=#{root}, base=#{base}"
15
- puts make_env_vars root, base, dirs
16
+ dirs = directories_to_process base
17
+ puts make_env_vars(root, base, dirs)
16
18
  end
17
19
 
18
20
  def self.env_var_name(path)
@@ -21,12 +23,26 @@ module GitTree
21
23
  end
22
24
 
23
25
  def self.help_evars(msg = nil)
24
- puts msg if msg
26
+ prog_name = File.basename $PROGRAM_NAME
27
+ puts "Error: #{msg}\n".red if msg
25
28
  puts <<~END_HELP
26
- Examines a tree of git repos and writes a bash script to STDOUT that defines environment variables that point to the repos in the tree.
27
- Does not redefine existing environment variables.
29
+ #{prog_name} - Examines a tree of git repositories and writes a bash script to STDOUT
30
+ that defines environment variables which point to the repositories in the tree.
31
+
32
+ Does not redefine existing environment variables; messages are written to
33
+ STDERR to indicate environment variables that are not redefined.
34
+
35
+ The environment variable must have been exported, for example:
36
+
37
+ $ export work=$HOME/work
28
38
 
29
39
  Directories containing a file called .ignore are ignored.
40
+
41
+ Usage example:
42
+
43
+ $ #{prog_name} '$work'
44
+
45
+ The name of the environment variable must be preceded by a dollar sign and enclosed within single quotes.
30
46
  END_HELP
31
47
  exit 1
32
48
  end
@@ -39,27 +55,28 @@ module GitTree
39
55
  # @param base a fully qualified directory name ("/a/b/c")
40
56
  # @param dirs directory list to process
41
57
  def self.make_env_vars(root, base, dirs)
42
- help_evars "Error: Please specify the subdirectory to traverse.\n\n" if root.to_s.empty?
58
+ help_evars "Error: Please specify the subdirectory to traverse." if root.to_s.empty?
43
59
 
44
60
  result = []
45
61
  result << make_env_var(env_var_name(base), MslinnUtil.deref_symlink(base))
46
62
  dirs.each do |dir|
47
63
  ename = env_var_name dir
48
64
  ename_value = MslinnUtil.expand_env "$#{ename}"
49
- ename_value = ename_value.shellescape.delete_prefix('\\') unless ename_value.empty?
50
- if ename_value.to_s.empty?
65
+ ename_value = ename_value.gsub(' ', '\\ ').delete_prefix('\\') unless ename_value.empty?
66
+ if ename_value.to_s.strip.empty?
51
67
  result << make_env_var(ename, "#{root}/#{dir}")
52
68
  else
53
69
  msg = "$#{ename} was previously defined as #{ename_value}"
54
- dir = MslinnUtil.expand_env(ename_value)
55
- if Dir.exist? dir
70
+ dir2 = MslinnUtil.expand_env(ename_value)
71
+ if Dir.exist? dir2
56
72
  warn msg.cyan
57
73
  else
58
- msg += ", but that directory does not exist, so redefining #{ename}."
74
+ msg += ", but that directory does not exist,\n so redefining #{ename} as #{dir}."
59
75
  warn msg.green
76
+ result << make_env_var(ename, "#{root}/#{dir}")
60
77
  end
61
78
  end
62
79
  end
63
- result.map { |x| "#{x}\n" }.join
80
+ result.map { |x| "#{x}\n" }.join + "\n"
64
81
  end
65
82
  end
@@ -0,0 +1,94 @@
1
+ require 'pathname'
2
+ require 'shellwords'
3
+ require_relative 'git_tree'
4
+
5
+ module GitTree
6
+ using Rainbow
7
+
8
+ # @param root might be:
9
+ # - '$envar'
10
+ # - A fully qualified directory name ("/a/b/c")
11
+ # - A list of either of the above
12
+ def self.command_exec(args = ARGV)
13
+ root = args[0]
14
+ command = args[1]
15
+
16
+ help_exec "A directory specification and a command must be specified." if args.empty?
17
+ help_exec "A command must be specified." if args.length == 1
18
+
19
+ base = MslinnUtil.expand_env root
20
+ help_exec "Environment variable '#{root}' is undefined." if base.empty?
21
+ base.shellsplit.each do |top|
22
+ dirs = directories_to_process(top)
23
+ dirs.each do |dir|
24
+ dir = File.join(base, dir) if Pathname.new(dir).relative?
25
+ execute dir, command
26
+ end
27
+ end
28
+ end
29
+
30
+ # @return array containing status code and result of running command in the given directory
31
+ # @param command [String] Shell command to execute
32
+ def self.execute(dir, command)
33
+ Dir.chdir(dir) do
34
+ unless File.exist? dir
35
+ warn "Warning: directory '#{dir}' does not exist.".yellow
36
+ return
37
+ end
38
+ unless Dir.exist? dir
39
+ warn "Warning: #{dir} is a file, not a directory.".yellow
40
+ return
41
+ end
42
+ result = `#{command}`.rstrip
43
+ puts result unless result.empty?
44
+ end
45
+ rescue StandardError => e
46
+ warn "Error: #{e.message} from executing '#{command}' in #{dir}".red
47
+ end
48
+
49
+ def self.help_exec(msg = nil)
50
+ prog_name = File.basename $PROGRAM_NAME
51
+ puts "Error: #{msg}\n".red if msg
52
+ puts <<~END_HELP
53
+ #{prog_name} - requires only one parameter,
54
+ which points to the top-level directory to process.
55
+ 3 forms are accepted.
56
+ Only direct child directories are processed; infinite recursion is not supported.
57
+ 1. A directory name, which may be relative or absolute.
58
+ 2. An environment variable reference,
59
+ which must be preceded by a dollar sign and enclosed within single quotes
60
+ to prevent expansion by the shell.
61
+ 3. A list of directory names, which may be relative or absolute,
62
+ and may contain environment variables.
63
+
64
+ The environment variable must have been exported, for example:
65
+
66
+ $ export work=$HOME/work
67
+
68
+ Directories containing a file called .ignore are ignored.
69
+
70
+ Usage examples:
71
+
72
+ 1) For all subdirectories of the current directory,
73
+ update `Gemfile.lock` and install a local copy of the gem:
74
+
75
+ $ #{prog_name} . 'bundle && bundle update && rake install'
76
+
77
+
78
+ 2) For all subdirectories of the directory pointed to by `$work`,
79
+ run git commit and push changes.
80
+
81
+ $ #{prog_name} '$work' 'git commit -am "-" && git push'
82
+
83
+
84
+ 3) For all subdirectories of the specified directories,
85
+ list the projects that have a demo/ subdirectory.
86
+
87
+ The specified directories are . (the current directory),
88
+ ~ (the home directory) and the directory pointed to by $my_plugins
89
+
90
+ $ #{prog_name} '. ~ $my_plugins' 'if [ -d demo]; then realpath demo; fi'
91
+ END_HELP
92
+ exit 1
93
+ end
94
+ end
@@ -1,25 +1,43 @@
1
1
  require_relative 'git_tree'
2
2
 
3
3
  module GitTree
4
+ using Rainbow
5
+
4
6
  # @param root might be "$envar" or a fully qualified directory name ("/a/b/c")
5
7
  def self.command_replicate(root = ARGV[0])
6
- abort "Error: No directories were specified" if root.to_s.empty?
7
- abort "Error: Argument must start with a dollar sign ($)" unless root.start_with? '$'
8
+ help_replicate "Environment variable reference was missing. Please enclose it within single quotes." if root.to_s.empty?
9
+ help_replicate "Error: Environment variable reference must start with a dollar sign ($)" unless root.start_with? '$'
8
10
 
9
11
  base = MslinnUtil.expand_env root
10
- dirs = directories_to_process base
12
+ help_replicate "Environment variable '#{root}' is undefined." if base.strip.empty?
13
+ help_replicate "Environment variable '#{root}' points to a non-existant directory (#{base})." unless File.exist?(base)
14
+ help_replicate "Environment variable '#{root}' points to a file (#{base}), not a directory." unless Dir.exist?(base)
11
15
 
12
- # puts "# root=#{root}, base=#{base}"
13
- puts make_replicate_script root, base, dirs
16
+ dirs = directories_to_process base
17
+ puts make_replicate_script(root, base, dirs)
14
18
  end
15
19
 
16
20
  def self.help_replicate(msg = nil)
17
- puts msg if msg
21
+ prog_name = File.basename $PROGRAM_NAME
22
+ puts "Error: #{msg}\n".red if msg
18
23
  puts <<~END_HELP
19
- Replicates tree of git repos and writes a bash script to STDOUT that clones the repos in the tree.
20
- Adds upstream remotes as required.
24
+ #{prog_name} - Replicates a tree of git repositories and writes a bash script
25
+ to STDOUT that clones the repositories in the tree. Replicates any remotes
26
+ defined in the source repositories to the target repositories.
27
+
28
+ The environment variable must have been exported, for example:
29
+
30
+ $ export work=$HOME/work
21
31
 
22
32
  Directories containing a file called .ignore are ignored.
33
+
34
+ Usage example:
35
+ Assuming that 'work' is an environment variable that contains the name of a
36
+ directory that contains a tree of git repositories:
37
+
38
+ $ #{prog_name} '$work'
39
+
40
+ The name of the environment variable must be preceded by a dollar sign and enclosed within single quotes.
23
41
  END_HELP
24
42
  exit 1
25
43
  end
@@ -38,7 +56,7 @@ module GitTree
38
56
 
39
57
  def self.replicate_one(dir)
40
58
  output = []
41
- project_dir = File.basename dir
59
+ # project_dir = File.basename dir
42
60
  parent_dir = File.dirname dir
43
61
  repo = Rugged::Repository.new dir
44
62
  origin_url = repo.config['remote.origin.url']
@@ -61,7 +79,7 @@ module GitTree
61
79
  # output << ' # Git project directory was renamed, renaming this copy to match original directory structure'
62
80
  # output << " mv #{git_dir_name} #{project_dir}"
63
81
  # end
64
- output << "fi"
82
+ output << 'fi'
65
83
  output << ''
66
84
  output
67
85
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Slinn
8
- autorequire:
9
8
  bindir: bindir
10
9
  cert_chain: []
11
- date: 2023-05-24 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rainbow
@@ -39,16 +38,21 @@ dependencies:
39
38
  - !ruby/object:Gem::Version
40
39
  version: '0'
41
40
  description: |
42
- Installs two commands that scan a git directory tree and write out scripts.
41
+ Installs 3 commands that process a git directory tree.
43
42
  Directories containing a file called .ignore are ignored.
44
- The git_tree_replicate command writes a script that clones the repos in the tree,
43
+
44
+ The git-tree-replicate command writes a script that clones the repos in the tree,
45
45
  and adds any defined remotes.
46
- The git_tree_evars command writes a script that defines environment variables pointing to git repos.
46
+
47
+ The git-tree-evars command writes a script that defines environment variables pointing to git repos.
48
+
49
+ The git-tree-exec command executes a bash expression on children of a directory, or a list of directories.
47
50
  email:
48
51
  - mslinn@mslinn.com
49
52
  executables:
50
- - git_tree_evars
51
- - git_tree_replicate
53
+ - git-tree-evars
54
+ - git-tree-exec
55
+ - git-tree-replicate
52
56
  extensions: []
53
57
  extra_rdoc_files: []
54
58
  files:
@@ -57,12 +61,14 @@ files:
57
61
  - LICENSE.txt
58
62
  - README.md
59
63
  - Rakefile
60
- - bindir/git_tree_evars
61
- - bindir/git_tree_replicate
64
+ - bindir/git-tree-evars
65
+ - bindir/git-tree-exec
66
+ - bindir/git-tree-replicate
62
67
  - git_tree.gemspec
63
68
  - lib/git_tree.rb
64
69
  - lib/git_tree/version.rb
65
70
  - lib/git_tree_evars.rb
71
+ - lib/git_tree_exec.rb
66
72
  - lib/git_tree_replicate.rb
67
73
  - lib/util.rb
68
74
  homepage: https://www.mslinn.com/git/1100-git-tree.html
@@ -92,8 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
98
  - !ruby/object:Gem::Version
93
99
  version: '0'
94
100
  requirements: []
95
- rubygems_version: 3.3.3
96
- signing_key:
101
+ rubygems_version: 3.7.2
97
102
  specification_version: 4
98
103
  summary: Installs two commands that scan a git directory tree and write out scripts
99
104
  for replication.
File without changes
File without changes