umwelt 0.1.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 +7 -0
- data/.circleci/config.yml +46 -0
- data/.gitignore +8 -0
- data/.rubocop.yml +28 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +79 -0
- data/LICENSE.txt +21 -0
- data/README.md +75 -0
- data/Rakefile +12 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bin/umwelt +7 -0
- data/lib/umwelt.rb +23 -0
- data/lib/umwelt/abstract.rb +7 -0
- data/lib/umwelt/abstract/file.rb +7 -0
- data/lib/umwelt/abstract/file/restore.rb +48 -0
- data/lib/umwelt/abstract/file/store.rb +44 -0
- data/lib/umwelt/abstract/mapper.rb +17 -0
- data/lib/umwelt/cli.rb +6 -0
- data/lib/umwelt/cli/commands.rb +15 -0
- data/lib/umwelt/cli/commands/clone.rb +16 -0
- data/lib/umwelt/cli/commands/convey.rb +57 -0
- data/lib/umwelt/cli/commands/pull.rb +11 -0
- data/lib/umwelt/cli/commands/version.rb +9 -0
- data/lib/umwelt/command.rb +6 -0
- data/lib/umwelt/command/convey.rb +84 -0
- data/lib/umwelt/episode.rb +7 -0
- data/lib/umwelt/episode/file.rb +7 -0
- data/lib/umwelt/episode/file/restore.rb +22 -0
- data/lib/umwelt/episode/file/store.rb +15 -0
- data/lib/umwelt/episode/mapper.rb +33 -0
- data/lib/umwelt/fragment.rb +6 -0
- data/lib/umwelt/fragment/mapper.rb +11 -0
- data/lib/umwelt/history.rb +10 -0
- data/lib/umwelt/history/aggregate.rb +49 -0
- data/lib/umwelt/history/file.rb +7 -0
- data/lib/umwelt/history/file/restore.rb +22 -0
- data/lib/umwelt/history/file/store.rb +15 -0
- data/lib/umwelt/history/follow.rb +32 -0
- data/lib/umwelt/history/mapper.rb +33 -0
- data/lib/umwelt/history/trace.rb +51 -0
- data/lib/umwelt/node.rb +46 -0
- data/lib/umwelt/node/build.rb +31 -0
- data/lib/umwelt/node/root.rb +6 -0
- data/lib/umwelt/node/space.rb +6 -0
- data/lib/umwelt/phase.rb +6 -0
- data/lib/umwelt/phase/mapper.rb +18 -0
- data/lib/umwelt/project.rb +7 -0
- data/lib/umwelt/project/file.rb +7 -0
- data/lib/umwelt/project/file/restore.rb +22 -0
- data/lib/umwelt/project/file/store.rb +15 -0
- data/lib/umwelt/project/mapper.rb +11 -0
- data/lib/umwelt/semantic.rb +57 -0
- data/lib/umwelt/semantic/plain.rb +12 -0
- data/lib/umwelt/semantic/plain/root.rb +13 -0
- data/lib/umwelt/semantic/plain/space.rb +13 -0
- data/lib/umwelt/structs/episode.rb +9 -0
- data/lib/umwelt/structs/fragment.rb +13 -0
- data/lib/umwelt/structs/history.rb +3 -0
- data/lib/umwelt/structs/node.rb +13 -0
- data/lib/umwelt/structs/phase.rb +13 -0
- data/lib/umwelt/structs/project.rb +10 -0
- data/lib/umwelt/structs/trunk.rb +8 -0
- data/lib/umwelt/tree.rb +8 -0
- data/lib/umwelt/tree/fill.rb +35 -0
- data/lib/umwelt/tree/imprint.rb +53 -0
- data/lib/umwelt/tree/trunk.rb +27 -0
- data/lib/umwelt/version.rb +5 -0
- data/umwelt.gemspec +56 -0
- metadata +248 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hanami/interactor'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Umwelt::Abstract::File
|
7
|
+
class Restore
|
8
|
+
include Hanami::Interactor
|
9
|
+
|
10
|
+
expose :struct
|
11
|
+
|
12
|
+
def initialize(path: '.umwelt',
|
13
|
+
mapper: Struct)
|
14
|
+
@path = path
|
15
|
+
@mapper = mapper
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def read(path)
|
21
|
+
path.read
|
22
|
+
rescue Errno::ENOENT
|
23
|
+
error! "Failed reading #{path}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse(str)
|
27
|
+
JSON.parse(str, symbolize_names: true)
|
28
|
+
rescue JSON::ParserError
|
29
|
+
error! "Failed JSON parsing #{self.class.name}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def struct(struct_hash)
|
33
|
+
clean @mapper.new.call(struct_hash)
|
34
|
+
end
|
35
|
+
|
36
|
+
def clean(result)
|
37
|
+
if result.success?
|
38
|
+
result.struct
|
39
|
+
else
|
40
|
+
error! result.errors
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def umwelt_root_path
|
45
|
+
Pathname.pwd / @path
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hanami/interactor'
|
4
|
+
require 'json'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'pathname'
|
7
|
+
|
8
|
+
module Umwelt::Abstract::File
|
9
|
+
class Store
|
10
|
+
extend Forwardable
|
11
|
+
include Hanami::Interactor
|
12
|
+
def_delegators FileUtils, :mkpath
|
13
|
+
|
14
|
+
def initialize(path: '.umwelt')
|
15
|
+
@path = path
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def serialize(struct)
|
21
|
+
JSON.pretty_generate struct
|
22
|
+
end
|
23
|
+
|
24
|
+
def destruct(obj)
|
25
|
+
obj.is_a?(Struct) ? destruct_members(obj.to_h) : obj
|
26
|
+
end
|
27
|
+
|
28
|
+
def destruct_members(hash)
|
29
|
+
hash.transform_values do |value|
|
30
|
+
if value.is_a?(Array)
|
31
|
+
value.map { |member| destruct(member) }
|
32
|
+
elsif value.is_a? Time
|
33
|
+
value.to_s
|
34
|
+
else
|
35
|
+
destruct(value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def umwelt_root_path
|
41
|
+
Pathname.pwd / @path
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hanami/interactor'
|
4
|
+
# require_relative './structs/phase'
|
5
|
+
# require_relative './structs/fragment'
|
6
|
+
|
7
|
+
class Umwelt::Abstract::Mapper
|
8
|
+
include Hanami::Interactor
|
9
|
+
|
10
|
+
expose :struct
|
11
|
+
|
12
|
+
def fill(struct, data)
|
13
|
+
struct.new(data)
|
14
|
+
rescue ArgumentError => e
|
15
|
+
error! [self.class.name, e.message, data]
|
16
|
+
end
|
17
|
+
end
|
data/lib/umwelt/cli.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Umwelt::CLI::Commands
|
4
|
+
require_relative './commands/convey'
|
5
|
+
require_relative './commands/clone'
|
6
|
+
require_relative './commands/pull'
|
7
|
+
require_relative './commands/version'
|
8
|
+
|
9
|
+
extend Hanami::CLI::Registry
|
10
|
+
|
11
|
+
register 'convey', Convey
|
12
|
+
register 'clone', Clone
|
13
|
+
register 'pull', Pull
|
14
|
+
register 'version', Version
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Umwelt::CLI
|
4
|
+
class Commands::Clone < Hanami::CLI::Command
|
5
|
+
desc 'Clone project from remote Umwelt'
|
6
|
+
|
7
|
+
argument :project,
|
8
|
+
type: :string, required: true,
|
9
|
+
desc: 'provide project as USERNAME/PROJECTNAME'
|
10
|
+
|
11
|
+
def call(project:)
|
12
|
+
puts "Cloning project: <#{project}>"
|
13
|
+
# Generator::Element.new(element).create
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Umwelt::CLI::Commands
|
4
|
+
class Convey < Hanami::CLI::Command
|
5
|
+
extend Forwardable
|
6
|
+
def_delegators Hanami::Utils::String, :classify
|
7
|
+
|
8
|
+
desc 'Convey Phase in Semantic from local Umwelt'
|
9
|
+
|
10
|
+
argument :phase,
|
11
|
+
type: :integer,
|
12
|
+
required: true,
|
13
|
+
desc: 'provide PHASE_ID to imprint'
|
14
|
+
|
15
|
+
argument :semantic,
|
16
|
+
type: :string,
|
17
|
+
default: 'plain',
|
18
|
+
values: %w[plain],
|
19
|
+
required: true,
|
20
|
+
desc: 'provide SEMANTIC to imprint'
|
21
|
+
|
22
|
+
option :source,
|
23
|
+
type: :string,
|
24
|
+
default: '.umwelt',
|
25
|
+
desc: 'provide folder where source stored'
|
26
|
+
|
27
|
+
option :target,
|
28
|
+
type: :string,
|
29
|
+
default: 'umwelt',
|
30
|
+
desc: 'provide folder for imprint'
|
31
|
+
|
32
|
+
def call(phase:, semantic:, **options)
|
33
|
+
puts "Buildung phase: #{phase} with semantic #{semantic}..."
|
34
|
+
|
35
|
+
if phase.to_i.zero?
|
36
|
+
puts 'Error: Phase must be an integer'
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
@convey = Umwelt::Command::Convey.new.call(
|
41
|
+
phase_id: phase.to_i,
|
42
|
+
semantic: classify(semantic).to_sym,
|
43
|
+
source: Pathname.new(options.fetch(:source)),
|
44
|
+
target: Pathname.new(options.fetch(:target))
|
45
|
+
)
|
46
|
+
|
47
|
+
if @convey.success?
|
48
|
+
@convey.result.each_pair do |key, value|
|
49
|
+
puts "#{key} => (#{value})"
|
50
|
+
end
|
51
|
+
puts "#{@convey.result.keys.count} files written succesfully"
|
52
|
+
else
|
53
|
+
@convey.errors.each { |e| puts "Error: #{e}" }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Umwelt::Command
|
4
|
+
class Convey
|
5
|
+
include Hanami::Interactor
|
6
|
+
# TODO: change to dry-rb transaction here
|
7
|
+
|
8
|
+
expose :result
|
9
|
+
|
10
|
+
def call(phase_id:, semantic:, source:, target:)
|
11
|
+
@result = imprint(
|
12
|
+
tree(source, phase_id), target, semantic
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def tree(source, phase_id)
|
19
|
+
tree_fill(
|
20
|
+
aggregate_history(
|
21
|
+
follow_history(
|
22
|
+
trace_history(
|
23
|
+
restore_history(source),
|
24
|
+
phase_id
|
25
|
+
), source
|
26
|
+
)
|
27
|
+
)
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def imprint(tree, target, semantic)
|
32
|
+
result = Umwelt::Tree::Imprint.new(tree, location: target).call(semantic)
|
33
|
+
if result.success?
|
34
|
+
result.written_paths
|
35
|
+
else
|
36
|
+
error! result.errors
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def tree_fill(fragments)
|
41
|
+
Umwelt::Tree::Fill.new.call(fragments)
|
42
|
+
end
|
43
|
+
|
44
|
+
def aggregate_history(episodes)
|
45
|
+
result = Umwelt::History::Aggregate.new.call(episodes)
|
46
|
+
if result.success?
|
47
|
+
result.fragments
|
48
|
+
else
|
49
|
+
error! result.errors
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def follow_history(continuity, source)
|
54
|
+
result = Umwelt::History::Follow
|
55
|
+
.new(path: source)
|
56
|
+
.call(continuity)
|
57
|
+
if result.success?
|
58
|
+
result.episodes
|
59
|
+
else
|
60
|
+
error! result.errors
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def trace_history(history, phase_id)
|
65
|
+
result = Umwelt::History::Trace.new.call(history, phase_id)
|
66
|
+
if result.success?
|
67
|
+
result.continuity
|
68
|
+
else
|
69
|
+
error! result.errors
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def restore_history(source)
|
74
|
+
restored = Umwelt::History::File::Restore
|
75
|
+
.new(path: source)
|
76
|
+
.call
|
77
|
+
if restored.success?
|
78
|
+
restored.struct
|
79
|
+
else
|
80
|
+
error! "Cannot restore history of #{phase_id}: #{restored.errors}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../structs/episode'
|
4
|
+
|
5
|
+
module Umwelt::Episode::File
|
6
|
+
class Restore < Umwelt::Abstract::File::Restore
|
7
|
+
def initialize(
|
8
|
+
path: '.umwelt',
|
9
|
+
mapper: Umwelt::Episode::Mapper
|
10
|
+
)
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(phase_id)
|
15
|
+
@struct = struct parse read full_path phase_id
|
16
|
+
end
|
17
|
+
|
18
|
+
def full_path(phase_id)
|
19
|
+
umwelt_root_path / "episodes/#{phase_id}.json"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Umwelt::Episode::File
|
4
|
+
class Store < Umwelt::Abstract::File::Store
|
5
|
+
def call(id, struct)
|
6
|
+
mkpath full_path(id).dirname
|
7
|
+
|
8
|
+
full_path(id).write serialize(destruct(struct))
|
9
|
+
end
|
10
|
+
|
11
|
+
def full_path(id)
|
12
|
+
umwelt_root_path / "episodes/#{id}.json"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../structs/phase'
|
4
|
+
require_relative '../structs/fragment'
|
5
|
+
|
6
|
+
module Umwelt::Episode
|
7
|
+
class Mapper < Umwelt::Abstract::Mapper
|
8
|
+
def call(
|
9
|
+
data = {
|
10
|
+
phase: {},
|
11
|
+
engaged: [],
|
12
|
+
forgotten: []
|
13
|
+
}
|
14
|
+
)
|
15
|
+
|
16
|
+
@struct = Struct::Episode.new(
|
17
|
+
phase: phase(data[:phase]),
|
18
|
+
engaged: fragments(data[:engaged]),
|
19
|
+
forgotten: data[:forgotten]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def fragments(array)
|
26
|
+
array.map { |data| fill(Struct::Fragment, data) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def phase(data)
|
30
|
+
fill(Struct::Phase, data)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|