teapot 3.6.0 → 3.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a21ff20aa745863cf4e91ffa997690d86c4de3a3f0fd3355f63b74ff432000ea
4
- data.tar.gz: 53011f5117cc8c25437dbf2a5ea762298107761f58cc35c9df8d2030f5dc7777
3
+ metadata.gz: 742147841aebb1df987a75d2ffefcb764d9d42f6faf5492bdd273c62a8e195ce
4
+ data.tar.gz: 11c7a76cfe57be54d9a5864b2e0d7eb821ab780c4128df78ca09e555599c7dca
5
5
  SHA512:
6
- metadata.gz: d3bb453fc48543c8ad03c681c2945c421cd4e9828ff5658961d3308e4eae6a354e0ba678fd394d7554e2f6dbdc6a70f32e02ca6b58210c8b1fcaaeb3f4658c2d
7
- data.tar.gz: 0c7b89c76b6f1e045071a9137d3b387003ed9b4bf6e659b80f64a417f1e7558fe2851fa7f47b0bbc05ae13868ae77389d10f281c7ba0595ee640f2edfedf0374
6
+ metadata.gz: '001587e6eca1be37e6697b2b603208afe8d5685b14a8364603325d9aa24af9c2af3a12effec6bf0f9513731cffd05d7ec76125333d3fa3fd9a76e9cf66467749'
7
+ data.tar.gz: 503bd6ed1aba820ce830b5e856468b9d990b179e2f2da32c7d1985a314f1e6ff48a54d8a0883a1352b7dd30380e51c951e2fdbf234d716926033700208f88b3a
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,139 @@
1
+ # Getting Started
2
+
3
+ This guide explains how to use `teapot` to manage cross-platform project dependencies and build systems.
4
+
5
+ ## Installation
6
+
7
+ Ensure that you already have a working install of Ruby 2.0.0+ and run the following to install `teapot`:
8
+
9
+ ~~~ bash
10
+ $ gem install teapot
11
+ ~~~
12
+
13
+ ## Create Project
14
+
15
+ Firstly, create your project by running:
16
+
17
+ ~~~ bash
18
+ $ teapot create "My Project" https://github.com/kurocha generate-project
19
+ $ cd my-project
20
+ ~~~
21
+
22
+ You will be asked to merge the project file. At present, merge tools are not very good and thus you may need to take a moment to review the changes. You want to keep most of the original file, but you would like to add the `define_target` blocks which are being added.
23
+
24
+ In the resulting project directory that has been created, you can see the list of dependencies:
25
+
26
+ ~~~ bash
27
+ $ teapot list
28
+ ... lots of output ...
29
+ ~~~
30
+
31
+ To only see things exported by your current project, you can run:
32
+
33
+ ~~~ bash
34
+ $ teapot list root
35
+ Package root (from /private/tmp/my-project):
36
+ #<Teapot::Project "my-project">
37
+ My Project description.
38
+ - Summary: A brief one line summary of the project.
39
+ - License: MIT License
40
+ - Version: 0.1.0
41
+ - Author: Samuel Williams <samuel.williams@oriontransfer.co.nz>
42
+ #<Teapot::Target "my-project-library">
43
+ - depends on "Build/Files"
44
+ - depends on "Build/Clang"
45
+ - depends on :platform
46
+ - depends on "Language/C++14" {:private=>true}
47
+ - provides "Library/MyProject"
48
+ #<Teapot::Target "my-project-test">
49
+ - depends on "Library/UnitTest"
50
+ - depends on "Library/MyProject"
51
+ - provides "Test/MyProject"
52
+ #<Teapot::Target "my-project-executable">
53
+ - depends on "Build/Files"
54
+ - depends on "Build/Clang"
55
+ - depends on :platform
56
+ - depends on "Language/C++14" {:private=>true}
57
+ - depends on "Library/MyProject"
58
+ - provides "Executable/MyProject"
59
+ #<Teapot::Target "my-project-run">
60
+ - depends on "Executable/MyProject"
61
+ - provides "Run/MyProject"
62
+ #<Teapot::Configuration "development" visibility=private>
63
+ - references root from /private/tmp/my-project
64
+ - clones platforms from https://github.com/kurocha/platforms
65
+ - clones unit-test from https://github.com/kurocha/unit-test
66
+ - clones generate-cpp-class from https://github.com/kurocha/generate-cpp-class
67
+ - clones generate-project from https://github.com/kurocha/generate-project
68
+ - clones variants from https://github.com/kurocha/variants
69
+ - clones platform-darwin-osx from https://github.com/kurocha/platform-darwin-osx
70
+ - clones platform-darwin-ios from https://github.com/kurocha/platform-darwin-ios
71
+ - clones build-clang from https://github.com/kurocha/build-clang
72
+ - clones build-darwin from https://github.com/kurocha/build-darwin
73
+ - clones build-files from https://github.com/kurocha/build-files
74
+ - clones streams from https://github.com/kurocha/streams
75
+ - clones generate-template from https://github.com/kurocha/generate-template
76
+ #<Teapot::Configuration "my-project" visibility=public>
77
+ - references root from /private/tmp/my-project
78
+ ~~~
79
+
80
+ ## Run Tests
81
+
82
+ Testing is a good idea, and teapot supports test driven development.
83
+
84
+ ~~~ bash
85
+ $ teapot Test/MyProject
86
+ ~~~
87
+
88
+ ### Wildcard Targets
89
+
90
+ To run all tests:
91
+
92
+ ~~~ bash
93
+ $ teapot "Test/*"
94
+ ~~~
95
+
96
+ Provided you are using an environment that supports sanitizers, you can test more thoroughly using:
97
+
98
+ ~~~ bash
99
+ $ teapot "Test/*" variant-sanitize
100
+ ~~~
101
+
102
+ ## Run Project
103
+
104
+ We can now build and run the project executable:
105
+
106
+ ~~~ bash
107
+ $ teapot Run/MyProject
108
+ I'm a little teapot,
109
+ Short and stout,
110
+ Here is my handle (one hand on hip),
111
+ Here is my spout (other arm out with elbow and wrist bent).
112
+ When I get all steamed up,
113
+ Hear me shout,
114
+ Tip me over and pour me out! (lean over toward spout)
115
+
116
+ ~
117
+ ___^___ __
118
+ .- / \./ /
119
+ / / _/
120
+ \__| |
121
+ \_______/
122
+ ~~~
123
+
124
+ The resulting executables and libraries will be framework dependent, but are typically located in:
125
+
126
+ ~~~ bash
127
+ $ cd teapot/platforms/development/$PLATFORM-debug/bin
128
+ $ ./$PROJECT_NAME
129
+ ~~~
130
+
131
+ ## Cloning Project
132
+
133
+ You can clone another project which will fetch all dependencies:
134
+
135
+ ~~~ bash
136
+ $ teapot clone https://github.com/kurocha/tagged-format
137
+ $ cd tagged-format
138
+ $ teapot build Executable/TaggedFormat
139
+ ~~~
@@ -0,0 +1,13 @@
1
+ # Automatically generated context index for Utopia::Project guides.
2
+ # Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
3
+ ---
4
+ description: Teapot is a tool for managing cross-platform builds.
5
+ metadata:
6
+ documentation_uri: https://ioquatix.github.io/teapot/
7
+ funding_uri: https://github.com/sponsors/ioquatix
8
+ source_code_uri: https://github.com/ioquatix/teapot
9
+ files:
10
+ - path: getting-started.md
11
+ title: Getting Started
12
+ description: This guide explains how to use `teapot` to manage cross-platform project
13
+ dependencies and build systems.
@@ -9,9 +9,11 @@ require "build/controller"
9
9
 
10
10
  module Teapot
11
11
  module Command
12
+ # Raised when the build fails.
12
13
  class BuildFailedError < StandardError
13
14
  end
14
15
 
16
+ # A command to build targets in the project.
15
17
  class Build < Selection
16
18
  self.description = "Build the specified target."
17
19
 
@@ -23,6 +25,8 @@ module Teapot
23
25
  many :targets, "Build these targets, or use them to help the dependency resolution process."
24
26
  split :argv, "Arguments passed to child process(es) of build if any."
25
27
 
28
+ # Build the selected targets or default build targets, resolving dependencies and executing the build controller.
29
+ # @returns [Build::Dependency::Chain] The dependency chain.
26
30
  def call
27
31
  context = parent.context
28
32
 
@@ -65,6 +69,8 @@ module Teapot
65
69
  return chain
66
70
  end
67
71
 
72
+ # Display task dependencies for debugging, showing which tasks generate which outputs.
73
+ # @parameter walker [Build::Walker] The build walker.
68
74
  def show_dependencies(walker)
69
75
  outputs = {}
70
76
 
@@ -7,9 +7,11 @@ require "samovar"
7
7
 
8
8
  module Teapot
9
9
  module Command
10
+ # A command to clean build artifacts.
10
11
  class Clean < Samovar::Command
11
12
  self.description = "Delete everything in the teapot directory."
12
13
 
14
+ # Delete build output directories for the specified targets or all targets.
13
15
  def call
14
16
  context = parent.context
15
17
  logger = parent.logger
@@ -13,11 +13,13 @@ require "build/uri"
13
13
 
14
14
  module Teapot
15
15
  module Command
16
+ # A command to clone a remote repository and fetch all dependencies.
16
17
  class Clone < Samovar::Command
17
18
  self.description = "Clone a remote repository and fetch all dependencies."
18
19
 
19
20
  one :source, "The source repository to clone.", required: true
20
21
 
22
+ # Clone packages from their remote repositories using git, parallelizing the operations.
21
23
  def call
22
24
  logger = parent.logger
23
25
 
@@ -37,6 +39,11 @@ module Teapot
37
39
  Fetch[parent: nested].call
38
40
  end
39
41
 
42
+ # Provide credentials for repository authentication.
43
+ # @parameter url [String] The repository URL.
44
+ # @parameter username [String] The username.
45
+ # @parameter types [Array] The credential types allowed.
46
+ # @returns [Rugged::Credentials] The credentials object.
40
47
  def credentials(url, username, types)
41
48
  # We should prompt for username/password if required...
42
49
  return Rugged::Credentials::SshKeyFromAgent.new(username: username)
@@ -11,6 +11,7 @@ require "rugged"
11
11
 
12
12
  module Teapot
13
13
  module Command
14
+ # A command to create a new teapot project.
14
15
  class Create < Samovar::Command
15
16
  self.description = "Create a new teapot package using the specified repository."
16
17
 
@@ -18,6 +19,7 @@ module Teapot
18
19
  one :source, "The source repository to use for fetching packages, e.g. https://github.com/kurocha.", required: true
19
20
  many :packages, "Any packages you'd like to include in the project.", default: ["generate-project"]
20
21
 
22
+ # Create a new project directory structure with default teapot.rb configuration.
21
23
  def call
22
24
  logger = parent.logger
23
25
 
@@ -64,6 +66,11 @@ module Teapot
64
66
  )
65
67
  end
66
68
 
69
+ # Generate the initial project files.
70
+ # @parameter root [Build::Files::Path] The project root path.
71
+ # @parameter name [String] The project name.
72
+ # @parameter source [String] The source repository URL.
73
+ # @parameter packages [Array(String)] The packages to include.
67
74
  def generate_project(root, name, source, packages)
68
75
  name = ::Build::Name.new(name)
69
76
 
@@ -8,7 +8,10 @@ require "rugged"
8
8
 
9
9
  module Teapot
10
10
  module Command
11
+ # Raised when a fetch operation fails.
11
12
  class FetchError < StandardError
13
+ # @parameter package [Package] The package that caused the error.
14
+ # @parameter message [String] The error message.
12
15
  def initialize(package, message)
13
16
  super(message)
14
17
  @package = package
@@ -17,6 +20,7 @@ module Teapot
17
20
  attr :package
18
21
  end
19
22
 
23
+ # A command to fetch remote packages and dependencies.
20
24
  class Fetch < Samovar::Command
21
25
  self.description = "Fetch remote packages according to the specified configuration."
22
26
 
@@ -32,10 +36,13 @@ module Teapot
32
36
 
33
37
  many :packages, "Only update the specified packages, or all packages if none specified."
34
38
 
39
+ # Get the context for this command.
40
+ # @returns [Context] The current context.
35
41
  def context
36
42
  parent.context
37
43
  end
38
44
 
45
+ # Update packages by pulling latest changes from their git remotes, subject to lock file constraints.
39
46
  def call
40
47
  selection = context.select
41
48
 
@@ -10,9 +10,13 @@ require_relative "selection"
10
10
 
11
11
  module Teapot
12
12
  module Command
13
+ # A command to list project definitions and dependencies.
13
14
  class List < Selection
14
15
  self.description = "List provisions and dependencies of the specified package."
15
16
 
17
+ # Create a terminal with custom styles for colorizing different definition types in output.
18
+ # @parameter output [IO] The output stream.
19
+ # @returns [Console::Terminal] The configured terminal.
16
20
  def terminal(output = $stdout)
17
21
  Console::Terminal.for(output).tap do |terminal|
18
22
  terminal[:definition] = terminal.style(nil, nil, :bright)
@@ -24,6 +28,8 @@ module Teapot
24
28
  end
25
29
  end
26
30
 
31
+ # Process and display the selection.
32
+ # @parameter selection [Select] The selection to process.
27
33
  def process(selection)
28
34
  context = selection.context
29
35
  terminal = self.terminal
@@ -7,17 +7,23 @@ require "samovar"
7
7
 
8
8
  module Teapot
9
9
  module Command
10
+ # Base class for commands that work with selections.
10
11
  class Selection < Samovar::Command
11
12
  options
12
13
 
13
14
  many :targets, "Only consider the specified targets, if any."
14
15
 
16
+ # The set of target names to process, or nil if no targets were specified.
17
+ # @returns [Set | Nil] The set of target names.
15
18
  def targets
16
19
  if @targets and @targets.any?
17
20
  Set.new(@targets)
18
21
  end
19
22
  end
20
23
 
24
+ # Get the selection for the given context.
25
+ # @parameter context [Context] The project context.
26
+ # @returns [Select] The selection.
21
27
  def selection(context)
22
28
  if targets = self.targets
23
29
  context.select(targets)
@@ -26,6 +32,7 @@ module Teapot
26
32
  end
27
33
  end
28
34
 
35
+ # Execute the selection command.
29
36
  def call
30
37
  context = parent.context
31
38
 
@@ -9,9 +9,13 @@ require "console/terminal"
9
9
 
10
10
  module Teapot
11
11
  module Command
12
+ # A command to show git status of packages.
12
13
  class Status < Selection
13
14
  self.description = "List the git status of the specified package(s)."
14
15
 
16
+ # Create a terminal with custom styles for colorizing git status information.
17
+ # @parameter output [IO] The output stream.
18
+ # @returns [Console::Terminal] The configured terminal.
15
19
  def terminal(output = $stdout)
16
20
  Console::Terminal.for(output).tap do |terminal|
17
21
  terminal[:worktree_new] = terminal.style(:green)
@@ -20,6 +24,9 @@ module Teapot
20
24
  end
21
25
  end
22
26
 
27
+ # Open the git repository for a package, or return nil if the package doesn't have a repository yet.
28
+ # @parameter package [Package] The package.
29
+ # @returns [Rugged::Repository | Nil] The repository or nil.
23
30
  def repository_for(package)
24
31
  Rugged::Repository.new(package.path.to_s)
25
32
  rescue Rugged::RepositoryError
@@ -27,6 +34,8 @@ module Teapot
27
34
  nil
28
35
  end
29
36
 
37
+ # Process and display the selection.
38
+ # @parameter selection [Select] The selection to process.
30
39
  def process(selection)
31
40
  context = selection.context
32
41
  terminal = self.terminal
@@ -8,6 +8,7 @@ require "graphviz"
8
8
 
9
9
  module Teapot
10
10
  module Command
11
+ # A command to visualize the dependency graph.
11
12
  class Visualize < Selection
12
13
  self.description = "Generate a picture of the dependency graph."
13
14
 
@@ -16,14 +17,21 @@ module Teapot
16
17
  option "-d/--dependency-name <name>", "Show the partial chain for the given named dependency."
17
18
  end
18
19
 
20
+ # Get the dependency names to visualize.
21
+ # @returns [Array(String)] The dependency names.
19
22
  def dependency_names
20
23
  @targets || []
21
24
  end
22
25
 
26
+ # Get the specific dependency name to visualize.
27
+ # @returns [String | Nil] The dependency name.
23
28
  def dependency_name
24
29
  @options[:dependency_name]
25
30
  end
26
31
 
32
+ # Process and generate the visualization.
33
+ # @parameter selection [Select] The selection to visualize.
34
+ # @returns [Graphviz::Graph] The generated graph.
27
35
  def process(selection)
28
36
  context = selection.context
29
37
  chain = selection.chain
@@ -23,7 +23,9 @@ require "fileutils"
23
23
  require "console"
24
24
 
25
25
  module Teapot
26
+ # @namespace
26
27
  module Command
28
+ # Represents the top-level command for the teapot CLI.
27
29
  class Top < Samovar::Command
28
30
  self.description = "A decentralised package manager and build tool."
29
31
 
@@ -46,18 +48,26 @@ module Teapot
46
48
  "clean" => Clean,
47
49
  }, default: "build"
48
50
 
51
+ # The project root directory, either from --root option or current working directory.
52
+ # @returns [Build::Files::Path] The root directory path.
49
53
  def root
50
54
  ::Build::Files::Path.expand(@options[:root] || Dir.getwd)
51
55
  end
52
56
 
57
+ # Whether verbose logging is enabled via --verbose flag.
58
+ # @returns [Boolean] True if verbose mode is enabled.
53
59
  def verbose?
54
60
  @options[:logging] == :verbose
55
61
  end
56
62
 
63
+ # Whether quiet logging is enabled via --quiet flag.
64
+ # @returns [Boolean] True if quiet mode is enabled.
57
65
  def quiet?
58
66
  @options[:logging] == :quiet
59
67
  end
60
68
 
69
+ # Get the logger for the command.
70
+ # @returns [Console::Logger] The configured logger instance.
61
71
  def logger
62
72
  @logger ||= Console::Logger.new(Console.logger, verbose: self.verbose?).tap do |logger|
63
73
  if verbose?
@@ -70,14 +80,20 @@ module Teapot
70
80
  end
71
81
  end
72
82
 
83
+ # The build configuration name from -c option or TEAPOT_CONFIGURATION environment variable.
84
+ # @returns [String | Nil] The configuration name if specified.
73
85
  def configuration
74
86
  @options[:configuration]
75
87
  end
76
88
 
89
+ # Create a context for the project.
90
+ # @parameter root [Build::Files::Path] The root directory path.
91
+ # @returns [Context] A new context instance.
77
92
  def context(root = self.root)
78
93
  Context.new(root, configuration: configuration)
79
94
  end
80
95
 
96
+ # Execute the command.
81
97
  def call
82
98
  if @options[:version]
83
99
  puts "teapot v#{Teapot::VERSION}"
@@ -20,6 +20,11 @@ module Teapot
20
20
  :import => true
21
21
  }.freeze
22
22
 
23
+ # Initialize a new configuration.
24
+ # @parameter context [Context] The project context.
25
+ # @parameter package [Package] The package.
26
+ # @parameter name [String] The configuration name.
27
+ # @parameter packages [Array] The list of packages.
23
28
  def initialize(context, package, name, packages = [], **options)
24
29
  super context, package, name
25
30
 
@@ -34,6 +39,7 @@ module Teapot
34
39
  @targets = Hash.new{|hash,key| hash[key] = Array.new}
35
40
  end
36
41
 
42
+ # Make the configuration immutable to prevent modification after targets and packages are resolved.
37
43
  def freeze
38
44
  return self if frozen?
39
45
 
@@ -48,6 +54,8 @@ module Teapot
48
54
  super
49
55
  end
50
56
 
57
+ # Create an environment for this configuration.
58
+ # @returns [Build::Environment] The build environment.
51
59
  def environment
52
60
  configuration = self
53
61
 
@@ -60,10 +68,13 @@ module Teapot
60
68
  # Controls how the configuration is exposed in the context.
61
69
  attr :visibility
62
70
 
71
+ # Whether this configuration is publicly accessible (not hidden from listings).
72
+ # @returns [Boolean] True if public.
63
73
  def public?
64
74
  @visibility == :public
65
75
  end
66
76
 
77
+ # Mark this configuration as publicly visible in listings and help output.
67
78
  def public!
68
79
  @visibility = :public
69
80
  end
@@ -112,7 +123,7 @@ module Teapot
112
123
  @options[key] = value
113
124
  end
114
125
 
115
- # Get a configuration option.
126
+ # Access configuration-specific settings that control build behavior and environment variables.
116
127
  def [] key
117
128
  @options[key]
118
129
  end
@@ -129,14 +140,19 @@ module Teapot
129
140
 
130
141
  alias platforms_path build_path
131
142
 
143
+ # Get the path to the lock file.
144
+ # @returns [Build::Files::Path] The lock file path.
132
145
  def lock_path
133
146
  context.root + "#{@name}-lock.yml"
134
147
  end
135
148
 
149
+ # Get the lock store for persisting state.
150
+ # @returns [YAML::Store] The lock store.
136
151
  def lock_store
137
152
  ::YAML::Store.new(lock_path.to_s)
138
153
  end
139
154
 
155
+ # @returns [String] The string representation.
140
156
  def to_s
141
157
  "#<#{self.class} #{@name.dump} visibility=#{@visibility}>"
142
158
  end
@@ -8,6 +8,8 @@ require_relative "select"
8
8
  module Teapot
9
9
  # A context represents a specific root package instance with a given configuration and all related definitions. A context is stateful in the sense that package selection is specialized based on #select and #dependency_chain. These parameters are usually set up initially as part of the context setup.
10
10
  class Context
11
+ # Initialize a new context.
12
+ # @parameter root [String] The root path.
11
13
  def initialize(root, **options)
12
14
  @root = Path[root]
13
15
  @options = options
@@ -29,14 +31,22 @@ module Teapot
29
31
  # The primary project.
30
32
  attr :project
31
33
 
34
+ # Discover and open the git repository for this context's root directory.
35
+ # @returns [Rugged::Repository] The git repository.
32
36
  def repository
33
37
  @repository ||= Rugged::Repository.discover(@root.to_s)
34
38
  end
35
39
 
40
+ # Create a selection that resolves dependencies and loads definitions for the specified targets or configurations.
41
+ # @parameter names [Array | Nil] The names to select.
42
+ # @parameter configuration [Configuration] The configuration to use.
43
+ # @returns [Select] The selection.
36
44
  def select(names = nil, configuration = @configuration)
37
45
  Select.new(self, configuration, names || [])
38
46
  end
39
47
 
48
+ # Get substitutions for template generation.
49
+ # @returns [Build::Text::Substitutions] The substitutions.
40
50
  def substitutions
41
51
  substitutions = Build::Text::Substitutions.new
42
52
 
@@ -71,6 +81,9 @@ module Teapot
71
81
  return substitutions
72
82
  end
73
83
 
84
+ # Load a package from its teapot.rb, tracking loaded packages to prevent duplicates.
85
+ # @parameter package [Package] The package to load.
86
+ # @returns [Script] The loaded script.
74
87
  def load(package)
75
88
  if loader = @loaded[package]
76
89
  return loader.script unless loader.changed?
@@ -4,7 +4,12 @@
4
4
  # Copyright, 2013-2026, by Samuel Williams.
5
5
 
6
6
  module Teapot
7
+ # Base class for definitions (target, configuration, or project).
7
8
  class Definition
9
+ # Initialize a new definition.
10
+ # @parameter context [Context] The project context.
11
+ # @parameter package [Package] The package.
12
+ # @parameter name [String] The definition name.
8
13
  def initialize(context, package, name)
9
14
  @context = context
10
15
  @package = package
@@ -14,6 +19,7 @@ module Teapot
14
19
  @description = nil
15
20
  end
16
21
 
22
+ # Make the definition immutable after it has been loaded from a teapot file.
17
23
  def freeze
18
24
  @name.freeze
19
25
  @description.freeze
@@ -21,6 +27,7 @@ module Teapot
21
27
  super
22
28
  end
23
29
 
30
+ # @returns [String] The string representation.
24
31
  def inspect
25
32
  "\#<#{self.class.name} #{@name}>"
26
33
  end
@@ -37,6 +44,8 @@ module Teapot
37
44
  # A textual description of the definition, possibly in markdown format:
38
45
  attr :description
39
46
 
47
+ # Assign a description with automatic removal of common leading indentation.
48
+ # @parameter text [String] The description text.
40
49
  def description=(text)
41
50
  if text =~ /^(\t+)/
42
51
  text = text.gsub(/#{$1}/, "")
@@ -50,6 +59,7 @@ module Teapot
50
59
  @package.path
51
60
  end
52
61
 
62
+ # @returns [String] The string representation.
53
63
  def to_s
54
64
  "#<#{self.class} #{@name.dump}>"
55
65
  end
data/lib/teapot/loader.rb CHANGED
@@ -24,7 +24,10 @@ module Teapot
24
24
  # The package relative path to the file to load:
25
25
  TEAPOT_FILE = "teapot.rb".freeze
26
26
 
27
+ # Raised when a teapot file requires an incompatible version.
27
28
  class IncompatibleTeapotError < StandardError
29
+ # @parameter package [Package] The package.
30
+ # @parameter version [String] The version.
28
31
  def initialize(package, version)
29
32
  super "Unsupported teapot_version #{version} in #{package.path}!"
30
33
  end
@@ -32,7 +35,9 @@ module Teapot
32
35
  attr :version
33
36
  end
34
37
 
38
+ # Raised when a teapot file cannot be found.
35
39
  class MissingTeapotError < StandardError
40
+ # @parameter path [String] The file path.
36
41
  def initialize(path)
37
42
  super "Could not read file at #{path}!"
38
43
  end
@@ -45,6 +50,10 @@ module Teapot
45
50
  Files = Build::Files
46
51
  Rule = Build::Rule
47
52
 
53
+ # Initialize a new script.
54
+ # @parameter context [Context] The project context.
55
+ # @parameter package [Package] The package.
56
+ # @parameter path [String] The teapot file path.
48
57
  def initialize(context, package, path = TEAPOT_FILE)
49
58
  @context = context
50
59
  @package = package
@@ -70,6 +79,8 @@ module Teapot
70
79
  attr :default_project
71
80
  attr :default_configuration
72
81
 
82
+ # Specify the minimum required teapot gem version for compatibility checks.
83
+ # @parameter version [String] The required version.
73
84
  def teapot_version(version)
74
85
  version = version[0..2]
75
86
 
@@ -82,6 +93,8 @@ module Teapot
82
93
 
83
94
  alias required_version teapot_version
84
95
 
96
+ # Define a new project.
97
+ # @parameter arguments [Array] The definition arguments.
85
98
  def define_project(*arguments, **options)
86
99
  project = Project.new(@context, @package, *arguments, **options)
87
100
 
@@ -91,6 +104,8 @@ module Teapot
91
104
  @defined << project
92
105
  end
93
106
 
107
+ # Define a new target.
108
+ # @parameter arguments [Array] The definition arguments.
94
109
  def define_target(*arguments, **options)
95
110
  target = Target.new(@context, @package, *arguments, **options)
96
111
 
@@ -101,6 +116,8 @@ module Teapot
101
116
  @defined << target
102
117
  end
103
118
 
119
+ # Define a new configuration.
120
+ # @parameter arguments [Array] The definition arguments.
104
121
  def define_configuration(*arguments, **options)
105
122
  configuration = Configuration.new(@context, @package, *arguments, **options)
106
123
 
@@ -127,6 +144,10 @@ module Teapot
127
144
 
128
145
  # Loads the teapot.rb script and can reload it if it was changed.
129
146
  class Loader
147
+ # Initialize a new loader.
148
+ # @parameter context [Context] The project context.
149
+ # @parameter package [Package] The package.
150
+ # @parameter path [String] The teapot file path.
130
151
  def initialize(context, package, path = TEAPOT_FILE)
131
152
  @context = context
132
153
  @package = package
@@ -139,14 +160,20 @@ module Teapot
139
160
 
140
161
  attr :script
141
162
 
163
+ # The absolute path to the teapot.rb file for this package.
164
+ # @returns [Build::Files::Path] The teapot file path.
142
165
  def teapot_path
143
166
  @package.path + @path
144
167
  end
145
168
 
169
+ # Whether the teapot file has been modified since it was loaded.
170
+ # @returns [Boolean] True if changed.
146
171
  def changed?
147
172
  File.mtime(teapot_path) > @mtime
148
173
  end
149
174
 
175
+ # Reload the loader with fresh data.
176
+ # @returns [Loader] A new loader instance.
150
177
  def reload
151
178
  self.class.new(@context, @package, @path)
152
179
  end
@@ -11,7 +11,12 @@ require_relative "definition"
11
11
  module Teapot
12
12
  Path = Build::Files::Path
13
13
 
14
+ # A package in the dependency graph.
14
15
  class Package
16
+ # Initialize a new package.
17
+ # @parameter path [String] The package path.
18
+ # @parameter name [String | Symbol] The package name or URI.
19
+ # @parameter options [Hash] Additional options.
15
20
  def initialize(path, name, options = {})
16
21
  # The path where the package is (or will be) located:
17
22
  @path = Path[path]
@@ -35,6 +40,7 @@ module Teapot
35
40
  @options = options
36
41
  end
37
42
 
43
+ # Make the package immutable to prevent modification after it's been loaded and processed.
38
44
  def freeze
39
45
  @path.freeze
40
46
  @name.freeze
@@ -50,14 +56,20 @@ module Teapot
50
56
  attr :uri
51
57
  attr_accessor :options
52
58
 
59
+ # The local filesystem path if this package is linked rather than cloned.
60
+ # @returns [String] The local path.
53
61
  def local
54
62
  @options[:local].to_s
55
63
  end
56
64
 
65
+ # Whether this package is linked from a local path instead of being cloned from a remote repository.
66
+ # @returns [Boolean] True if local.
57
67
  def local?
58
68
  @options.include?(:local)
59
69
  end
60
70
 
71
+ # Whether this package should be cloned from an external source repository.
72
+ # @returns [Boolean] True if external.
61
73
  def external?
62
74
  @options.include?(:source)
63
75
  end
@@ -67,10 +79,14 @@ module Teapot
67
79
  Build::URI[@options[:source]]
68
80
  end
69
81
 
82
+ # Construct the full URL from which this package should be cloned, combining the root path, source URI, and package URI.
83
+ # @parameter root_path [String | Nil] The root path.
84
+ # @returns [Build::URI] The external URL.
70
85
  def external_url(root_path = nil)
71
86
  Build::URI[root_path] + source_uri + Build::URI[@uri]
72
87
  end
73
88
 
89
+ # @returns [String] The string representation.
74
90
  def to_s
75
91
  if self.local?
76
92
  "links #{@name} from #{self.local}"
@@ -83,10 +99,15 @@ module Teapot
83
99
 
84
100
  # Package may be used as hash key / in a set:
85
101
 
102
+ # Packages are hashed by path for use as hash keys and set members.
103
+ # @returns [Integer] The hash code.
86
104
  def hash
87
105
  @path.hash
88
106
  end
89
107
 
108
+ # Packages are considered equal if they have the same path.
109
+ # @parameter other [Package] The other package.
110
+ # @returns [Boolean] True if equal.
90
111
  def eql?(other)
91
112
  @path.eql?(other.path)
92
113
  end
@@ -6,9 +6,14 @@
6
6
  require_relative "definition"
7
7
 
8
8
  module Teapot
9
+ # A project definition.
9
10
  class Project < Definition
10
11
  Author = Struct.new(:name, :email, :website)
11
12
 
13
+ # Initialize a new project.
14
+ # @parameter context [Context] The project context.
15
+ # @parameter package [Package] The package.
16
+ # @parameter name [String] The project name.
12
17
  def initialize(context, package, name)
13
18
  super context, package, name
14
19
 
@@ -16,6 +21,8 @@ module Teapot
16
21
  @authors = []
17
22
  end
18
23
 
24
+ # Get the project name as a Build::Name object.
25
+ # @returns [Build::Name] The project name.
19
26
  def name
20
27
  if @title
21
28
  # Prefer title, it retains case.
@@ -26,6 +33,7 @@ module Teapot
26
33
  end
27
34
  end
28
35
 
36
+ # Make the project immutable after all packages and configurations have been loaded.
29
37
  def freeze
30
38
  @title.freeze
31
39
  @summary.freeze
@@ -46,6 +54,9 @@ module Teapot
46
54
 
47
55
  attr :authors
48
56
 
57
+ # Add an author to the project.
58
+ # @parameter name [String] The author name.
59
+ # @parameter options [Hash] Author options (email, website).
49
60
  def add_author(name, options = {})
50
61
  @authors << Author.new(name, options[:email], options[:website])
51
62
  end
data/lib/teapot/select.rb CHANGED
@@ -11,11 +11,17 @@ require "build/text/substitutions"
11
11
  require "build/text/merge"
12
12
 
13
13
  module Teapot
14
+ # Raised when a definition is already defined.
14
15
  class AlreadyDefinedError < StandardError
16
+ # @parameter definition [Definition] The definition.
17
+ # @parameter previous [Definition] The previous definition.
15
18
  def initialize(definition, previous)
16
19
  super "Definition #{definition.name} in #{definition.path} has already been defined in #{previous.path}!"
17
20
  end
18
21
 
22
+ # Check if a definition would cause a conflict.
23
+ # @parameter definition [Definition] The definition to check.
24
+ # @parameter definitions [Hash] The existing definitions.
19
25
  def self.check(definition, definitions)
20
26
  previous = definitions[definition.name]
21
27
 
@@ -25,6 +31,10 @@ module Teapot
25
31
 
26
32
  # A selection is a specific view of the data exposed by the context at a specific point in time.
27
33
  class Select
34
+ # Initialize a new selection.
35
+ # @parameter context [Context] The project context.
36
+ # @parameter configuration [Configuration] The configuration.
37
+ # @parameter names [Array] The names to select.
28
38
  def initialize(context, configuration, names = [])
29
39
  @context = context
30
40
  @configuration = Configuration.new(context, configuration.package, configuration.name, [], **configuration.options)
@@ -61,10 +71,15 @@ module Teapot
61
71
  attr :resolved
62
72
  attr :unresolved
63
73
 
74
+ # Get the dependency chain.
75
+ # @returns [Build::Dependency::Chain] The dependency chain.
64
76
  def chain
65
77
  @chain ||= Build::Dependency::Chain.expand(@dependencies, @targets.values, @selection)
66
78
  end
67
79
 
80
+ # Extract the targets that directly satisfy the requested dependencies.
81
+ # @parameter ordered [Array] The ordered targets.
82
+ # @returns [Array] The direct targets.
68
83
  def direct_targets(ordered)
69
84
  @dependencies.collect do |dependency|
70
85
  ordered.find{|(package, _)| package.provides? dependency}
data/lib/teapot/target.rb CHANGED
@@ -11,18 +11,22 @@ require "build/environment"
11
11
  require "build/rulebook"
12
12
 
13
13
  module Teapot
14
+ # Raised during build operations.
14
15
  class BuildError < StandardError
15
16
  end
16
17
 
18
+ # A build target.
17
19
  class Target < Definition
18
20
  include Build::Dependency
19
21
 
22
+ # Initialize a new target.
20
23
  def initialize(*)
21
24
  super
22
25
 
23
26
  @build = nil
24
27
  end
25
28
 
29
+ # Make the target immutable after it has been completely defined with dependencies and build rules.
26
30
  def freeze
27
31
  return self if frozen?
28
32
 
@@ -31,6 +35,9 @@ module Teapot
31
35
  super
32
36
  end
33
37
 
38
+ # Define the build block for this target.
39
+ # @parameter block [Proc | Nil] The build block.
40
+ # @returns [Proc | Nil] The build block.
34
41
  def build(&block)
35
42
  if block_given?
36
43
  @build = block
@@ -39,6 +46,7 @@ module Teapot
39
46
  return @build
40
47
  end
41
48
 
49
+ # Update environments with the build block.
42
50
  def update_environments!
43
51
  return unless @build
44
52
 
@@ -3,6 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2012-2026, by Samuel Williams.
5
5
 
6
+ # @namespace
6
7
  module Teapot
7
- VERSION = "3.6.0"
8
+ VERSION = "3.6.1"
8
9
  end
data/lib/teapot.rb CHANGED
@@ -4,8 +4,4 @@
4
4
  # Copyright, 2012-2026, by Samuel Williams.
5
5
 
6
6
  require "teapot/version"
7
-
8
7
  require "teapot/context"
9
-
10
- module Teapot
11
- end
data/readme.md CHANGED
@@ -17,127 +17,13 @@ Ensure that you already have a working install of Ruby 2.0.0+ and run the follow
17
17
 
18
18
  ## Usage
19
19
 
20
- Please see the [project documentation](http://www.teapot.nz) for more details.
21
-
22
- ### Create Project
23
-
24
- Firstly, create your project by running:
25
-
26
- $ teapot create "My Project" https://github.com/kurocha generate-project
27
- $ cd my-project
28
-
29
- You will be asked to merge the project file. At present, merge tools are not very good and thus you may need to take a moment to review the changes. You want to keep most of the original file, but you would like to add the `define_target` blocks which are being added.
30
-
31
- In the resulting project directory that has been created, you can see the list of dependencies:
32
-
33
- $ teapot list
34
- ... lots of output ...
35
-
36
- To only see things exported by your current project, you can run:
37
-
38
- $ teapot list root
39
- Package root (from /private/tmp/my-project):
40
- #<Teapot::Project "my-project">
41
- My Project description.
42
- - Summary: A brief one line summary of the project.
43
- - License: MIT License
44
- - Version: 0.1.0
45
- - Author: Samuel Williams <samuel.williams@oriontransfer.co.nz>
46
- #<Teapot::Target "my-project-library">
47
- - depends on "Build/Files"
48
- - depends on "Build/Clang"
49
- - depends on :platform
50
- - depends on "Language/C++14" {:private=>true}
51
- - provides "Library/MyProject"
52
- #<Teapot::Target "my-project-test">
53
- - depends on "Library/UnitTest"
54
- - depends on "Library/MyProject"
55
- - provides "Test/MyProject"
56
- #<Teapot::Target "my-project-executable">
57
- - depends on "Build/Files"
58
- - depends on "Build/Clang"
59
- - depends on :platform
60
- - depends on "Language/C++14" {:private=>true}
61
- - depends on "Library/MyProject"
62
- - provides "Executable/MyProject"
63
- #<Teapot::Target "my-project-run">
64
- - depends on "Executable/MyProject"
65
- - provides "Run/MyProject"
66
- #<Teapot::Configuration "development" visibility=private>
67
- - references root from /private/tmp/my-project
68
- - clones platforms from https://github.com/kurocha/platforms
69
- - clones unit-test from https://github.com/kurocha/unit-test
70
- - clones generate-cpp-class from https://github.com/kurocha/generate-cpp-class
71
- - clones generate-project from https://github.com/kurocha/generate-project
72
- - clones variants from https://github.com/kurocha/variants
73
- - clones platform-darwin-osx from https://github.com/kurocha/platform-darwin-osx
74
- - clones platform-darwin-ios from https://github.com/kurocha/platform-darwin-ios
75
- - clones build-clang from https://github.com/kurocha/build-clang
76
- - clones build-darwin from https://github.com/kurocha/build-darwin
77
- - clones build-files from https://github.com/kurocha/build-files
78
- - clones streams from https://github.com/kurocha/streams
79
- - clones generate-template from https://github.com/kurocha/generate-template
80
- #<Teapot::Configuration "my-project" visibility=public>
81
- - references root from /private/tmp/my-project
82
-
83
- ### Run Tests
84
-
85
- Testing is a good idea, and teapot supports test driven development.
86
-
87
- $ teapot Test/MyProject
88
-
89
- #### Wildcard Targets
90
-
91
- To run all tests:
92
-
93
- $ teapot "Test/*"
94
-
95
- Provided you are using an environment that supports sanitizers, you can test more thoroughly using:
96
-
97
- $ teapot "Test/*" variant-sanitize
98
-
99
- ### Run Project
100
-
101
- We can now build and run the project executable:
102
-
103
- $ teapot Run/MyProject
104
- I'm a little teapot,
105
- Short and stout,
106
- Here is my handle (one hand on hip),
107
- Here is my spout (other arm out with elbow and wrist bent).
108
- When I get all steamed up,
109
- Hear me shout,
110
- Tip me over and pour me out! (lean over toward spout)
111
-
112
- ~
113
- ___^___ __
114
- .- / \./ /
115
- / / _/
116
- \__| |
117
- \_______/
118
-
119
- The resulting executables and libraries will be framework dependent, but are typically located in:
120
-
121
- $ cd teapot/platforms/development/$PLATFORM-debug/bin
122
- $ ./$PROJECT_NAME
123
-
124
- ### Cloning Project
125
-
126
- You can clone another project which will fetch all dependencies:
127
-
128
- $ teapot clone https://github.com/kurocha/tagged-format
129
- $ cd tagged-format
130
- $ teapot build Executable/TaggedFormat
131
-
132
- ## Open Issues
133
-
134
- - Should packages be built into a shared prefix or should they be built into unique prefixes and joined together either via install or `-L` and `-I`?
135
- - Relative include paths might fail to work correctly if headers are not installed into same directory.
136
- - Should packages have some way to expose system requirements, e.g. installed compiler, libraries, etc. Perhaps some kind of `Package#valid?` which allows custom logic?
20
+ Please see the [project documentation](https://ioquatix.github.io/teapot/) for more details.
21
+
22
+ - [Getting Started](https://ioquatix.github.io/teapot/guides/getting-started/index) - This guide explains how to use `teapot` to manage cross-platform project dependencies and build systems.
137
23
 
138
24
  ## Releases
139
25
 
140
- Please see the [project releases](http://www.teapot.nzreleases/index) for all releases.
26
+ Please see the [project releases](https://ioquatix.github.io/teapot/releases/index) for all releases.
141
27
 
142
28
  ### v3.6.0
143
29
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teapot
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.0
4
+ version: 3.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -150,20 +150,6 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: '1.0'
153
- - !ruby/object:Gem::Dependency
154
- name: graphviz
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: '1.0'
160
- type: :runtime
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: '1.0'
167
153
  - !ruby/object:Gem::Dependency
168
154
  name: process-group
169
155
  requirement: !ruby/object:Gem::Requirement
@@ -226,6 +212,8 @@ extensions: []
226
212
  extra_rdoc_files: []
227
213
  files:
228
214
  - bin/teapot
215
+ - context/getting-started.md
216
+ - context/index.yaml
229
217
  - lib/teapot.rb
230
218
  - lib/teapot/command.rb
231
219
  - lib/teapot/command/build.rb
@@ -250,10 +238,12 @@ files:
250
238
  - notes.md
251
239
  - readme.md
252
240
  - releases.md
253
- homepage: http://www.teapot.nz
254
241
  licenses:
255
242
  - MIT
256
- metadata: {}
243
+ metadata:
244
+ documentation_uri: https://ioquatix.github.io/teapot/
245
+ funding_uri: https://github.com/sponsors/ioquatix
246
+ source_code_uri: https://github.com/ioquatix/teapot
257
247
  rdoc_options: []
258
248
  require_paths:
259
249
  - lib
@@ -270,5 +260,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
260
  requirements: []
271
261
  rubygems_version: 4.0.6
272
262
  specification_version: 4
273
- summary: Teapot is a tool for managing complex cross-platform builds.
263
+ summary: Teapot is a tool for managing cross-platform builds.
274
264
  test_files: []
metadata.gz.sig CHANGED
Binary file