Skip to content

Commit

Permalink
docs: add code level documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
soumyamahunt committed Mar 11, 2022
1 parent 8bbac4d commit f3c04ed
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 4 deletions.
53 changes: 52 additions & 1 deletion lib/cocoapods-embed-flutter/flutter/dependency.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,37 @@

module Flutter
module Pub
# Provides a DSL to describe a flutter dependency. A dependency is defined in
# `pubspec.yaml` in `dependencies` or `dev_dependencies` sections.
#
class Dependency
attr_reader :name, :requirements, :parent_spec, :is_dev_dependency
# @return [String] the name of the dependency.
#
attr_reader :name
# @return [String, Hash] the requirements for
# dependency as declred in parent `pubspec`.
#
attr_reader :requirements
# @return [Spec] the parent specification where
# dependency declared.
#
attr_reader :parent_spec
# @return [Boolean] If this specification is an app specification.
#
attr_reader :is_dev_dependency

# @param [String] name
# the name of the specification.
#
# @param [String, Hash] requirements
# the requirements for dependency as declred in `pubspec`
#
# @param [Spec] parent_specification
# the parent specification where dependency declared
#
# @param [Boolean] is_dev_dependency
# Whether the dependency only required during development
#
def initialize(name, requirements, parent_spec, dev_dependency = false)
raise StandardError, 'A flutter dependency requires a name.' unless name
raise StandardError, 'A flutter dependency requires a parent pubspec.' unless parent_spec.is_a?(Flutter::Pub::Spec)
Expand All @@ -14,19 +42,42 @@ def initialize(name, requirements, parent_spec, dev_dependency = false)
@is_dev_dependency = dev_dependency
end

# Returns dependencies from hash declared in `dependencies` or `dev_dependencies`
# section in `pubspec.yaml` file.
#
# @param [Hash] hash declared in `dependencies` or `dev_dependencies`
# section in `pubspec.yaml` file
#
# @param [Spec] parent_specification
# the parent specification where dependency declared
#
# @param [Boolean] is_dev_dependency
# Whether the dependency only required during development
#
# @return [Array<Dependency>] dependencies from hash declared in `dependencies`
# or `dev_dependencies` section in `pubspec.yaml` file.
#
def self.create_from_hash(hash, parent_spec, dev_dependency = false)
raise StandardError, 'A flutter dependency requires a parent pubspec.' unless parent_spec.is_a?(Flutter::Pub::Spec)
hash.keys.map { |key| Dependency.new(key, hash[key], parent_spec, dev_dependency) }
end

# @return [Boolean] If this dependency is a local flutter project.
#
def local?
requirements.is_a?(Hash) && requirements.include?('path')
end

# @return [Spec] for this dependency if this dependency is a local flutter project.
#
def spec
Spec.find(name, File.expand_path(path, File.dirname(parent_spec.defined_in_file)))
end

# Install this dependency for the parent project.
#
# @return void
#
def install
spec.setup if local?
end
Expand Down
2 changes: 2 additions & 0 deletions lib/cocoapods-embed-flutter/flutter/downloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ module Downloader
# @param [Pathname,Nil] cache_path
# the path used to cache pod downloads.
#
# @todo Implement caching for remote sources.
#
def self.download(
request,
target,
Expand Down
14 changes: 14 additions & 0 deletions lib/cocoapods-embed-flutter/flutter/external_sources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ module ExternalSources
:http => [:flatten, :type, :sha256, :sha1, :headers].freeze,
}.freeze

# Returns the path to `pubspec` with the given name and location to search.
#
# @param [String] name
# the name of the project declared in `pubspec`.
#
# @param [Hash] options
# requirement opttions for the source of project.
#
# @note the source of project can either be local or all the remotes
# supported by `cocoapods-downloader`.
#
# @return [Spec] the `pubspec` with the given name satisfying
# requirement options.
#
def self.fetchWithNameAndOptions(name, options)
raise StandardError, 'A flutter module requires a name.' unless name

Expand Down
76 changes: 73 additions & 3 deletions lib/cocoapods-embed-flutter/flutter/pubspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,41 @@ module Pub
TOOL_DIR = '.dart_tool'.freeze
CACHE_FILE = 'package_config.json'.freeze

# The Specification provides a DSL to describe a flutter project.
# A project is defined as a library originating from a source.
# A specification can support detailed attributes for modules of code
# through dependencies.
#
# Usually it is stored in `pubspec.yaml` file.
#
class Spec
# @return [String] the path where the specification is defined, if loaded
# from a file.
#
attr_reader :defined_in_file

# @param [String] path
# the path to the specification.
#
def initialize(path)
@data = YAML.load_file path
@defined_in_file = path
end

# Returns the path to `pubspec` with the given name and location to search.
#
# @param [String] name
# the name of the project declared in `pubspec`.
#
# @param [String] path
# where project or pubspec is located.
#
# @note either the flutter module or the `pubspec` of the flutter module
# can be in the path. Optionally you can provide the `pubspec`
# file directly.
#
# @return [String] path to the `pubspec` with the given name if present.
#
def self.find_file(name, path)
path = File.expand_path(path, Dir.pwd)

Expand All @@ -32,6 +59,20 @@ def self.find_file(name, path)
end
end

# Returns the path to `pubspec` with the given name and location to search.
#
# @param [String] name
# the name of the project declared in `pubspec`.
#
# @param [String] path
# where project or pubspec is located.
#
# @note either the flutter module or the `pubspec` of the flutter module
# can be in the path. Optionally you can provide the `pubspec`
# file directly.
#
# @return [Spec] the `pubspec` with the given name if present.
#
def self.find(name, path)
pubspec_path = find_file(name, path)
raise StandardError, "Invalid path: '#{path}' for flutter module: '#{name}'." unless pubspec_path
Expand All @@ -40,47 +81,76 @@ def self.find(name, path)
return pubspec
end

# @return [Boolean] If this specification is a module specification.
#
def module?
return false unless @data.include?(Flutter::NAME)
return @data[Flutter::NAME].is_a?(Hash) && @data[Flutter::NAME].include?('module')
end

# @return [String] the path to the flutter project.
#
def project_path
File.dirname(defined_in_file)
end

# @return [String] the path to the flutter project
# dependencies cache file.
#
def package_cache_path
File.join(project_path, Pub::TOOL_DIR, Pub::CACHE_FILE)
end

# @return [String] the path to the flutter project.
#
def pod_helper_path
File.join(project_path, '.ios', Flutter::DIR_NAME, 'podhelper.rb') if module?
end

# @return [Array<Dependency>] the list of all the projects this
# specification depends upon and are included in app release.
#
def dependencies
return [] unless @data.include?('dependencies')
Flutter::Pub::Dependency.create_from_hash(@data['dependencies'], self)
Dependency.create_from_hash(@data['dependencies'], self)
end

# @return [Array<Dependency>] the list of all the projects this
# specification depends upon only during development.
#
def dev_dependencies
return [] unless @data.include?('dev_dependencies')
Flutter::Pub::Dependency.create_from_hash(@data['dev_dependencies'], self)
Dependency.create_from_hash(@data['dev_dependencies'], self)
end

# @return [Array<Dependency>] the list of all the projects this
# specification depends upon.
#
def all_dependencies
dependencies + dev_dependencies
end

# @return [Boolean] If the flutter project for this specification
# has all its dependencies installed.
#
def setup?
File.exists?(package_cache_path) && (!module? || File.exists?(pod_helper_path))
end

# Sets up the project installing all specified dependencies.
#
# @return void
#
def setup
return if setup?
pup_get
all_dependencies.each(&:install)
end
end

# Runs `flutter pub get` on project directory.
#
# @return void
#
def pup_get
Dir.chdir(project_path) { |path| system('flutter pub get', exception: true) }
end
Expand Down
92 changes: 92 additions & 0 deletions lib/cocoapods-embed-flutter/src/pub.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,99 @@

module Pod
class Podfile
# The Podfile is a specification that describes the dependencies of the
# targets of one or more Xcode projects. With Embed Flutter
# it is possible to declare flutter module as dependency
#
# A Podfile can be very simple:
#
# target 'MyApp'
# pub 'flutter_module', :path => '../'
#
# An example of a more complex Podfile can be:
#
# platform :ios, '9.0'
# inhibit_all_warnings!
#
# target 'MyApp' do
# pub 'flutter_module', :path => '../'
# end
#
# target 'MyAppTests' do
# pub 'flutter_module_test', :path => '../'
# end
#
# post_install do |installer|
# installer.pods_project.targets.each do |target|
# puts "#{target.name}"
# end
# end
#
#
# @note Currently only one flutter module per target is
# supported.
#
module DSL
# Specifies a flutter module dependency of the project.
#
# A dependency requirement is defined by the name of the module and
# optionally a list of requirements.
#
#
# ### Using the files from a local path.
#
# If you would like to use develop a flutter module in tandem with
# its client project you can use the `path` option.
#
# pub 'flutter_module', :path => '../'
#
# Using this option Embed Flutter will assume the given folder
# to be the root of the flutter module or the root of flutter module `pubspec` file
# or points to the `pubspec` file itself and will link the files directly from there
# in the Pods project. This means that your edits will persist to
# CocoaPods installations.
#
# The referenced folder can be a checkout of your your favourite SCM or
# even a git submodule of the current repository.
#
# Note that either the flutter module or the `pubspec` of the flutter module
# can be in the folder. Optionally you can provide the `pubspec` file directly.
#
#
# ### From a flutter module in the root of a library repository.
#
# Sometimes you may want to use the bleeding edge version of a module. Or a
# specific revision. If this is the case, you can specify that with your
# pub declaration.
#
# To use the `master` or `main` branch of the repository:
#
# pub 'flutter_module', :git => 'https://github.com/octokit/flutter_module.git'
#
#
# To use a different branch of the repository:
#
# pub 'flutter_module', :git => 'https://github.com/octokit/flutter_module.git', :branch => 'dev'
#
#
# To use a tag of the repository:
#
# pub 'flutter_module', :git => 'https://github.com/octokit/flutter_module.git', :tag => '0.7.0'
#
#
# Or specify a commit:
#
# pub 'flutter_module', :git => 'https://github.com/octokit/flutter_module.git', :commit => '082f8319af'
#
# The flutter module or its `pubspec` file is expected to be in the
# root of the repository.
#
#
# @note This method allow a nil name and the raises to be more
# informative.
#
# @return [void]
#
def pub(name = nil, *requirements)
pubspec = Flutter::Pub::ExternalSources.fetchWithNameAndOptions(name, requirements)
pubspec.setup
Expand Down

0 comments on commit f3c04ed

Please sign in to comment.