ddenv 0.1.0 → 0.1.1
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 +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