From f3c04ed6fddab8901511530014282006beb11e8f Mon Sep 17 00:00:00 2001 From: Soumya Ranjan Mahunt Date: Fri, 11 Mar 2022 09:42:17 +0530 Subject: [PATCH] docs: add code level documentation --- .../flutter/dependency.rb | 53 ++++++++++- .../flutter/downloader.rb | 2 + .../flutter/external_sources.rb | 14 +++ .../flutter/pubspec.rb | 76 ++++++++++++++- lib/cocoapods-embed-flutter/src/pub.rb | 92 +++++++++++++++++++ 5 files changed, 233 insertions(+), 4 deletions(-) diff --git a/lib/cocoapods-embed-flutter/flutter/dependency.rb b/lib/cocoapods-embed-flutter/flutter/dependency.rb index a202d39..319dddd 100644 --- a/lib/cocoapods-embed-flutter/flutter/dependency.rb +++ b/lib/cocoapods-embed-flutter/flutter/dependency.rb @@ -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) @@ -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] 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 diff --git a/lib/cocoapods-embed-flutter/flutter/downloader.rb b/lib/cocoapods-embed-flutter/flutter/downloader.rb index 7b417fc..4fe6589 100644 --- a/lib/cocoapods-embed-flutter/flutter/downloader.rb +++ b/lib/cocoapods-embed-flutter/flutter/downloader.rb @@ -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, diff --git a/lib/cocoapods-embed-flutter/flutter/external_sources.rb b/lib/cocoapods-embed-flutter/flutter/external_sources.rb index 4875260..ccbac66 100644 --- a/lib/cocoapods-embed-flutter/flutter/external_sources.rb +++ b/lib/cocoapods-embed-flutter/flutter/external_sources.rb @@ -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 diff --git a/lib/cocoapods-embed-flutter/flutter/pubspec.rb b/lib/cocoapods-embed-flutter/flutter/pubspec.rb index 585172f..1b6a634 100644 --- a/lib/cocoapods-embed-flutter/flutter/pubspec.rb +++ b/lib/cocoapods-embed-flutter/flutter/pubspec.rb @@ -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) @@ -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 @@ -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] 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] 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] 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 diff --git a/lib/cocoapods-embed-flutter/src/pub.rb b/lib/cocoapods-embed-flutter/src/pub.rb index 6991a27..4828710 100644 --- a/lib/cocoapods-embed-flutter/src/pub.rb +++ b/lib/cocoapods-embed-flutter/src/pub.rb @@ -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