teapot 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74fb639fe5cc1f9596048d3a55255d8b9ed534114bb7ac4ce0a337274a93b7ec
4
- data.tar.gz: ee891bde08844f98b972f76a77ee6427996b5b05de39ac8a0f2ca3891310ee09
3
+ metadata.gz: decb98e7874aae571e257044efad1fc480cdb9f0e7ee1f9fc780d9a8d5995b7f
4
+ data.tar.gz: 63ec173747e3992349864d3342b1a6cf91c4d9a95a98237f2f26100a4e85e64c
5
5
  SHA512:
6
- metadata.gz: 5061e625c2c4ccdd3a698a829699a62170e0753d95bdeff9ab87790795aa960974fd0955cf4c68df815cbf5e201ac9492b6f9b11e4e2516d64385a34399bb479
7
- data.tar.gz: 331cd7ab35e021d1720a9426332583bd8141cf79f4a5e63da90bf8d19ef2583eb1afb6338e11242ad7da64241c2c8e265ff2be8fed1c28be9e49d3ac5da60762
6
+ metadata.gz: 1d0bf01d50bfe4bb0c87dae6ed592cda4507bb7fe59fc12020736ca0d3fb24b21d69d2e654029c7e5d6c1b273939fc0b1d9a92f2d22f03a115df388925080274
7
+ data.tar.gz: fe1e2de8b7b34b04d632058e5d8ad304696f7767772e50e3460280c97adfaaa7f5bec5854b6c74bb14c6b81eb84f39c8db072230d7d3e621e076c642086531d0
@@ -16,7 +16,7 @@ matrix:
16
16
  - rvm: 2.6
17
17
  os: osx
18
18
  before_install: brew install pkgconfig zlib curl openssl libssh2 libgit2
19
- env: RUGGED_USE_SYSTEM_LIBRARIES=y
19
+ # env: RUGGED_USE_SYSTEM_LIBRARIES=y
20
20
  - rvm: 2.6
21
21
  env: COVERAGE=BriefSummary,Coveralls
22
22
 
@@ -29,5 +29,5 @@ addons:
29
29
  - clang-4.0
30
30
  - libc++-dev
31
31
  - libc++abi-dev
32
- env:
33
- - CC=clang-4.0 CXX=clang++-4.0
32
+ # env:
33
+ # - CC=clang-4.0 CXX=clang++-4.0
data/bin/teapot CHANGED
@@ -20,40 +20,42 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
  # THE SOFTWARE.
22
22
 
23
- require 'teapot/command'
23
+ require_relative '../lib/teapot/command'
24
24
 
25
- options = Teapot::Command.parse(ARGV)
25
+ if command = Teapot::Command.parse(ARGV)
26
+ logger = command.logger
26
27
 
27
- begin
28
- options.invoke
29
- rescue Teapot::IncompatibleTeapotError => error
30
- $stderr.puts error.message.color(:red)
31
- $stderr.puts "Supported minimum version #{Teapot::MINIMUM_LOADER_VERSION.dump} to #{Teapot::LOADER_VERSION.dump}."
32
-
33
- exit 1
34
- rescue Build::Dependency::UnresolvedDependencyError => error
35
- $stderr.puts "Unresolved dependencies:"
28
+ begin
29
+ command.invoke
30
+ rescue Teapot::IncompatibleTeapotError => error
31
+ logger.error(command, error) do
32
+ "Supported minimum version #{Teapot::MINIMUM_LOADER_VERSION.dump} to #{Teapot::LOADER_VERSION.dump}."
33
+ end
34
+
35
+ exit 1
36
+ rescue Build::Dependency::UnresolvedDependencyError => error
37
+ logger.error(command, error) do |buffer|
38
+ buffer.puts "Unresolved dependencies:"
36
39
 
37
- error.chain.unresolved.each do |name, parent|
38
- $stderr.puts "#{parent} depends on #{name.inspect}".color(:red)
39
-
40
- conflicts = error.chain.conflicts[name]
41
-
42
- if conflicts
43
- conflicts.each do |conflict|
44
- $stderr.puts " - provided by #{conflict.name}".color(:red)
40
+ error.chain.unresolved.each do |name, parent|
41
+ buffer.puts "#{parent} depends on #{name.inspect}"
42
+
43
+ conflicts = error.chain.conflicts[name]
44
+
45
+ if conflicts
46
+ conflicts.each do |conflict|
47
+ buffer.puts " - provided by #{conflict.name}"
48
+ end
49
+ end
45
50
  end
51
+
52
+ buffer.puts "Cannot continue due to unresolved dependencies!".color(:red)
46
53
  end
54
+
55
+ exit 2
56
+ rescue StandardError => error
57
+ logger.error(command, error)
58
+
59
+ exit 3
47
60
  end
48
-
49
- $stderr.puts "Cannot continue due to unresolved dependencies!".color(:red)
50
-
51
- exit 2
52
- rescue StandardError => error
53
- $stderr.puts error.message.color(:red)
54
-
55
- # Could be nice to have some improved error reporting.
56
- $stderr.puts error.backtrace
57
-
58
- exit 3
59
61
  end
@@ -33,12 +33,9 @@ require_relative 'context'
33
33
  require_relative 'configuration'
34
34
  require_relative 'version'
35
35
 
36
- require 'uri'
37
- require 'rainbow'
38
- require 'rainbow/ext/string'
39
36
  require 'fileutils'
40
37
 
41
- require 'build/logger'
38
+ require 'console'
42
39
 
43
40
  module Teapot
44
41
  module Command
@@ -57,7 +54,7 @@ module Teapot
57
54
  option '-v/--version', "Print out the application version."
58
55
  end
59
56
 
60
- nested '<command>', {
57
+ nested :command, {
61
58
  "create" => Create,
62
59
  "clone" => Clone,
63
60
  "fetch" => Fetch,
@@ -81,15 +78,13 @@ module Teapot
81
78
  end
82
79
 
83
80
  def logger
84
- @logger ||= Logger.new($stderr).tap do |logger|
85
- logger.formatter = ::Build::CompactFormatter.new(verbose: verbose?)
86
-
81
+ @logger ||= Console::Logger.new(Console.logger, verbose: self.verbose?).tap do |logger|
87
82
  if verbose?
88
- logger.level = Logger::DEBUG
83
+ logger.debug!
89
84
  elsif quiet?
90
- logger.level = Logger::WARN
85
+ logger.warn!
91
86
  else
92
- logger.level = Logger::INFO
87
+ logger.info!
93
88
  end
94
89
  end
95
90
  end
@@ -102,15 +97,13 @@ module Teapot
102
97
  Context.new(root, configuration: configuration)
103
98
  end
104
99
 
105
- def invoke(program_name: File.basename($0))
100
+ def invoke
106
101
  if @options[:version]
107
102
  puts "teapot v#{Teapot::VERSION}"
108
- elsif @options[:help] or @command.nil?
109
- print_usage(program_name)
103
+ elsif @options[:help]
104
+ print_usage(output: $stdout)
110
105
  else
111
- track_time do
112
- @command.invoke(self)
113
- end
106
+ @command.invoke
114
107
  end
115
108
  end
116
109
  end
@@ -18,7 +18,7 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require 'samovar'
21
+ require_relative 'selection'
22
22
 
23
23
  require 'build/controller'
24
24
 
@@ -27,7 +27,7 @@ module Teapot
27
27
  class BuildFailedError < StandardError
28
28
  end
29
29
 
30
- class Build < Samovar::Command
30
+ class Build < Selection
31
31
  self.description = "Build the specified target."
32
32
 
33
33
  options do
@@ -38,7 +38,7 @@ module Teapot
38
38
  many :targets, "Build these targets, or use them to help the dependency resolution process."
39
39
  split :argv, "Arguments passed to child process(es) of build if any."
40
40
 
41
- def invoke(parent)
41
+ def invoke
42
42
  context = parent.context
43
43
 
44
44
  # The targets to build:
@@ -25,15 +25,15 @@ module Teapot
25
25
  class Clean < Samovar::Command
26
26
  self.description = "Delete everything in the teapot directory."
27
27
 
28
- def invoke(parent)
28
+ def invoke
29
29
  context = parent.context
30
30
  logger = parent.logger
31
31
  configuration = context.configuration
32
32
 
33
- logger.info "Removing #{configuration.platforms_path}...".color(:cyan)
34
- FileUtils.rm_rf configuration.platforms_path
33
+ logger.info "Removing #{configuration.build_path}..."
34
+ FileUtils.rm_rf configuration.build_path
35
35
 
36
- logger.info "Removing #{configuration.packages_path}...".color(:cyan)
36
+ logger.info "Removing #{configuration.packages_path}..."
37
37
  FileUtils.rm_rf configuration.packages_path
38
38
  end
39
39
  end
@@ -31,11 +31,9 @@ module Teapot
31
31
  class Clone < Samovar::Command
32
32
  self.description = "Clone a remote repository and fetch all dependencies."
33
33
 
34
- one :source, "The source repository to clone."
34
+ one :source, "The source repository to clone.", required: true
35
35
 
36
- def invoke(parent)
37
- raise ArgumentError, "source is required" unless @source
38
-
36
+ def invoke
39
37
  logger = parent.logger
40
38
 
41
39
  name = File.basename(::Build::URI[@source].path, ".git")
@@ -47,11 +45,11 @@ module Teapot
47
45
  raise ArgumentError.new("#{root} already exists!")
48
46
  end
49
47
 
50
- logger.info "Cloning #{@source} to #{root}...".color(:cyan)
48
+ logger.info "Cloning #{@source} to #{root}..."
51
49
  _repository = Rugged::Repository.clone_at(@source, root.to_s, credentials: self.method(:credentials))
52
50
 
53
51
  # Fetch the initial packages:
54
- Fetch[].invoke(nested)
52
+ Fetch[parent: nested].invoke
55
53
  end
56
54
 
57
55
  def credentials(url, username, types)
@@ -29,17 +29,14 @@ module Teapot
29
29
  class Create < Samovar::Command
30
30
  self.description = "Create a new teapot package using the specified repository."
31
31
 
32
- one :project_name, "The name of the new project in title-case, e.g. 'My Project'."
33
- one :source, "The source repository to use for fetching packages, e.g. https://github.com/kurocha."
34
- many :packages, "Any additional packages you'd like to include in the project."
32
+ one :name, "The name of the new project in title-case, e.g. 'My Project'.", required: true
33
+ one :source, "The source repository to use for fetching packages, e.g. https://github.com/kurocha.", required: true
34
+ many :packages, "Any packages you'd like to include in the project.", default: ["generate-project"]
35
35
 
36
- def invoke(parent)
37
- raise ArgumentError, "project_name is required" unless @project_name
38
- raise ArgumentError, "source is required" unless @source
39
-
36
+ def invoke
40
37
  logger = parent.logger
41
38
 
42
- nested = parent['--root', parent.options[:root] || project_name.gsub(/\s+/, '-').downcase]
39
+ nested = parent['--root', parent.options[:root] || name.gsub(/\s+/, '-').downcase]
43
40
  root = nested.root
44
41
 
45
42
  if root.exist?
@@ -51,11 +48,11 @@ module Teapot
51
48
 
52
49
  repository = Rugged::Repository.init_at(root.to_s)
53
50
 
54
- logger.info "Creating project named #{project_name} at path #{root}...".color(:cyan)
55
- generate_project(root, @project_name, @source, @packages)
51
+ logger.info "Creating project named #{name} at path #{root}..."
52
+ generate_project(root, @name, @source, @packages)
56
53
 
57
54
  # Fetch the initial packages:
58
- Fetch[].invoke(nested)
55
+ Fetch[parent: nested].invoke
59
56
 
60
57
  context = nested.context
61
58
  selection = context.select
@@ -63,10 +60,10 @@ module Teapot
63
60
 
64
61
  if target_names.any?
65
62
  # Generate the initial project files:
66
- Build[*target_names].invoke(nested)
63
+ Build[*target_names, parent: nested].invoke
67
64
 
68
65
  # Fetch any additional packages:
69
- Fetch[].invoke(nested)
66
+ Fetch[parent: nested].invoke
70
67
  end
71
68
 
72
69
  # Stage all files:
@@ -82,8 +79,8 @@ module Teapot
82
79
  )
83
80
  end
84
81
 
85
- def generate_project(root, project_name, source, packages)
86
- name = ::Build::Name.new(project_name)
82
+ def generate_project(root, name, source, packages)
83
+ name = ::Build::Name.new(name)
87
84
 
88
85
  # Otherwise the initial commit will try to include teapot/
89
86
  File.open(root + ".gitignore", "w") do |output|
@@ -18,8 +18,7 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require 'samovar'
22
-
21
+ require_relative 'selection'
23
22
  require 'rugged'
24
23
 
25
24
  module Teapot
@@ -48,18 +47,21 @@ module Teapot
48
47
 
49
48
  many :packages, "Only update the specified packages, or all packages if none specified."
50
49
 
51
- def invoke(parent)
52
- logger = parent.logger
53
- context = parent.context
54
-
50
+ def context
51
+ parent.context
52
+ end
53
+
54
+ def invoke
55
55
  selection = context.select
56
56
 
57
57
  packages = selection.configuration.packages
58
58
 
59
- if @packages.any?
60
- packages = packages.slice(@packages)
59
+ if specified_packages = self.packages
60
+ packages = packages.slice(specified_packages)
61
61
  end
62
62
 
63
+ logger = parent.logger
64
+
63
65
  # If no additional packages were resolved, we have reached a fixed point:
64
66
  while packages.any?
65
67
  packages.each do |package|
@@ -77,12 +79,15 @@ module Teapot
77
79
  end
78
80
 
79
81
  if selection.unresolved.count > 0
80
- logger.error "Could not fetch all packages!".color(:red)
81
- selection.unresolved.each do |package|
82
- logger.error "\t#{package}".color(:red)
82
+ logger.error(self) do |buffer|
83
+ buffer.puts "Could not fetch all packages!"
84
+
85
+ selection.unresolved.each do |package|
86
+ buffer.puts "\t#{package}"
87
+ end
83
88
  end
84
89
  else
85
- logger.info "Completed fetch successfully.".color(:green)
90
+ logger.info "Completed fetch successfully."
86
91
  end
87
92
  end
88
93
 
@@ -98,7 +103,7 @@ module Teapot
98
103
  end
99
104
 
100
105
  def link_local_package(context, configuration, package, logger)
101
- logger.info "Linking local #{package}...".color(:cyan)
106
+ logger.info "Linking local #{package}..." #.color(:cyan)
102
107
 
103
108
  local_path = context.root + package.options[:local]
104
109
 
@@ -119,7 +124,7 @@ module Teapot
119
124
  end
120
125
 
121
126
  def clone_or_pull_package(context, configuration, package, package_lock, logger)
122
- logger.info "Processing #{package}...".color(:cyan)
127
+ logger.info "Processing #{package}..." #.color(:cyan)
123
128
 
124
129
  # Where we are going to put the package:
125
130
  destination_path = package.path
@@ -140,7 +145,7 @@ module Teapot
140
145
  end
141
146
 
142
147
  if destination_path.exist?
143
- logger.info "Updating package at path #{destination_path}...".color(:cyan)
148
+ logger.info "Updating package at path #{destination_path}..." #.color(:cyan)
144
149
 
145
150
  repository = Rugged::Repository.new(destination_path.to_s)
146
151
 
@@ -165,7 +170,7 @@ module Teapot
165
170
  # Reset it to the requested commit if required:
166
171
  repository.reset(commit_id, :hard)
167
172
  else
168
- logger.info "Cloning package at path #{destination_path}...".color(:cyan)
173
+ logger.info "Cloning package at path #{destination_path}..." #.color(:cyan)
169
174
 
170
175
  external_url = package.external_url(context.root)
171
176
 
@@ -19,75 +19,77 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  require 'samovar'
22
+ require 'console/terminal'
23
+
24
+ require_relative 'selection'
22
25
 
23
26
  module Teapot
24
27
  module Command
25
- class List < Samovar::Command
28
+ class List < Selection
26
29
  self.description = "List provisions and dependencies of the specified package."
27
30
 
28
- many :packages, "Limit the listing to only these packages, or all packages if none specified."
29
-
30
- def only
31
- if @packages.any?
32
- Set.new(@packages)
31
+ def terminal(output = $stdout)
32
+ Console::Terminal.for(output).tap do |terminal|
33
+ terminal[:definition] = terminal.style(nil, nil, :bright)
34
+ terminal[:dependency] = terminal.style(:blue)
35
+ terminal[:provision] = terminal.style(:green)
36
+ terminal[:package] = terminal.style(:yellow)
37
+ terminal[:import] = terminal.style(:cyan)
38
+ terminal[:error] = terminal.style(:red)
33
39
  end
34
40
  end
35
41
 
36
- def invoke(parent)
37
- context = parent.context
42
+ def process(selection)
43
+ context = selection.context
44
+ terminal = self.terminal
38
45
 
39
- logger = parent.logger
40
-
41
- context.configuration.packages.each do |package|
42
- # The root package is the local package for this context:
43
- next unless only == nil or only.include?(package.name)
46
+ selection.resolved.each do |package|
47
+ terminal.puts "Package #{package.name} (from #{package.path}):"
44
48
 
45
- logger.info "Package #{package.name} (from #{package.path}):".bright
46
-
47
49
  begin
48
50
  script = context.load(package)
49
51
  definitions = script.defined
50
52
 
51
53
  definitions.each do |definition|
52
- logger.info "\t#{definition}"
54
+ terminal.puts "\t#{definition}", style: :definition
53
55
 
54
56
  definition.description.each_line do |line|
55
- logger.info "\t\t#{line.chomp}".color(:cyan)
57
+ terminal.puts "\t\t#{line.chomp}", style: :description
56
58
  end if definition.description
57
59
 
58
60
  case definition
59
61
  when Project
60
- logger.info "\t\t- Summary: #{definition.summary}" if definition.summary
61
- logger.info "\t\t- License: #{definition.license}" if definition.license
62
- logger.info "\t\t- Website: #{definition.website}" if definition.website
63
- logger.info "\t\t- Version: #{definition.version}" if definition.version
62
+ terminal.puts "\t\t- Summary: #{definition.summary}" if definition.summary
63
+ terminal.puts "\t\t- License: #{definition.license}" if definition.license
64
+ terminal.puts "\t\t- Website: #{definition.website}" if definition.website
65
+ terminal.puts "\t\t- Version: #{definition.version}" if definition.version
64
66
 
65
67
  definition.authors.each do |author|
66
- contact_text = [author.email, author.website].compact.collect{|text|" <#{text}>"}.join
67
- logger.info "\t\t- Author: #{author.name}" + contact_text
68
+ contact_text = [author.email, author.website].compact.collect{|text| " <#{text}>"}.join
69
+ terminal.puts "\t\t- Author: #{author.name}" + contact_text
68
70
  end
69
71
  when Target
70
72
  definition.dependencies.each do |dependency|
71
- logger.info "\t\t- #{dependency}".color(:red)
73
+ terminal.puts "\t\t- #{dependency}", style: :dependency
72
74
  end
73
75
 
74
76
  definition.provisions.each do |name, provision|
75
- logger.info "\t\t- #{provision}".color(:green)
77
+ terminal.puts "\t\t- #{provision}", style: :provision
76
78
  end
77
79
  when Configuration
78
80
  definition.packages.each do |package|
79
- logger.info "\t\t- #{package}".color(:green)
81
+ terminal.puts "\t\t- #{package}", style: :package
80
82
  end
81
83
 
82
84
  definition.imports.select(&:explicit).each do |import|
83
- logger.info "\t\t- import #{import.name}".color(:red)
85
+ terminal.puts "\t\t- import #{import.name}", style: :import
84
86
  end
85
87
  end
86
88
  end
87
- rescue NonexistantTeapotError => error
88
- logger.info "\t#{error.message}".color(:red)
89
+ rescue MissingTeapotError => error
90
+ terminal.puts "\t#{error.message}", style: :error
89
91
  rescue IncompatibleTeapotError => error
90
- logger.info "\t#{error.message}".color(:red)
92
+ terminal.puts "\t#{error.message}", style: :error
91
93
  end
92
94
  end
93
95
  end
@@ -0,0 +1,51 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'samovar'
22
+
23
+ module Teapot
24
+ module Command
25
+ class Selection < Samovar::Command
26
+ options
27
+
28
+ many :targets, "Only consider the specified targets, if any."
29
+
30
+ def targets
31
+ if @targets and @targets.any?
32
+ Set.new(@targets)
33
+ end
34
+ end
35
+
36
+ def selection(context)
37
+ if targets = self.targets
38
+ context.select(targets)
39
+ else
40
+ context.select(context.configuration[:build])
41
+ end
42
+ end
43
+
44
+ def invoke
45
+ context = parent.context
46
+
47
+ self.process(selection(parent.context))
48
+ end
49
+ end
50
+ end
51
+ end
@@ -18,30 +18,28 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require 'samovar'
21
+ require_relative 'selection'
22
22
  require 'rugged'
23
+ require 'console/terminal'
23
24
 
24
25
  module Teapot
25
26
  module Command
26
- class Status < Samovar::Command
27
+ class Status < Selection
27
28
  self.description = "List the git status of the specified package(s)."
28
29
 
29
- many :packages, "Limit the listing to only these packages, or all packages if none specified."
30
-
31
- def only
32
- if @packages.any?
33
- Set.new(@packages)
30
+ def terminal(output = $stdout)
31
+ Console::Terminal.for(output).tap do |terminal|
32
+ terminal[:worktree_new] = terminal.style(:green)
33
+ terminal[:worktree_modified] = terminal.style(:yellow)
34
+ terminal[:worktree_deleted] = terminal.style(:red)
34
35
  end
35
36
  end
36
37
 
37
- def invoke(parent)
38
- context = parent.context
39
- logger = parent.logger
38
+ def process(selection)
39
+ context = selection.context
40
+ terminal = self.terminal
40
41
 
41
- context.configuration.packages.each do |package|
42
- # The root package is the local package for this context:
43
- next unless only == nil or only.include?(package.name)
44
-
42
+ selection.resolved.each do |package|
45
43
  repository = Rugged::Repository.new(package.path.to_s)
46
44
 
47
45
  changes = {}
@@ -53,18 +51,10 @@ module Teapot
53
51
 
54
52
  next if changes.empty?
55
53
 
56
- logger.info "Package #{package.name} (from #{package.path}):".bright
54
+ terminal.puts "Package #{package.name} (from #{package.path}):"
57
55
 
58
- changes.each do |file, status|
59
- if status == [:worktree_new]
60
- logger.info "\t#{file}".color(:blue)
61
- elsif status == [:worktree_modified]
62
- logger.info "\t#{file}".color(:orange)
63
- elsif status == [:worktree_deleted]
64
- logger.info "\t#{file}".color(:red)
65
- else
66
- logger.info "\t#{file} #{status.inspect}"
67
- end
56
+ changes.each do |file, statuses|
57
+ terminal.puts "\t#{file} (#{statuses})", style: statuses.last
68
58
  end
69
59
  end
70
60
  end
@@ -18,12 +18,12 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require 'samovar'
21
+ require_relative 'selection'
22
22
  require 'graphviz'
23
23
 
24
24
  module Teapot
25
25
  module Command
26
- class Visualize < Samovar::Command
26
+ class Visualize < Selection
27
27
  self.description = "Generate a picture of the dependency graph."
28
28
 
29
29
  options do
@@ -31,8 +31,6 @@ module Teapot
31
31
  option '-d/--dependency-name <name>', "Show the partial chain for the given named dependency."
32
32
  end
33
33
 
34
- many :targets, "Visualize these targets, or use them to help the dependency resolution process."
35
-
36
34
  def dependency_names
37
35
  @targets || []
38
36
  end
@@ -41,15 +39,13 @@ module Teapot
41
39
  @options[:dependency_name]
42
40
  end
43
41
 
44
- def invoke(parent)
45
- context = parent.context
46
- selection = context.select(dependency_names)
42
+ def process(selection)
43
+ context = selection.context
47
44
  chain = selection.chain
48
45
 
49
46
  if dependency_name
50
47
  provider = selection.dependencies[dependency_name]
51
48
 
52
- # TODO The visualisation generated isn't quite right. It's introspecting too much from the packages and not reflecting #ordered and #provisions.
53
49
  chain = chain.partial(provider)
54
50
  end
55
51
 
@@ -58,7 +54,9 @@ module Teapot
58
54
  graph = visualization.generate(chain)
59
55
 
60
56
  if output_path = @options[:output_path]
61
- Graphviz::output(graph, :path => output_path)
57
+ Graphviz.output(graph, path: output_path, format: :svg)
58
+ else
59
+ $stdout.puts graph.to_dot
62
60
  end
63
61
 
64
62
  return graph
@@ -48,8 +48,8 @@ module Teapot
48
48
  @repository ||= Rugged::Repository.new(@root.to_s)
49
49
  end
50
50
 
51
- def select(names = [], configuration = @configuration)
52
- Select.new(self, configuration, names)
51
+ def select(names = nil, configuration = @configuration)
52
+ Select.new(self, configuration, names || [])
53
53
  end
54
54
 
55
55
  def substitutions
@@ -69,6 +69,9 @@ module Teapot
69
69
  # e.g. foo-bar, typically used for targets, executables
70
70
  substitutions['PROJECT_TARGET_NAME'] = name.target
71
71
 
72
+ # e.g. foo_bar, typically used for variables.
73
+ substitutions['PROJECT_VARIABLE_NAME'] = name.key
74
+
72
75
  substitutions['LICENSE'] = @project.license
73
76
  end
74
77
 
@@ -105,10 +108,10 @@ module Teapot
105
108
  def load_root_package(**options)
106
109
  # Load the root package:
107
110
  script = load(root_package)
108
-
111
+
109
112
  # Find the default configuration, if it exists:
110
113
  if configuration_name = options[:configuration]
111
- @configuration = @configurations[configuration_name]
114
+ @configuration = script.configurations[configuration_name]
112
115
  else
113
116
  @configuration = script.default_configuration
114
117
  end
@@ -47,7 +47,7 @@ module Teapot
47
47
  attr :version
48
48
  end
49
49
 
50
- class NonexistantTeapotError < StandardError
50
+ class MissingTeapotError < StandardError
51
51
  def initialize(path)
52
52
  super "Could not read file at #{path}!"
53
53
  end
@@ -67,6 +67,8 @@ module Teapot
67
67
  @defined = []
68
68
  @version = nil
69
69
 
70
+ @configurations = Build::Dependency::Set.new
71
+
70
72
  @default_project = nil
71
73
  @default_configuration = nil
72
74
 
@@ -78,6 +80,8 @@ module Teapot
78
80
  attr :defined
79
81
  attr :version
80
82
 
83
+ attr :configurations
84
+
81
85
  attr :default_project
82
86
  attr :default_configuration
83
87
 
@@ -119,6 +123,7 @@ module Teapot
119
123
 
120
124
  @default_configuration ||= configuration
121
125
  @defined << configuration
126
+ @configurations << configuration
122
127
  end
123
128
 
124
129
  # Checks the host patterns and executes the block if they match.
@@ -165,7 +170,7 @@ module Teapot
165
170
 
166
171
  # Load a teapot.rb file relative to the root of the @package.
167
172
  def load!(path = teapot_path)
168
- raise NonexistantTeapotError.new(path) unless File.exist?(path)
173
+ raise MissingTeapotError.new(path) unless File.exist?(path)
169
174
 
170
175
  script = Script.new(@context, @package)
171
176
 
@@ -47,11 +47,11 @@ module Teapot
47
47
  @targets = {}
48
48
  @configurations = {}
49
49
  @projects = {}
50
- @rules = Build::Rulebook.new
51
50
 
52
51
  @dependencies = []
53
52
  @selection = Set.new
54
- @unresolved = Set.new
53
+ @resolved = Build::Dependency::Set.new
54
+ @unresolved = Build::Dependency::Set.new
55
55
 
56
56
  load!(configuration, names)
57
57
 
@@ -69,11 +69,11 @@ module Teapot
69
69
 
70
70
  # All public configurations.
71
71
  attr :configurations
72
-
73
- attr :rules
74
72
 
75
73
  attr :dependencies
76
74
  attr :selection
75
+
76
+ attr :resolved
77
77
  attr :unresolved
78
78
 
79
79
  def chain
@@ -103,9 +103,6 @@ module Teapot
103
103
  when Project
104
104
  AlreadyDefinedError.check(definition, @projects)
105
105
  @projects[definition.name] = definition
106
- when Rule
107
- AlreadyDefinedError.check(definition, @rules)
108
- @rules << definition
109
106
  end
110
107
  end
111
108
 
@@ -117,7 +114,9 @@ module Teapot
117
114
  script.defined.each do |definition|
118
115
  append(definition)
119
116
  end
120
- rescue NonexistantTeapotError, IncompatibleTeapotError
117
+
118
+ @resolved << package
119
+ rescue MissingTeapotError, IncompatibleTeapotError
121
120
  # If the package doesn't exist or the teapot version is too old, it failed:
122
121
  @unresolved << package
123
122
  end
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Teapot
22
- VERSION = "3.0.0"
22
+ VERSION = "3.1.0"
23
23
  end
@@ -27,14 +27,32 @@ RSpec.describe Teapot::Context do
27
27
  it "should specify correct number of packages" do
28
28
  default_configuration = context.configuration
29
29
 
30
- expect(default_configuration.packages.count).to be == 13
30
+ expect(default_configuration.packages.count).to be == 0
31
31
  end
32
32
 
33
- it "should load teapot.rb file" do
33
+ it "should select configuration" do
34
+ expect(context.configuration.name).to be == 'development'
35
+ end
36
+
37
+ context "with specific configuration" do
38
+ let(:context) {Teapot::Context.new(root, configuration: 'context_spec')}
39
+
40
+ it "should select configuration" do
41
+ expect(context.configuration.name).to be == 'context_spec'
42
+ end
43
+
44
+ it "should specify correct number of packages" do
45
+ default_configuration = context.configuration
46
+
47
+ expect(default_configuration.packages.count).to be == 13
48
+ end
49
+ end
50
+
51
+ it "should load teapot script" do
34
52
  selection = context.select
35
53
 
36
54
  # There is one configuration:
37
- expect(selection.configurations.count).to be == 1
55
+ expect(selection.configurations.count).to be == 2
38
56
  expect(selection.targets.count).to be == 1
39
57
 
40
58
  # We didn't expect any of them to actually load...
@@ -3,9 +3,16 @@
3
3
  # This file is part of the "Teapot" project, and is released under the MIT license.
4
4
  #
5
5
 
6
- teapot_version "1.0.0"
6
+ teapot_version "3.0.0"
7
7
 
8
- define_configuration 'test' do |configuration|
8
+ define_target "context_spec" do |target|
9
+ end
10
+
11
+ define_configuration 'development' do |configuration|
12
+ configuration.import 'context_spec'
13
+ end
14
+
15
+ define_configuration 'context_spec' do |configuration|
9
16
  configuration.public!
10
17
 
11
18
  configuration[:source] = "../kurocha"
@@ -31,6 +38,3 @@ define_configuration 'test' do |configuration|
31
38
 
32
39
  configuration.require "opencv"
33
40
  end
34
-
35
- define_target "context_spec" do |target|
36
- end
@@ -24,19 +24,18 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.required_ruby_version = '>= 2.1.0'
26
26
 
27
- spec.add_dependency "rainbow", "~> 2.0"
28
-
29
27
  spec.add_dependency "graphviz", "~> 1.0"
30
-
31
28
  spec.add_dependency "rugged"
32
29
 
33
- spec.add_dependency "build", "~> 2.0"
30
+ spec.add_dependency "build", "~> 2.4"
31
+ spec.add_dependency "build-environment", "~> 1.10.0"
34
32
  spec.add_dependency "build-files", "~> 1.4"
35
33
  spec.add_dependency "build-dependency", "~> 1.4"
36
34
  spec.add_dependency "build-uri", "~> 1.0"
37
35
  spec.add_dependency "build-text", "~> 1.0"
38
36
 
39
- spec.add_dependency "samovar", "~> 1.7"
37
+ spec.add_dependency "console", "~> 1.0"
38
+ spec.add_dependency "samovar", "~> 2.0"
40
39
 
41
40
  spec.add_development_dependency "covered"
42
41
  spec.add_development_dependency "bundler"
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teapot
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-15 00:00:00.000000000 Z
11
+ date: 2019-04-28 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: '2.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '2.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: graphviz
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +44,28 @@ dependencies:
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: '2.0'
47
+ version: '2.4'
62
48
  type: :runtime
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: '2.0'
54
+ version: '2.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: build-environment
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.10.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.10.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: build-files
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +122,34 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: console
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: samovar
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: '1.7'
145
+ version: '2.0'
132
146
  type: :runtime
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '1.7'
152
+ version: '2.0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: covered
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -219,6 +233,7 @@ files:
219
233
  - lib/teapot/command/create.rb
220
234
  - lib/teapot/command/fetch.rb
221
235
  - lib/teapot/command/list.rb
236
+ - lib/teapot/command/selection.rb
222
237
  - lib/teapot/command/status.rb
223
238
  - lib/teapot/command/visualize.rb
224
239
  - lib/teapot/configuration.rb
@@ -267,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
267
282
  - !ruby/object:Gem::Version
268
283
  version: '0'
269
284
  requirements: []
270
- rubygems_version: 3.0.2
285
+ rubygems_version: 3.0.3
271
286
  signing_key:
272
287
  specification_version: 4
273
288
  summary: Teapot is a tool for managing complex cross-platform builds.