git_tree 0.2.0 → 0.2.2
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 +4 -4
- data/.rubocop.yml +4 -2
- data/CHANGELOG.md +6 -1
- data/README.md +20 -12
- data/Rakefile +2 -2
- data/bindir/git_tree_evars +1 -1
- data/bindir/git_tree_replicate +1 -1
- data/git_tree.gemspec +1 -0
- data/lib/git_tree/version.rb +1 -1
- data/lib/git_tree.rb +8 -103
- data/lib/git_tree_evars.rb +65 -0
- data/lib/git_tree_replicate.rb +68 -0
- data/lib/util.rb +62 -1
- metadata +18 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 45ac579ee8e240d6c78bd782b40b1ca473ffd5e7f1d87a1fb81b53012516465c
|
|
4
|
+
data.tar.gz: 32b342b9e45b35a64beca464cf9a0e3af514ea5867cd864916ff551425f3dcd7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7ecfa103809f6cd8d63bbd76b69cbbf5d7af5c746b16a7d533d7bfc9a269687413413b98b7fa5aab27028f37a7d8e2ef4df40decd49a07828549cedfb072c47a
|
|
7
|
+
data.tar.gz: 1dc61521613c96dbb776de98b02b269a3dc0d0aa2605e534fdc19d4facf103c8e4a9fa6dddef143720b841e672b9fc5072c74b81b643cc1fd6ea4ba502a1a821
|
data/.rubocop.yml
CHANGED
|
@@ -66,6 +66,9 @@ Naming/FileName:
|
|
|
66
66
|
RSpec/ExampleLength:
|
|
67
67
|
Max: 20
|
|
68
68
|
|
|
69
|
+
RSpec/FilePath:
|
|
70
|
+
Enabled: false
|
|
71
|
+
|
|
69
72
|
RSpec/MultipleExpectations:
|
|
70
73
|
Max: 15
|
|
71
74
|
|
|
@@ -88,8 +91,7 @@ Style/RegexpLiteral:
|
|
|
88
91
|
Enabled: false
|
|
89
92
|
|
|
90
93
|
Style/StringConcatenation:
|
|
91
|
-
|
|
92
|
-
- spec/**/*
|
|
94
|
+
Enabled: false
|
|
93
95
|
|
|
94
96
|
Style/StringLiterals:
|
|
95
97
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
## 0.2.
|
|
1
|
+
## 0.2.2 / 2023-05-23
|
|
2
|
+
* `git_tree_evars` now checks for previous definitions and issues warnings.
|
|
3
|
+
## 0.2.1 / 2023-05-03
|
|
4
|
+
* Removed the here document wrapper from the output of `git_tree_evars`.
|
|
5
|
+
|
|
6
|
+
## 0.2.0 / 2023-05-03
|
|
2
7
|
* Renamed gem to `git_tree`
|
|
3
8
|
* Renamed `replicate_git_tree` command to `git_tree_replicate`.
|
|
4
9
|
* Added `.evars` support with new executable: `git_tree_evars`
|
data/README.md
CHANGED
|
@@ -15,13 +15,12 @@ Directories containing a file called `.ignore` are ignored.
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
## Usage
|
|
18
|
-
Both commands
|
|
19
|
-
the name of the
|
|
18
|
+
Both commands require one environment variable reference to be passed to them.
|
|
19
|
+
Enclose the name of the environment variable within single quotes,
|
|
20
|
+
which will prevent the shell from expanding it before invoking the command.
|
|
20
21
|
|
|
21
|
-
You must pass an environment variable to both commands.
|
|
22
|
-
Enclosing the name of the env var in single quotes,
|
|
23
|
-
which will prevent the shell from expanding it before invoking either command:
|
|
24
22
|
|
|
23
|
+
## `Git_tree_replicate` Usage
|
|
25
24
|
The following creates a script in the current directory called `work.sh`,
|
|
26
25
|
that replicates the desired portions of the directory tree of git repos pointed to by `$work`:
|
|
27
26
|
```shell
|
|
@@ -29,8 +28,8 @@ $ git_tree_replicate '$work' > work.sh
|
|
|
29
28
|
```
|
|
30
29
|
|
|
31
30
|
The generated environment variables will all be relative to the
|
|
32
|
-
|
|
33
|
-
You will understand what this means once you
|
|
31
|
+
path pointed to by the expanded environment variable that you provided.
|
|
32
|
+
You will understand what this means once you look at the generated script.
|
|
34
33
|
|
|
35
34
|
When `git_tree_replicate` completes,
|
|
36
35
|
edit the generated script to suit, then
|
|
@@ -58,14 +57,24 @@ if [ ! -d "sinatra/sinatras-skeleton/.git" ]; then
|
|
|
58
57
|
fi
|
|
59
58
|
```
|
|
60
59
|
|
|
60
|
+
## `Git_tree_evars` Usage
|
|
61
|
+
The `git_tree_evars` command should be run on the target computer.
|
|
62
|
+
The command requires only one parameter:
|
|
63
|
+
an environment variable reference, pointing to the top-level directory to replicate.
|
|
64
|
+
The environment variable reference must be contained within single quotes to prevent expansion by the shell.
|
|
65
|
+
|
|
66
|
+
The following appends to any script in the `$work` directory called `.evars`.
|
|
67
|
+
The script defines environment variables that point to each git repos pointed to by `$work`:
|
|
68
|
+
```shell
|
|
69
|
+
$ git_tree_evars '$work' >> $work/.evars
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
|
|
61
73
|
### Generated Script from `git_tree_evars`
|
|
62
74
|
Following is a sample of environment variable definitions.
|
|
63
75
|
You can edit it to suit.
|
|
64
|
-
Notice that it appends these environment variable definitions to `$work/.evars`.
|
|
65
|
-
You could cause it to replace the contents of that file by changing the `>>` to `>`.
|
|
66
76
|
|
|
67
77
|
```shell
|
|
68
|
-
cat <<EOF >> $work/.evars
|
|
69
78
|
export work=/mnt/c/work
|
|
70
79
|
export ancientWarmth=$work/ancientWarmth/ancientWarmth
|
|
71
80
|
export ancientWarmthBackend=$work/ancientWarmth/ancientWarmthBackend
|
|
@@ -74,7 +83,6 @@ export survey_analytics=$work/ancientWarmth/survey-analytics
|
|
|
74
83
|
export survey_creator=$work/ancientWarmth/survey-creator
|
|
75
84
|
export django=$work/django/django
|
|
76
85
|
export frobshop=$work/django/frobshop
|
|
77
|
-
EOF
|
|
78
86
|
```
|
|
79
87
|
|
|
80
88
|
The environment variable definitions are meant to be saved into a file that is `source`d upon boot.
|
|
@@ -97,7 +105,7 @@ $ cd $my_project
|
|
|
97
105
|
## Installation
|
|
98
106
|
Type the following at a shell prompt:
|
|
99
107
|
|
|
100
|
-
```
|
|
108
|
+
```shell
|
|
101
109
|
$ gem install git_tree
|
|
102
110
|
```
|
|
103
111
|
|
data/Rakefile
CHANGED
data/bindir/git_tree_evars
CHANGED
data/bindir/git_tree_replicate
CHANGED
data/git_tree.gemspec
CHANGED
|
@@ -41,5 +41,6 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
|
41
41
|
spec.summary = 'Installs two commands that scan a git directory tree and write out scripts for replication.'
|
|
42
42
|
spec.version = GitUrlsVersion::VERSION
|
|
43
43
|
|
|
44
|
+
spec.add_dependency 'rainbow'
|
|
44
45
|
spec.add_dependency 'rugged'
|
|
45
46
|
end
|
data/lib/git_tree/version.rb
CHANGED
data/lib/git_tree.rb
CHANGED
|
@@ -1,38 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# @param root might be "$envar" or a fully qualified directory name ("/a/b/c")
|
|
7
|
-
def self.command_evars(root = ARGV[0])
|
|
8
|
-
abort "Error: Argument must start with a dollar sign ($)" unless root.start_with? '$'
|
|
9
|
-
|
|
10
|
-
base = MslinnUtil.expand_env root
|
|
11
|
-
dirs = directories_to_process base
|
|
12
|
-
|
|
13
|
-
# puts "# root=#{root}, base=#{base}"
|
|
14
|
-
puts make_env_vars root, base, dirs
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# @param root might be "$envar" or a fully qualified directory name ("/a/b/c")
|
|
18
|
-
def self.command_replicate(root = ARGV[0])
|
|
19
|
-
abort "Error: Argument must start with a dollar sign ($)" unless root.start_with? '$'
|
|
1
|
+
require 'find'
|
|
2
|
+
require 'rainbow/refinement'
|
|
3
|
+
require 'rugged'
|
|
4
|
+
require_relative 'util'
|
|
20
5
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# puts "# root=#{root}, base=#{base}"
|
|
25
|
-
puts make_replicate_script root, base, dirs
|
|
26
|
-
end
|
|
6
|
+
module GitTree
|
|
7
|
+
using Rainbow
|
|
27
8
|
|
|
28
9
|
# @return array containing directory names to process
|
|
29
10
|
# Each directory name ends with a slash, to ensure symlinks are dereferences
|
|
30
11
|
def self.directories_to_process(root)
|
|
31
12
|
root_fq = File.expand_path root
|
|
32
|
-
abort "Error: #{root_fq} is a file, instead of a directory. Cannot recurse." if File.file? root_fq
|
|
13
|
+
abort "Error: #{root_fq} is a file, instead of a directory. Cannot recurse.".red if File.file? root_fq
|
|
33
14
|
|
|
34
15
|
root_fq = MslinnUtil.deref_symlink(root_fq).to_s
|
|
35
|
-
abort "Error: #{root_fq} does not exist. Halting." unless Dir.exist? root_fq
|
|
16
|
+
abort "Error: #{root_fq} does not exist. Halting.".red unless Dir.exist? root_fq
|
|
36
17
|
|
|
37
18
|
result = []
|
|
38
19
|
Find.find(root_fq) do |path|
|
|
@@ -47,80 +28,4 @@ module GitTree
|
|
|
47
28
|
end
|
|
48
29
|
result.map { |x| x.delete_prefix("#{root_fq}/") }
|
|
49
30
|
end
|
|
50
|
-
|
|
51
|
-
def self.env_var_name(path)
|
|
52
|
-
name = path.include?('/') ? File.basename(path) : path
|
|
53
|
-
name.tr(' ', '_').tr('-', '_')
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def self.help(msg = nil)
|
|
57
|
-
puts msg if msg
|
|
58
|
-
puts <<~END_HELP
|
|
59
|
-
Replicates tree of git repos and writes a bash script to STDOUT that clones the repos in the tree.
|
|
60
|
-
Adds upstream remotes as required.
|
|
61
|
-
|
|
62
|
-
Directories containing a file called .ignore are ignored.
|
|
63
|
-
END_HELP
|
|
64
|
-
exit 1
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def self.make_env_var(name, value)
|
|
68
|
-
"export #{env_var_name(name)}=#{value}"
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# @param root might be "$envar" or a fully qualified directory name ("/a/b/c")
|
|
72
|
-
# @param base a fully qualified directory name ("/a/b/c")
|
|
73
|
-
# @param dirs directory list to process
|
|
74
|
-
def self.make_env_vars(root, base, dirs)
|
|
75
|
-
result = []
|
|
76
|
-
result << "cat <<EOF >> #{root}/.evars"
|
|
77
|
-
result << make_env_var(env_var_name(base), MslinnUtil.deref_symlink(base))
|
|
78
|
-
dirs.each do |dir|
|
|
79
|
-
result << make_env_var(env_var_name(dir), "#{root}/#{dir}")
|
|
80
|
-
end
|
|
81
|
-
result << "EOF\n"
|
|
82
|
-
result.join "\n"
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# @param root might be "$envar" or a fully qualified directory name ("/a/b/c")
|
|
86
|
-
# @param base a fully qualified directory name ("/a/b/c")
|
|
87
|
-
# @param dirs directory list to process
|
|
88
|
-
def self.make_replicate_script(root, base, dirs)
|
|
89
|
-
help "Error: Please specify the subdirectory to traverse.\n\n" if root.to_s.empty?
|
|
90
|
-
|
|
91
|
-
Dir.chdir(base) do
|
|
92
|
-
result = dirs.map { |dir| replicate_one(dir) }
|
|
93
|
-
result.join "\n"
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def self.replicate_one(dir)
|
|
98
|
-
output = []
|
|
99
|
-
project_dir = File.basename dir
|
|
100
|
-
parent_dir = File.dirname dir
|
|
101
|
-
repo = Rugged::Repository.new dir
|
|
102
|
-
origin_url = repo.config['remote.origin.url']
|
|
103
|
-
|
|
104
|
-
output << "if [ ! -d \"#{dir}/.git\" ]; then"
|
|
105
|
-
output << " mkdir -p '#{parent_dir}'"
|
|
106
|
-
output << " pushd '#{parent_dir}' > /dev/null"
|
|
107
|
-
output << " git clone #{origin_url}"
|
|
108
|
-
|
|
109
|
-
repo.remotes.each do |remote|
|
|
110
|
-
next if remote.name == 'origin' || remote.url == 'no_push'
|
|
111
|
-
|
|
112
|
-
output << " git remote add #{remote.name} '#{remote.url}'"
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
output << ' popd > /dev/null'
|
|
116
|
-
|
|
117
|
-
# git_dir_name = File.basename Dir.pwd
|
|
118
|
-
# if git_dir_name != project_dir
|
|
119
|
-
# output << ' # Git project directory was renamed, renaming this copy to match original directory structure'
|
|
120
|
-
# output << " mv #{git_dir_name} #{project_dir}"
|
|
121
|
-
# end
|
|
122
|
-
output << "fi"
|
|
123
|
-
output << ''
|
|
124
|
-
output
|
|
125
|
-
end
|
|
126
31
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
require_relative 'git_tree'
|
|
3
|
+
|
|
4
|
+
module GitTree
|
|
5
|
+
using Rainbow
|
|
6
|
+
|
|
7
|
+
# @param root might be "$envar" or a fully qualified directory name ("/a/b/c")
|
|
8
|
+
def self.command_evars(root = ARGV[0])
|
|
9
|
+
abort "Error: Argument must start with a dollar sign ($)".red unless root.start_with? '$'
|
|
10
|
+
|
|
11
|
+
base = MslinnUtil.expand_env root
|
|
12
|
+
dirs = directories_to_process base
|
|
13
|
+
|
|
14
|
+
# puts "# root=#{root}, base=#{base}"
|
|
15
|
+
puts make_env_vars root, base, dirs
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.env_var_name(path)
|
|
19
|
+
name = path.include?('/') ? File.basename(path) : path
|
|
20
|
+
name.tr(' ', '_').tr('-', '_')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.help_evars(msg = nil)
|
|
24
|
+
puts msg if msg
|
|
25
|
+
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.
|
|
28
|
+
|
|
29
|
+
Directories containing a file called .ignore are ignored.
|
|
30
|
+
END_HELP
|
|
31
|
+
exit 1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.make_env_var(name, value)
|
|
35
|
+
"export #{env_var_name(name)}=#{value}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @param root should be an "$envar" that points to the root of a directory tree containing git repos.
|
|
39
|
+
# @param base a fully qualified directory name ("/a/b/c")
|
|
40
|
+
# @param dirs directory list to process
|
|
41
|
+
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?
|
|
43
|
+
|
|
44
|
+
result = []
|
|
45
|
+
result << make_env_var(env_var_name(base), MslinnUtil.deref_symlink(base))
|
|
46
|
+
dirs.each do |dir|
|
|
47
|
+
ename = env_var_name dir
|
|
48
|
+
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?
|
|
51
|
+
result << make_env_var(ename, "#{root}/#{dir}")
|
|
52
|
+
else
|
|
53
|
+
msg = "$#{ename} was previously defined as #{ename_value}"
|
|
54
|
+
dir = MslinnUtil.expand_env(ename_value)
|
|
55
|
+
if Dir.exist? dir
|
|
56
|
+
warn msg.cyan
|
|
57
|
+
else
|
|
58
|
+
msg += ", but that directory does not exist, so redefining #{ename}."
|
|
59
|
+
warn msg.green
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
result.map { |x| "#{x}\n" }.join
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require_relative 'git_tree'
|
|
2
|
+
|
|
3
|
+
module GitTree
|
|
4
|
+
# @param root might be "$envar" or a fully qualified directory name ("/a/b/c")
|
|
5
|
+
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
|
+
|
|
9
|
+
base = MslinnUtil.expand_env root
|
|
10
|
+
dirs = directories_to_process base
|
|
11
|
+
|
|
12
|
+
# puts "# root=#{root}, base=#{base}"
|
|
13
|
+
puts make_replicate_script root, base, dirs
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.help_replicate(msg = nil)
|
|
17
|
+
puts msg if msg
|
|
18
|
+
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.
|
|
21
|
+
|
|
22
|
+
Directories containing a file called .ignore are ignored.
|
|
23
|
+
END_HELP
|
|
24
|
+
exit 1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @param root should be an "$envar" that points to the root of a directory tree containing git repos.
|
|
28
|
+
# @param base a fully qualified directory name ("/a/b/c")
|
|
29
|
+
# @param dirs directory list to process
|
|
30
|
+
def self.make_replicate_script(root, base, dirs)
|
|
31
|
+
help_replicate "Error: Please specify the subdirectory to traverse.\n\n" if root.to_s.empty?
|
|
32
|
+
|
|
33
|
+
Dir.chdir(base) do
|
|
34
|
+
result = dirs.map { |dir| replicate_one(dir) }
|
|
35
|
+
result.join "\n"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.replicate_one(dir)
|
|
40
|
+
output = []
|
|
41
|
+
project_dir = File.basename dir
|
|
42
|
+
parent_dir = File.dirname dir
|
|
43
|
+
repo = Rugged::Repository.new dir
|
|
44
|
+
origin_url = repo.config['remote.origin.url']
|
|
45
|
+
|
|
46
|
+
output << "if [ ! -d \"#{dir}/.git\" ]; then"
|
|
47
|
+
output << " mkdir -p '#{parent_dir}'"
|
|
48
|
+
output << " pushd '#{parent_dir}' > /dev/null"
|
|
49
|
+
output << " git clone #{origin_url}"
|
|
50
|
+
|
|
51
|
+
repo.remotes.each do |remote|
|
|
52
|
+
next if remote.name == 'origin' || remote.url == 'no_push'
|
|
53
|
+
|
|
54
|
+
output << " git remote add #{remote.name} '#{remote.url}'"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
output << ' popd > /dev/null'
|
|
58
|
+
|
|
59
|
+
# git_dir_name = File.basename Dir.pwd
|
|
60
|
+
# if git_dir_name != project_dir
|
|
61
|
+
# output << ' # Git project directory was renamed, renaming this copy to match original directory structure'
|
|
62
|
+
# output << " mv #{git_dir_name} #{project_dir}"
|
|
63
|
+
# end
|
|
64
|
+
output << "fi"
|
|
65
|
+
output << ''
|
|
66
|
+
output
|
|
67
|
+
end
|
|
68
|
+
end
|
data/lib/util.rb
CHANGED
|
@@ -1,4 +1,66 @@
|
|
|
1
1
|
module MslinnUtil
|
|
2
|
+
# @param paths [Array[String]] all start with a leading '/' (they are assumed to be absolute paths).
|
|
3
|
+
# @return [String] the longest path prefix that is a prefix of all paths in array.
|
|
4
|
+
# If array is empty, return ''.
|
|
5
|
+
# If only the leading slash matches, and allow_root_match is true, return '/', else return ''.
|
|
6
|
+
def self.common_prefix(paths, allow_root_match: false)
|
|
7
|
+
return '' if paths.empty?
|
|
8
|
+
|
|
9
|
+
relative_paths = paths.reject { |x| x.start_with? '/' }
|
|
10
|
+
abort "Error: common_prefix received relative paths:" + relative_paths.map { |x| " #{x}\n" } \
|
|
11
|
+
unless relative_paths.empty?
|
|
12
|
+
|
|
13
|
+
if paths.length == 1
|
|
14
|
+
result = paths.first.split('/').slice(0...-1).join('/')
|
|
15
|
+
return result.empty? && allow_root_match ? '/' : result
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
arr = paths.sort
|
|
19
|
+
first = arr.first.split('/')
|
|
20
|
+
last = arr.last.split('/')
|
|
21
|
+
i = 0
|
|
22
|
+
i += 1 while first[i] == last[i] && i <= first.length
|
|
23
|
+
result = first.slice(0, i).join('/')
|
|
24
|
+
|
|
25
|
+
result.empty? && allow_root_match ? '/' : result
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @param paths [Array[String]] absolute paths to examine
|
|
29
|
+
# @param level [Int] minimum # of leading directory names in result, origin 1
|
|
30
|
+
def self.roots(paths, level, allow_root_match: false)
|
|
31
|
+
abort "Error: level must be positive, but it is #{level}." unless level.positive?
|
|
32
|
+
return allow_root_match ? '/' : '' if paths.empty?
|
|
33
|
+
|
|
34
|
+
abort("Error: level parameter must be positive, #{level} was supplied instead.") if level <= 0
|
|
35
|
+
|
|
36
|
+
if paths.length == 1
|
|
37
|
+
root = File.dirname(paths.first)
|
|
38
|
+
return allow_root_match ? '/' : '' if root == '/'
|
|
39
|
+
|
|
40
|
+
return root
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
loop do
|
|
44
|
+
paths = trim_to_level(paths, level) # does this change paths in the caller?
|
|
45
|
+
return paths.first if paths.length == 1
|
|
46
|
+
|
|
47
|
+
level -= 1
|
|
48
|
+
break if level.zero?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
allow_root_match ? '/' : ''
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @param paths [Array[String]] absolute paths to examine
|
|
55
|
+
# @param level is origin 1
|
|
56
|
+
def self.trim_to_level(paths, level)
|
|
57
|
+
result = paths.map do |x|
|
|
58
|
+
elements = x.split('/').reject(&:empty?)
|
|
59
|
+
'/' + elements[0..level - 1].join('/')
|
|
60
|
+
end
|
|
61
|
+
result.sort.uniq
|
|
62
|
+
end
|
|
63
|
+
|
|
2
64
|
# @return Path to symlink
|
|
3
65
|
def self.deref_symlink(symlink)
|
|
4
66
|
require 'pathname'
|
|
@@ -15,5 +77,4 @@ module MslinnUtil
|
|
|
15
77
|
ENV.fetch(Regexp.last_match(1), nil)
|
|
16
78
|
end
|
|
17
79
|
end
|
|
18
|
-
|
|
19
80
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: git_tree
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Slinn
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bindir
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-05-
|
|
11
|
+
date: 2023-05-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rainbow
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: rugged
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -48,6 +62,8 @@ files:
|
|
|
48
62
|
- git_tree.gemspec
|
|
49
63
|
- lib/git_tree.rb
|
|
50
64
|
- lib/git_tree/version.rb
|
|
65
|
+
- lib/git_tree_evars.rb
|
|
66
|
+
- lib/git_tree_replicate.rb
|
|
51
67
|
- lib/util.rb
|
|
52
68
|
homepage: https://www.mslinn.com/git/1100-git-tree.html
|
|
53
69
|
licenses:
|