mixlibrary-core 0.0.12 → 0.0.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +70 -69
- data/lib/mixlibrary/core/shell/shell_call.rb +28 -28
- data/lib/mixlibrary/core/utilities/ruby_info.rb +31 -31
- data/lib/mixlibrary/core/utilities/windows_architecture_helper.rb +78 -78
- data/lib/mixlibrary/core/version.rb +1 -1
- data/lib/mixlibrary/core/windows/features.rb +101 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef4a566c667287778808f57fffce0bb5a57f754d
|
4
|
+
data.tar.gz: 873869ec7de6d902d8110bd221a83d3f7c1c8438
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec1f03b9858fb2e45b413a49c6a92a03f2ceb482bdce59222560f82fdd65827d3ff331e15da9e4cdd36ed9f044d0169bb102277814412dfa3c6cd704ae309888
|
7
|
+
data.tar.gz: 8e94b5c2e35b9177954d93b6f646130ee468f2a325e2e9fa08967f561ef484cc97dce1ebe6be42d52a8d69836f66838c11aba4786654b4858ed4417b62d4dafa
|
data/README.md
CHANGED
@@ -1,69 +1,70 @@
|
|
1
|
-
# Mixlibrary-Core
|
2
|
-
[![GitHub](http://img.shields.io/badge/github-ebsco/mixlibrary-blue.svg)](https://github.com/ebsco/mixlibrary-core)
|
3
|
-
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/mixlibrary-core/frames)
|
4
|
-
|
5
|
-
[![Gem Version](https://badge.fury.io/rb/mixlibrary-core.svg)](https://github.com/ebsco/mixlibrary-core/releases)
|
6
|
-
[![Build Status](https://api.travis-ci.org/ebsco/mixlibrary-core.svg?branch=master)](https://travis-ci.org/ebsco/mixlibrary-core)
|
7
|
-
[![License](http://img.shields.io/badge/license-Apache2-yellowgreen.svg)](https://github.com/ebsco/mixlibrary-core/blob/master/LICENSE.txt)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
1
|
+
# Mixlibrary-Core
|
2
|
+
[![GitHub](http://img.shields.io/badge/github-ebsco/mixlibrary-blue.svg)](https://github.com/ebsco/mixlibrary-core)
|
3
|
+
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/mixlibrary-core/frames)
|
4
|
+
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/mixlibrary-core.svg)](https://github.com/ebsco/mixlibrary-core/releases)
|
6
|
+
[![Build Status - Linux](https://api.travis-ci.org/ebsco/mixlibrary-core.svg?branch=master)](https://travis-ci.org/ebsco/mixlibrary-core)
|
7
|
+
[![License](http://img.shields.io/badge/license-Apache2-yellowgreen.svg)](https://github.com/ebsco/mixlibrary-core/blob/master/LICENSE.txt)
|
8
|
+
[![Build status - Windows](https://ci.appveyor.com/api/projects/status/0d26tuv87r13b27r/branch/master?svg=true)](https://ci.appveyor.com/project/carpnick/mixlibrary-core/branch/master)
|
9
|
+
|
10
|
+
Wraps some provider functionality from chef into easily consumable ruby classes that do not have the extra baggage of being dependent on Chef data objects. Node object, Environment etc.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'mixlibrary-core'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle install
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install mixlibrary-core
|
25
|
+
|
26
|
+
## How to Install via Chef Recipe
|
27
|
+
* [Recipe Install Sample](https://github.com/ebsco/mixlibrary-core/blob/master/Samples/SampleRecipeDeployment.rb)
|
28
|
+
|
29
|
+
## Documentation
|
30
|
+
* Uses yard to document classes and methods. Generate docs or automatic documentation: http://www.rubydoc.info
|
31
|
+
* rake doc
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
### Windows Oriented
|
36
|
+
|
37
|
+
#### Powershell Scripts
|
38
|
+
Needed ability to execute powershell scripts and get the powershell process back. So to execute a powershell script:
|
39
|
+
|
40
|
+
```
|
41
|
+
require 'mixlibrary/core/apps/shell'
|
42
|
+
|
43
|
+
script= <<-EOF
|
44
|
+
write-host "Hello 'World'"
|
45
|
+
EOF
|
46
|
+
|
47
|
+
procobj = Mixlibrary::Core::Shell.windows_script_out!(:powershell,script)
|
48
|
+
```
|
49
|
+
|
50
|
+
#### Batch
|
51
|
+
Not Implemented yet
|
52
|
+
|
53
|
+
### Linux Oriented
|
54
|
+
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
# Run All the Tests on your platform and build the gem
|
58
|
+
|
59
|
+
bundle install
|
60
|
+
|
61
|
+
bundle exec rake
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
1. Fork it (http://github.com/<my-github-username>/mixlibrary-core/fork)
|
67
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
68
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
69
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
70
|
+
5. Create new Pull Request
|
@@ -1,28 +1,28 @@
|
|
1
|
-
#We had our hand forced here. We had to make this an instantianted class because the Ruby Include syntax does not work with entirely static methods.
|
2
|
-
|
3
|
-
module Mixlibrary
|
4
|
-
module Core
|
5
|
-
module Shell
|
6
|
-
class ShellCall
|
7
|
-
include Chef::Mixin::ShellOut
|
8
|
-
|
9
|
-
def
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def shell(command, options)
|
14
|
-
result = shell_out("#{command}", options)
|
15
|
-
return result
|
16
|
-
end
|
17
|
-
|
18
|
-
def shell!(command, options)
|
19
|
-
result = shell_out!("#{command}", options)
|
20
|
-
return result
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
|
1
|
+
#We had our hand forced here. We had to make this an instantianted class because the Ruby Include syntax does not work with entirely static methods.
|
2
|
+
|
3
|
+
module Mixlibrary
|
4
|
+
module Core
|
5
|
+
module Shell
|
6
|
+
class ShellCall
|
7
|
+
include Chef::Mixin::ShellOut
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def shell(command, options)
|
14
|
+
result = shell_out("#{command}", options)
|
15
|
+
return result
|
16
|
+
end
|
17
|
+
|
18
|
+
def shell!(command, options)
|
19
|
+
result = shell_out!("#{command}", options)
|
20
|
+
return result
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
@@ -1,31 +1,31 @@
|
|
1
|
-
#Begin defining constant symbols for ruby versions
|
2
|
-
|
3
|
-
module Mixlibrary
|
4
|
-
module Core
|
5
|
-
module Utilities
|
6
|
-
class RubyInfo
|
7
|
-
|
8
|
-
def self.windows?
|
9
|
-
if RUBY_PLATFORM =~ /mswin|mingw|windows/
|
10
|
-
true
|
11
|
-
else
|
12
|
-
false
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.architecture
|
17
|
-
#x64-mingw32
|
18
|
-
#i386-mingw32
|
19
|
-
myarch = RbConfig::CONFIG["arch"]
|
20
|
-
if(myarch.upcase.include?("I386"))
|
21
|
-
return :i386
|
22
|
-
elsif (myarch.upcase.include?("X64"))
|
23
|
-
return :x86_64
|
24
|
-
else
|
25
|
-
raise "Unsupported arch found: #{myarch}"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
1
|
+
#Begin defining constant symbols for ruby versions
|
2
|
+
|
3
|
+
module Mixlibrary
|
4
|
+
module Core
|
5
|
+
module Utilities
|
6
|
+
class RubyInfo
|
7
|
+
|
8
|
+
def self.windows?
|
9
|
+
if RUBY_PLATFORM =~ /mswin|mingw|windows/
|
10
|
+
true
|
11
|
+
else
|
12
|
+
false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.architecture
|
17
|
+
#x64-mingw32
|
18
|
+
#i386-mingw32
|
19
|
+
myarch = RbConfig::CONFIG["arch"]
|
20
|
+
if(myarch.upcase.include?("I386"))
|
21
|
+
return :i386
|
22
|
+
elsif (myarch.upcase.include?("X64"))
|
23
|
+
return :x86_64
|
24
|
+
else
|
25
|
+
raise "Unsupported arch found: #{myarch}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,79 +1,79 @@
|
|
1
|
-
require 'mixlibrary/core/utilities/ruby_info'
|
2
|
-
require 'win32/api' if Mixlibrary::Core::Utilities::RubyInfo.windows?
|
3
|
-
|
4
|
-
module Mixlibrary
|
5
|
-
module Core
|
6
|
-
module Utilities
|
7
|
-
class WindowsArchitectureHelper
|
8
|
-
|
9
|
-
#Attempts to determine if this machine is 64 bit or not in a variety of ways - using generic ruby and/or Windows specific environment variabes
|
10
|
-
def self.is_machine_64bit?
|
11
|
-
if(RubyInfo.architecture==:x86_64)
|
12
|
-
return true
|
13
|
-
end
|
14
|
-
|
15
|
-
if(ENV.has_key?('ProgramFiles(x86)'))
|
16
|
-
return true;
|
17
|
-
end
|
18
|
-
|
19
|
-
if(ENV.has_key?('PROCESSOR_ARCHITEW6432'))
|
20
|
-
return true;
|
21
|
-
end
|
22
|
-
|
23
|
-
return false;
|
24
|
-
end
|
25
|
-
|
26
|
-
#returns the architecture based on if the machine is 64 bit
|
27
|
-
def self.architecture
|
28
|
-
if(is_machine_64bit?)
|
29
|
-
return :x86_64
|
30
|
-
else
|
31
|
-
return :i386
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
#Determines if the syswow redirection needs to be disabled based on the desired architecture.
|
36
|
-
def self.wow64_architecture_override_required?(desired_architecture)
|
37
|
-
#only use case we need to disable redirection is if
|
38
|
-
#running as 32 bit
|
39
|
-
#want 64 bit
|
40
|
-
#On 64bit machine
|
41
|
-
RubyInfo.architecture==:i386 &&
|
42
|
-
desired_architecture == :x86_64 &&
|
43
|
-
is_machine_64bit?
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
#Disables syswow redirection
|
48
|
-
def self.disable_wow64_file_redirection()
|
49
|
-
original_redirection_state = ['0'].pack('P')
|
50
|
-
|
51
|
-
win32_wow_64_disable_wow_64_fs_redirection =
|
52
|
-
::Win32::API.new('Wow64DisableWow64FsRedirection', 'P', 'L', 'kernel32')
|
53
|
-
|
54
|
-
succeeded = win32_wow_64_disable_wow_64_fs_redirection.call(original_redirection_state)
|
55
|
-
|
56
|
-
if succeeded == 0
|
57
|
-
raise "Failed to disable Wow64 file redirection"
|
58
|
-
end
|
59
|
-
|
60
|
-
return original_redirection_state
|
61
|
-
end
|
62
|
-
|
63
|
-
#Restore syswow redirection
|
64
|
-
def self.restore_wow64_file_redirection(original_redirection_state )
|
65
|
-
|
66
|
-
win32_wow_64_revert_wow_64_fs_redirection =
|
67
|
-
::Win32::API.new('Wow64RevertWow64FsRedirection', 'P', 'L', 'kernel32')
|
68
|
-
|
69
|
-
succeeded = win32_wow_64_revert_wow_64_fs_redirection.call(original_redirection_state)
|
70
|
-
|
71
|
-
if succeeded == 0
|
72
|
-
raise "Failed to revert Wow64 file redirection"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
1
|
+
require 'mixlibrary/core/utilities/ruby_info'
|
2
|
+
require 'win32/api' if Mixlibrary::Core::Utilities::RubyInfo.windows?
|
3
|
+
|
4
|
+
module Mixlibrary
|
5
|
+
module Core
|
6
|
+
module Utilities
|
7
|
+
class WindowsArchitectureHelper
|
8
|
+
|
9
|
+
#Attempts to determine if this machine is 64 bit or not in a variety of ways - using generic ruby and/or Windows specific environment variabes
|
10
|
+
def self.is_machine_64bit?
|
11
|
+
if(RubyInfo.architecture==:x86_64)
|
12
|
+
return true
|
13
|
+
end
|
14
|
+
|
15
|
+
if(ENV.has_key?('ProgramFiles(x86)'))
|
16
|
+
return true;
|
17
|
+
end
|
18
|
+
|
19
|
+
if(ENV.has_key?('PROCESSOR_ARCHITEW6432'))
|
20
|
+
return true;
|
21
|
+
end
|
22
|
+
|
23
|
+
return false;
|
24
|
+
end
|
25
|
+
|
26
|
+
#returns the architecture based on if the machine is 64 bit
|
27
|
+
def self.architecture
|
28
|
+
if(is_machine_64bit?)
|
29
|
+
return :x86_64
|
30
|
+
else
|
31
|
+
return :i386
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
#Determines if the syswow redirection needs to be disabled based on the desired architecture.
|
36
|
+
def self.wow64_architecture_override_required?(desired_architecture)
|
37
|
+
#only use case we need to disable redirection is if
|
38
|
+
#running as 32 bit
|
39
|
+
#want 64 bit
|
40
|
+
#On 64bit machine
|
41
|
+
RubyInfo.architecture==:i386 &&
|
42
|
+
desired_architecture == :x86_64 &&
|
43
|
+
is_machine_64bit?
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
#Disables syswow redirection
|
48
|
+
def self.disable_wow64_file_redirection()
|
49
|
+
original_redirection_state = ['0'].pack('P')
|
50
|
+
|
51
|
+
win32_wow_64_disable_wow_64_fs_redirection =
|
52
|
+
::Win32::API.new('Wow64DisableWow64FsRedirection', 'P', 'L', 'kernel32')
|
53
|
+
|
54
|
+
succeeded = win32_wow_64_disable_wow_64_fs_redirection.call(original_redirection_state)
|
55
|
+
|
56
|
+
if succeeded == 0
|
57
|
+
raise "Failed to disable Wow64 file redirection"
|
58
|
+
end
|
59
|
+
|
60
|
+
return original_redirection_state
|
61
|
+
end
|
62
|
+
|
63
|
+
#Restore syswow redirection
|
64
|
+
def self.restore_wow64_file_redirection(original_redirection_state )
|
65
|
+
|
66
|
+
win32_wow_64_revert_wow_64_fs_redirection =
|
67
|
+
::Win32::API.new('Wow64RevertWow64FsRedirection', 'P', 'L', 'kernel32')
|
68
|
+
|
69
|
+
succeeded = win32_wow_64_revert_wow_64_fs_redirection.call(original_redirection_state)
|
70
|
+
|
71
|
+
if succeeded == 0
|
72
|
+
raise "Failed to revert Wow64 file redirection"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
79
|
end
|
@@ -1,8 +1,102 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
require 'mixlibrary/core/apps/shell'
|
2
|
+
#require 'mixlibrary/core/windows/features'
|
3
|
+
#myclass=Mixlibrary::Core::Windows::Features.new("Web-Server")
|
4
|
+
module Mixlibrary
|
5
|
+
module Core
|
6
|
+
module Windows
|
7
|
+
class Features
|
8
|
+
|
9
|
+
def initialize(feature_name)
|
10
|
+
if feature_name.to_s.strip.length == 0
|
11
|
+
# It's nil, empty, or just whitespace
|
12
|
+
raise "Feature name cannot be empty or just white space"
|
13
|
+
end
|
14
|
+
|
15
|
+
@feature_name=feature_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def install_feature()
|
19
|
+
Chef::Log.info("Installing feature:#{@feature_name}")
|
20
|
+
script= <<-EOF
|
21
|
+
import-module ServerManager;
|
22
|
+
Add-WindowsFeature -Name "#{@feature_name}"
|
23
|
+
EOF
|
24
|
+
|
25
|
+
procobj = Mixlibrary::Core::Shell.windows_script_out!(:powershell, script)
|
26
|
+
Chef::Log.debug("Command output: #{procobj.stdout}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove_feature()
|
30
|
+
Chef::Log.info("Removing feature:#{@feature_name}")
|
31
|
+
script= <<-EOF
|
32
|
+
import-module ServerManager;
|
33
|
+
Remove-WindowsFeature -Name "#{@feature_name}"
|
34
|
+
EOF
|
35
|
+
|
36
|
+
procobj = Mixlibrary::Core::Shell.windows_script_out!(:powershell, script)
|
37
|
+
Chef::Log.debug("Command output: #{procobj.stdout}")
|
38
|
+
end
|
39
|
+
|
40
|
+
def install_feature()
|
41
|
+
Chef::Log.info("Installing feature:#{@feature_name}")
|
42
|
+
script= <<-EOF
|
43
|
+
import-module ServerManager;
|
44
|
+
Add-WindowsFeature -Name "#{@feature_name}"
|
45
|
+
EOF
|
46
|
+
|
47
|
+
procobj = Mixlibrary::Core::Shell.windows_script_out!(:powershell, script)
|
48
|
+
Chef::Log.debug("Command output: #{procobj.stdout}")
|
49
|
+
end
|
50
|
+
|
51
|
+
def is_feature_available?()
|
52
|
+
Chef::Log.info("Is feature available:#{@feature_name}")
|
53
|
+
script= <<-EOF
|
54
|
+
import-module ServerManager;
|
55
|
+
Get-WindowsFeature -Name #{@feature_name}
|
56
|
+
EOF
|
57
|
+
|
58
|
+
procobj = Mixlibrary::Core::Shell.windows_script_out!(:powershell, script)
|
59
|
+
Chef::Log.info("Command output:#{procobj.stdout}")
|
60
|
+
|
61
|
+
return procobj.stderr.empty? && procobj.stdout !~ /Removed/i
|
62
|
+
end
|
63
|
+
|
64
|
+
def is_installed?
|
65
|
+
Chef::Log.info("Is feature installed:#{@feature_name}")
|
66
|
+
#Need to handle this use case: Get-WindowsFeature Web* | Select Installed | % { Write-Host $_.Installed }
|
67
|
+
#(cmd.stdout =~ /true/i) != nil ---There needs to be one true
|
68
|
+
#(cmd.stdout =~ /False/i) == nil ---There needs to be no false
|
69
|
+
#And no standard error
|
70
|
+
script= <<-EOF
|
71
|
+
import-module ServerManager;
|
72
|
+
Get-WindowsFeature -Name #{@feature_name} | Select Installed | % { Write-Host $_.Installed }
|
73
|
+
EOF
|
74
|
+
|
75
|
+
procobj = Mixlibrary::Core::Shell.windows_script_out!(:powershell, script)
|
76
|
+
Chef::Log.debug("Command output:#{procobj.stdout}")
|
77
|
+
procobj.stderr.empty? && (procobj.stdout =~ /False/i) == nil && (procobj.stdout =~ /true/i) != nil
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
def above_2008r2?
|
83
|
+
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
|
84
|
+
require 'chef/win32/version'
|
85
|
+
win_version = Chef::ReservedNames::Win32::Version.new
|
86
|
+
#"Windows Server 2008 R2" => {:major => 6, :minor => 1
|
87
|
+
major = win_version.instance_variable_get("@major_version")
|
88
|
+
minor = win_version.instance_variable_get("@minor_version")
|
89
|
+
|
90
|
+
if major >= 6 && minor > 1
|
91
|
+
return true
|
92
|
+
end
|
93
|
+
|
94
|
+
return false
|
95
|
+
end
|
96
|
+
|
97
|
+
raise 'Calling this method on any system but Windows is unsupported'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
8
102
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixlibrary-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Carpenter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|