ddenv 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +4 -0
- data/README.md +35 -25
- data/ddenv.yaml +3 -0
- data/lib/ddenv/commands/up.rb +15 -8
- data/lib/ddenv/config.rb +2 -0
- data/lib/ddenv/goal.rb +32 -0
- data/lib/ddenv/goals/homebrew_package_installed.rb +6 -0
- data/lib/ddenv/goals/ruby_install_installed.rb +11 -0
- data/lib/ddenv/goals/ruby_installed.rb +49 -0
- data/lib/ddenv/goals/ruby_shadowenv_created.rb +73 -0
- data/lib/ddenv/goals/shadowenv_dir_created.rb +34 -0
- data/lib/ddenv/goals/shadowenv_dir_git_ignored.rb +22 -0
- data/lib/ddenv/goals/shadowenv_initialized.rb +30 -0
- data/lib/ddenv/goals/shadowenv_trusted.rb +28 -0
- data/lib/ddenv/version.rb +1 -1
- data/lib/ddenv.rb +8 -0
- metadata +23 -2
- data/dev.yml +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec082036626c59440016bd290efe318994ed5d11affb29c29c74a40fb7bf6f57
|
4
|
+
data.tar.gz: 4af215b869b270245f24b97ac688301e6f8b53fac521c4c1c11c15c750279e99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9eb69dfcc93bc53d2757483eff2f14469666b220487e4356353c37687d1b22c7ff7d58a3c5a308d4565e891d08721fafca7eabc45e9a70958a7af4aecc26792c
|
7
|
+
data.tar.gz: '08f42ffb6c4ab4acf25ef12253dbbe5e8c2c8d2b9031562e55f7993e94023143055dddb319e45b2880c646f5c53815352b1cdbb3a98aac455397bc8f049f5ac7'
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,39 +1,49 @@
|
|
1
|
-
#
|
1
|
+
# ddenv
|
2
2
|
|
3
|
-
|
3
|
+
**ddenv** (*Denis’ Developer Environment*) is a tool for maintaining a local
|
4
|
+
environment for development.
|
4
5
|
|
5
|
-
|
6
|
+
> [!CAUTION]
|
7
|
+
> This software is a pre-alpha work in progress. Do not use just yet.
|
6
8
|
|
7
|
-
##
|
9
|
+
## Requirements
|
8
10
|
|
9
|
-
|
11
|
+
- Homebrew
|
12
|
+
- fish shell
|
10
13
|
|
11
|
-
|
14
|
+
> [!NOTE]
|
15
|
+
> In the future, this will work for bash and zsh as well.
|
12
16
|
|
13
|
-
|
17
|
+
## Quick start
|
14
18
|
|
15
|
-
|
19
|
+
Install it: `brew install denisdefreyne/ddenv/ddenv`.
|
16
20
|
|
17
|
-
|
21
|
+
Next, create a `ddenv.yaml` file which contains the list of dependencies to manage:
|
18
22
|
|
19
|
-
|
23
|
+
```yaml
|
24
|
+
up:
|
25
|
+
- homebrew: overmind
|
26
|
+
- ruby: 3.3.0
|
27
|
+
```
|
20
28
|
|
21
|
-
|
29
|
+
Lastly, run `ddenv up`.
|
22
30
|
|
23
|
-
|
31
|
+
```
|
32
|
+
% ddenv up
|
33
|
+
[✔] Installing Homebrew package overmind ... done (previously achieved)
|
34
|
+
[✔] Installing Homebrew package ruby-install... done (previously achieved)
|
35
|
+
[✔] Installing Ruby v3.3.0 ... done (previously achieved)
|
36
|
+
[✔] Initializing Shadowenv ... done (previously achieved)
|
37
|
+
[✔] Creating .shadowenv.d ... done (previously achieved)
|
38
|
+
[✔] Adding .shadowenv.d to .gitignore ... done (previously achieved)
|
39
|
+
[✔] Trusting .shadowenv.d ... done (previously achieved)
|
40
|
+
[✔] Adding Ruby to shadowenv ... done (previously achieved)
|
41
|
+
%
|
42
|
+
```
|
24
43
|
|
25
|
-
|
44
|
+
Now your local developer environment is ready to be used.
|
26
45
|
|
27
|
-
|
46
|
+
## Goals
|
28
47
|
|
29
|
-
|
30
|
-
|
31
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ddenv. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/ddenv/blob/main/CODE_OF_CONDUCT.md).
|
32
|
-
|
33
|
-
## License
|
34
|
-
|
35
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
36
|
-
|
37
|
-
## Code of Conduct
|
38
|
-
|
39
|
-
Everyone interacting in the Ddenv project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/ddenv/blob/main/CODE_OF_CONDUCT.md).
|
48
|
+
- <code>homebrew: <var>PACKAGENAME</var></code> installs the Homebrew package with the given name.
|
49
|
+
- <code>ruby: <var>VERSION</var></code> installs the given version of Ruby.
|
data/ddenv.yaml
ADDED
data/lib/ddenv/commands/up.rb
CHANGED
@@ -4,19 +4,26 @@ module Ddenv
|
|
4
4
|
module Commands
|
5
5
|
class Up < Ddenv::Command
|
6
6
|
def call
|
7
|
-
config = Ddenv::Config.read_from_file("
|
7
|
+
config = Ddenv::Config.read_from_file("ddenv.yaml")
|
8
|
+
|
9
|
+
all_goals = config.goals.flat_map(&:with_pre_and_post_goals).uniq
|
10
|
+
|
11
|
+
max_message_size = all_goals.map { _1.message.size }.max
|
12
|
+
|
13
|
+
all_goals.each do |goal|
|
14
|
+
spinner = TTY::Spinner.new("[:spinner] :message... :title")
|
15
|
+
spinner.update(message: format("%-#{max_message_size}s", goal.message))
|
16
|
+
spinner.update(title: "checking")
|
17
|
+
spinner.auto_spin
|
8
18
|
|
9
|
-
config.goals.each do |goal|
|
10
|
-
puts goal.message
|
11
|
-
puts " Checking..."
|
12
19
|
if goal.achieved?
|
13
|
-
|
20
|
+
spinner.update(title: "done (previously achieved)")
|
14
21
|
else
|
15
|
-
|
22
|
+
spinner.update(title: "working...")
|
16
23
|
goal.achieve
|
17
|
-
|
24
|
+
spinner.update(title: "done (newly achieved)")
|
18
25
|
end
|
19
|
-
|
26
|
+
spinner.success
|
20
27
|
end
|
21
28
|
end
|
22
29
|
end
|
data/lib/ddenv/config.rb
CHANGED
data/lib/ddenv/goal.rb
CHANGED
@@ -15,5 +15,37 @@ module Ddenv
|
|
15
15
|
def achieve
|
16
16
|
raise SubclassResponsibilityError.new(self.class, __method__)
|
17
17
|
end
|
18
|
+
|
19
|
+
def pre_goals
|
20
|
+
[]
|
21
|
+
end
|
22
|
+
|
23
|
+
def post_goals
|
24
|
+
[]
|
25
|
+
end
|
26
|
+
|
27
|
+
def with_pre_and_post_goals
|
28
|
+
[
|
29
|
+
*pre_goals.flat_map(&:with_pre_and_post_goals),
|
30
|
+
self,
|
31
|
+
*post_goals.flat_map(&:with_pre_and_post_goals)
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
def props
|
36
|
+
[]
|
37
|
+
end
|
38
|
+
|
39
|
+
def ==(other)
|
40
|
+
self.class == other.class && props == other.props
|
41
|
+
end
|
42
|
+
|
43
|
+
def eql?(other)
|
44
|
+
self == other
|
45
|
+
end
|
46
|
+
|
47
|
+
def hash
|
48
|
+
[self.class, props].hash
|
49
|
+
end
|
18
50
|
end
|
19
51
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module Ddenv
|
4
4
|
module Goals
|
5
5
|
class HomebrewPackageInstalled < Goal
|
6
|
+
attr_reader :package_name
|
7
|
+
|
6
8
|
def initialize(package_name)
|
7
9
|
super()
|
8
10
|
@package_name = package_name
|
@@ -21,6 +23,10 @@ module Ddenv
|
|
21
23
|
cmd = TTY::Command.new(printer: :null)
|
22
24
|
cmd.run("brew", "install", @package_name)
|
23
25
|
end
|
26
|
+
|
27
|
+
def props
|
28
|
+
[@package_name]
|
29
|
+
end
|
24
30
|
end
|
25
31
|
end
|
26
32
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ddenv
|
4
|
+
module Goals
|
5
|
+
class RubyInstalled < Goal
|
6
|
+
def initialize(ruby_version)
|
7
|
+
super()
|
8
|
+
@ruby_version = ruby_version
|
9
|
+
end
|
10
|
+
|
11
|
+
def message
|
12
|
+
"Installing Ruby v#{@ruby_version}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def achieved?
|
16
|
+
pathname = Pathname.new(Dir.home) / ".rubies" / "ruby-#{@ruby_version}"
|
17
|
+
pathname.directory?
|
18
|
+
end
|
19
|
+
|
20
|
+
def achieve
|
21
|
+
# TODO: use :pretty when passing --verbose
|
22
|
+
cmd = TTY::Command.new(printer: :null)
|
23
|
+
cmd.run("ruby-install", "--cleanup", @ruby_version)
|
24
|
+
end
|
25
|
+
|
26
|
+
def pre_goals
|
27
|
+
[
|
28
|
+
RubyInstallInstalled.new
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
def post_goals
|
33
|
+
[
|
34
|
+
RubyShadowenvCreated.new(ruby_pathname.to_s, @ruby_version)
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
def props
|
39
|
+
[@ruby_version]
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def ruby_pathname
|
45
|
+
@_ruby_pathname ||= Pathname.new(Dir.home) / ".rubies" / "ruby-#{@ruby_version}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ddenv
|
4
|
+
module Goals
|
5
|
+
class RubyShadowenvCreated < Goal
|
6
|
+
PATH = ".shadowenv.d/10_ruby.lisp"
|
7
|
+
|
8
|
+
def initialize(ruby_version, ruby_path)
|
9
|
+
super()
|
10
|
+
@ruby_version = ruby_version
|
11
|
+
@ruby_path = ruby_path
|
12
|
+
end
|
13
|
+
|
14
|
+
def message
|
15
|
+
"Adding Ruby to shadowenv"
|
16
|
+
end
|
17
|
+
|
18
|
+
def achieved?
|
19
|
+
File.file?(PATH) && File.read(PATH) == shadowenv_contents
|
20
|
+
end
|
21
|
+
|
22
|
+
def achieve
|
23
|
+
File.write(PATH, shadowenv_contents)
|
24
|
+
|
25
|
+
# TODO: use :pretty when passing --verbose
|
26
|
+
cmd = TTY::Command.new(printer: :null)
|
27
|
+
cmd.run("shadowenv", "trust")
|
28
|
+
end
|
29
|
+
|
30
|
+
def pre_goals
|
31
|
+
[
|
32
|
+
Ddenv::Goals::ShadowenvDirCreated.new
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def shadowenv_contents
|
39
|
+
<<~CONTENTS
|
40
|
+
(provide "ruby" "#{@ruby_version}")
|
41
|
+
|
42
|
+
(when-let ((ruby-root (env/get "RUBY_ROOT")))
|
43
|
+
(env/remove-from-pathlist "PATH" (path-concat ruby-root "bin"))
|
44
|
+
(when-let ((gem-root (env/get "GEM_ROOT")))
|
45
|
+
(env/remove-from-pathlist "PATH" (path-concat gem-root "bin")))
|
46
|
+
(when-let ((gem-home (env/get "GEM_HOME")))
|
47
|
+
(env/remove-from-pathlist "PATH" (path-concat gem-home "bin"))))
|
48
|
+
|
49
|
+
(env/set "GEM_PATH" ())
|
50
|
+
(env/set "GEM_HOME" ())
|
51
|
+
(env/set "RUBYOPT" ())
|
52
|
+
|
53
|
+
(env/set "RUBY_ROOT" "#{@ruby_path}")
|
54
|
+
(env/prepend-to-pathlist "PATH" "#{@ruby_path}/bin")
|
55
|
+
(env/set "RUBY_ENGINE" "ruby")
|
56
|
+
(env/set "RUBY_VERSION" "#{@ruby_version}")
|
57
|
+
(env/set "GEM_ROOT" "#{@ruby_path}/lib/ruby/gems/#{@ruby_version}")
|
58
|
+
|
59
|
+
(when-let ((gem-root (env/get "GEM_ROOT")))
|
60
|
+
(env/prepend-to-pathlist "GEM_PATH" gem-root)
|
61
|
+
(env/prepend-to-pathlist "PATH" (path-concat gem-root "bin")))
|
62
|
+
|
63
|
+
(let ((gem-home
|
64
|
+
(path-concat (env/get "HOME") ".gem" (env/get "RUBY_ENGINE") (env/get "RUBY_VERSION"))))
|
65
|
+
(do
|
66
|
+
(env/set "GEM_HOME" gem-home)
|
67
|
+
(env/prepend-to-pathlist "GEM_PATH" gem-home)
|
68
|
+
(env/prepend-to-pathlist "PATH" (path-concat gem-home "bin"))))
|
69
|
+
CONTENTS
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ddenv
|
4
|
+
module Goals
|
5
|
+
class ShadowenvDirCreated < Goal
|
6
|
+
PATH = ".shadowenv.d"
|
7
|
+
|
8
|
+
def message
|
9
|
+
"Creating .shadowenv.d"
|
10
|
+
end
|
11
|
+
|
12
|
+
def achieved?
|
13
|
+
Pathname.new(PATH).directory?
|
14
|
+
end
|
15
|
+
|
16
|
+
def achieve
|
17
|
+
FileUtils.mkdir_p(PATH)
|
18
|
+
end
|
19
|
+
|
20
|
+
def pre_goals
|
21
|
+
[
|
22
|
+
Ddenv::Goals::ShadowenvInitialized.new
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
def post_goals
|
27
|
+
[
|
28
|
+
Ddenv::Goals::ShadowenvDirGitIgnored.new,
|
29
|
+
Ddenv::Goals::ShadowenvTrusted.new
|
30
|
+
]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ddenv
|
4
|
+
module Goals
|
5
|
+
class ShadowenvDirGitIgnored < Goal
|
6
|
+
PATH = ".shadowenv.d/.gitignore"
|
7
|
+
CONTENTS = "*\n"
|
8
|
+
|
9
|
+
def message
|
10
|
+
"Adding .shadowenv.d to .gitignore"
|
11
|
+
end
|
12
|
+
|
13
|
+
def achieved?
|
14
|
+
File.file?(PATH) && File.read(PATH) == CONTENTS
|
15
|
+
end
|
16
|
+
|
17
|
+
def achieve
|
18
|
+
File.write(PATH, CONTENTS)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ddenv
|
4
|
+
module Goals
|
5
|
+
class ShadowenvInitialized < Goal
|
6
|
+
FISH_LINE = "shadowenv init fish | source"
|
7
|
+
|
8
|
+
def message
|
9
|
+
"Initializing Shadowenv"
|
10
|
+
end
|
11
|
+
|
12
|
+
# TODO: support bash and zsh
|
13
|
+
|
14
|
+
def achieved?
|
15
|
+
fish_config = File.read(fish_config_path)
|
16
|
+
fish_config.lines.any? { _1.chomp == FISH_LINE }
|
17
|
+
end
|
18
|
+
|
19
|
+
def achieve
|
20
|
+
File.write(fish_config_path, "\n\n#{FISH_LINE}", mode: "a+")
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def fish_config_path
|
26
|
+
@_fish_config_path ||= File.expand_path("~/.config/fish/config.fish")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ddenv
|
4
|
+
module Goals
|
5
|
+
class ShadowenvTrusted < Goal
|
6
|
+
def message
|
7
|
+
"Trusting .shadowenv.d"
|
8
|
+
end
|
9
|
+
|
10
|
+
def achieved?
|
11
|
+
# TODO: use :pretty when passing --verbose
|
12
|
+
cmd = TTY::Command.new(printer: :null)
|
13
|
+
begin
|
14
|
+
cmd.run("shadowenv", "exec", "--", "ls")
|
15
|
+
rescue StandardError
|
16
|
+
return false
|
17
|
+
end
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def achieve
|
22
|
+
# TODO: use :pretty when passing --verbose
|
23
|
+
cmd = TTY::Command.new(printer: :null)
|
24
|
+
cmd.run("shadowenv", "trust")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/ddenv/version.rb
CHANGED
data/lib/ddenv.rb
CHANGED
@@ -4,6 +4,7 @@ require "json"
|
|
4
4
|
require "yaml"
|
5
5
|
|
6
6
|
require "tty-command"
|
7
|
+
require "tty-spinner"
|
7
8
|
|
8
9
|
require_relative "ddenv/cli"
|
9
10
|
require_relative "ddenv/command"
|
@@ -17,3 +18,10 @@ require_relative "ddenv/commands/help"
|
|
17
18
|
require_relative "ddenv/commands/up"
|
18
19
|
|
19
20
|
require_relative "ddenv/goals/homebrew_package_installed"
|
21
|
+
require_relative "ddenv/goals/ruby_install_installed"
|
22
|
+
require_relative "ddenv/goals/ruby_installed"
|
23
|
+
require_relative "ddenv/goals/ruby_shadowenv_created"
|
24
|
+
require_relative "ddenv/goals/shadowenv_initialized"
|
25
|
+
require_relative "ddenv/goals/shadowenv_dir_created"
|
26
|
+
require_relative "ddenv/goals/shadowenv_dir_git_ignored"
|
27
|
+
require_relative "ddenv/goals/shadowenv_trusted"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ddenv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: tty-spinner
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
27
41
|
description: Creates and maintains an environment for local development, including
|
28
42
|
Ruby and Node versions.
|
29
43
|
email:
|
@@ -40,7 +54,7 @@ files:
|
|
40
54
|
- LICENSE.txt
|
41
55
|
- README.md
|
42
56
|
- Rakefile
|
43
|
-
-
|
57
|
+
- ddenv.yaml
|
44
58
|
- exe/ddenv
|
45
59
|
- lib/ddenv.rb
|
46
60
|
- lib/ddenv/cli.rb
|
@@ -50,6 +64,13 @@ files:
|
|
50
64
|
- lib/ddenv/config.rb
|
51
65
|
- lib/ddenv/goal.rb
|
52
66
|
- lib/ddenv/goals/homebrew_package_installed.rb
|
67
|
+
- lib/ddenv/goals/ruby_install_installed.rb
|
68
|
+
- lib/ddenv/goals/ruby_installed.rb
|
69
|
+
- lib/ddenv/goals/ruby_shadowenv_created.rb
|
70
|
+
- lib/ddenv/goals/shadowenv_dir_created.rb
|
71
|
+
- lib/ddenv/goals/shadowenv_dir_git_ignored.rb
|
72
|
+
- lib/ddenv/goals/shadowenv_initialized.rb
|
73
|
+
- lib/ddenv/goals/shadowenv_trusted.rb
|
53
74
|
- lib/ddenv/homebrew.rb
|
54
75
|
- lib/ddenv/subclass_responsibility_error.rb
|
55
76
|
- lib/ddenv/version.rb
|
data/dev.yml
DELETED