teapot 3.0.0 → 3.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 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.