def execute_seedfile
      @current_target_name = nil

      # Sets `@swift_seedname_prefix` as `true`.
      #
      # @!scope method
      # @!visibility private
      #
      def swift_seedname_prefix!()
        @swift_seedname_prefix = true
      end

      # Set current Xcode project with given path.
      #
      # @!scope method
      # @!visibility private
      #
      def xcodeproj(path)
        proejct_filename = File.join(self.root_path, path)
        self.project = Xcodeproj::Project.open(proejct_filename)
        self.validate_project
      end

      # Sets `@current_target_name` and executes code block.
      #
      # @param [String] names The name of target.
      #
      # @!scope method
      # @!visibility private
      #
      def target(*names, &code)
        self.validate_project
        names.each do |name|
          name = name.to_s  # use string instead of symbol
          target = self.project.target_named(name)
          if not target
            raise Seeds::Exception.new\
              "#{self.project.path.basename} doesn't have a target `#{name}`"
          end

          @current_target_name = name
          code.call()
        end
        @current_target_name = nil
      end

      def local(name, source_dir, options={})
        self.validate_project
        if not @current_target_name
          target *self.project.targets.map(&:name) do
            send(__callee__, name, source_dir, options)
          end
        else
          seed = Seeds::Seed::LocalSeed.new
          if not name
            raise Seeds::Exception.new\
            "Need a name to identifier."
          else
            seed.name = name
          end

          if not source_dir
            raise Seeds::Exception.new\
            "Need a source dir."
          else
            seed.source_dir = source_dir
          end

          seed.files = options[:files] ||  '**/*.{h,m,mm,swift}'
          if seed.files.kind_of? String
            seed.files = [seed.files]
          end
          seed.exclude_files = options[:exclude_files] || []
          self.seeds[seed.name] = seed
          self.targets[seed.name] ||= []
          self.targets[seed.name] << @current_target_name.to_s
        end
      end
      # Creates a new instance of {#Seeds::Seed::GitHub} and adds to {#seeds}.
      #
      # @see #Seeds::Seed::GitHub
      #
      # @!scope method
      # @!visibility private
      #
      def github(repo, tag, options={})
        self.validate_project
        if not @current_target_name  # apply to all targets
          target *self.project.targets.map(&:name) do
            send(__callee__, repo, tag, options)
          end
        elsif repo.split('/').count != 2
          raise Seeds::Exception.new\
          "#{repo}: GitHub should have both username and repo name.\n"\
          "    (e.g. `devxoul/JLToast`)"
        else
          seed = Seeds::Seed::GitHub.new
          seed.url = "https://github.com/#{repo}"
          seed.name = repo.split('/')[1]
          if tag.is_a?(String)
            if options[:commit]
              raise Seeds::Exception.new\
                "#{repo}: Version and commit are both specified."
            end
            seed.version = tag
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          elsif tag.is_a?(Hash)
            options.merge!(tag)
            seed.commit = options[:commit][0..6]
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          end
          if seed.files.kind_of?(String)
            seed.files = [seed.files]
          end
          if seed.exclude_files.kind_of?(String)
            seed.exclude_files = [seed.exclude_files]
          end
          self.seeds[seed.name] = seed
          self.targets[seed.name] ||= []
          self.targets[seed.name] << @current_target_name.to_s
        end
      end

      # Creates a new instance of {#Seeds::Seed::BitBucket} and adds to
      # {#seeds}.
      #
      # @see #Seeds::Seed::BitBucket
      #
      # @!scope method
      # @!visibility private
      #
      def bitbucket(repo, tag, options={})
        self.validate_project
        if not @current_target_name  # apply to all targets
          target *self.project.targets.map(&:name) do
            send(__callee__, repo, tag, options)
          end
        elsif repo.split('/').count != 2
          raise Seeds::Exception.new\
          "#{repo}: BitBucket should have both username and repo name.\n"\
          "    (e.g. `devxoul/JLToast`)"
        else
          seed = Seeds::Seed::BitBucket.new
          seed.url = "https://bitbucket.org/#{repo}"
          seed.name = repo.split('/')[1]
          if tag.is_a?(String)
            if options[:commit]
              raise Seeds::Exception.new\
                "#{repo}: Version and commit are both specified."
            end
            seed.version = tag
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          elsif tag.is_a?(Hash)
            options.merge!(tag)
            seed.commit = options[:commit][0..6]
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          end
          if seed.files.kind_of?(String)
            seed.files = [seed.files]
          end
          if seed.exclude_files.kind_of?(String)
            seed.exclude_files = [seed.exclude_files]
          end
          self.seeds[seed.name] = seed
          self.targets[seed.name] ||= []
          self.targets[seed.name] << @current_target_name.to_s
        end
      end

      def git(repo, tag, options={})
        self.validate_project
        if not @current_target_name
          target *self.project.targets.map(&:name) do
            send(__callee__, repo, tag, options)
          end
        elsif not repo.end_with? ".git"
          raise Seeds::Exception.new\
          "#{repo}: is not a valid git repo.\n"
        else
          seed = Seeds::Seed::CustomSeed.new
          seed.url = repo
          seed.name = repo.split('/').last.sub /.git$/, ''
          if tag.is_a? String
            if options[:commit]
              raise Seeds::Exception.new\
              "#{repo}: Version and commit are both specified."
            end
            seed.version = tag
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          elsif tag.is_a? Hash
            seed.commit = tag[:commit][0..6]
            seed.files = tag[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          end
          if seed.files.kind_of? String
            seed.files = [seed.files]
          end
          if seed.exclude_files.kind_of? String
            seed.exclude_files = [seed.exclude_files]
          end
          self.seeds[seed.name] = seed
          self.targets[seed.name] ||= []
          self.targets[seed.name] << @current_target_name.to_s
        end
      end

      eval seedfile
    end
def execute_seedfile
      @current_target_name = nil

      # Sets `@swift_seedname_prefix` as `true`.
      #
      # @!scope method
      # @!visibility private
      #
      def swift_seedname_prefix!()
        @swift_seedname_prefix = true
      end

      # Set current Xcode project with given path.
      #
      # @!scope method
      # @!visibility private
      #
      def xcodeproj(path)
        proejct_filename = File.join(self.root_path, path)
        self.project = Xcodeproj::Project.open(proejct_filename)
        self.validate_project
      end

      # Sets `@current_target_name` and executes code block.
      #
      # @param [String] names The name of target.
      #
      # @!scope method
      # @!visibility private
      #
      def target(*names, &code)
        self.validate_project
        names.each do |name|
          name = name.to_s  # use string instead of symbol
          target = self.project.target_named(name)
          if not target
            raise Seeds::Exception.new\
              "#{self.project.path.basename} doesn't have a target `#{name}`"
          end

          @current_target_name = name
          code.call()
        end
        @current_target_name = nil
      end

      def local(name, source_dir, options={})
        self.validate_project
        if not @current_target_name
          target *self.project.targets.map(&:name) do
            send(__callee__, name, source_dir, options)
          end
        else
          seed = Seeds::Seed::LocalSeed.new
          if not name
            raise Seeds::Exception.new\
            "Need a name to identifier."
          else
            seed.name = name
          end

          if not source_dir
            raise Seeds::Exception.new\
            "Need a source dir."
          else
            seed.source_dir = source_dir
          end

          seed.files = options[:files] ||  '**/*.{h,m,mm,swift}'
          if seed.files.kind_of? String
            seed.files = [seed.files]
          end
          seed.exclude_files = options[:exclude_files] || []
          self.seeds[seed.name] = seed
          self.targets[seed.name] ||= []
          self.targets[seed.name] << @current_target_name.to_s
        end
      end
      # Creates a new instance of {#Seeds::Seed::GitHub} and adds to {#seeds}.
      #
      # @see #Seeds::Seed::GitHub
      #
      # @!scope method
      # @!visibility private
      #
      def github(repo, tag, options={})
        self.validate_project
        if not @current_target_name  # apply to all targets
          target *self.project.targets.map(&:name) do
            send(__callee__, repo, tag, options)
          end
        elsif repo.split('/').count != 2
          raise Seeds::Exception.new\
          "#{repo}: GitHub should have both username and repo name.\n"\
          "    (e.g. `devxoul/JLToast`)"
        else
          seed = Seeds::Seed::GitHub.new
          seed.url = "https://github.com/#{repo}"
          seed.name = repo.split('/')[1]
          if tag.is_a?(String)
            if options[:commit]
              raise Seeds::Exception.new\
                "#{repo}: Version and commit are both specified."
            end
            seed.version = tag
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          elsif tag.is_a?(Hash)
            options.merge!(tag)
            seed.commit = options[:commit][0..6]
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          end
          if seed.files.kind_of?(String)
            seed.files = [seed.files]
          end
          if seed.exclude_files.kind_of?(String)
            seed.exclude_files = [seed.exclude_files]
          end
          self.seeds[seed.name] = seed
          self.targets[seed.name] ||= []
          self.targets[seed.name] << @current_target_name.to_s
        end
      end

      # Creates a new instance of {#Seeds::Seed::BitBucket} and adds to
      # {#seeds}.
      #
      # @see #Seeds::Seed::BitBucket
      #
      # @!scope method
      # @!visibility private
      #
      def bitbucket(repo, tag, options={})
        self.validate_project
        if not @current_target_name  # apply to all targets
          target *self.project.targets.map(&:name) do
            send(__callee__, repo, tag, options)
          end
        elsif repo.split('/').count != 2
          raise Seeds::Exception.new\
          "#{repo}: BitBucket should have both username and repo name.\n"\
          "    (e.g. `devxoul/JLToast`)"
        else
          seed = Seeds::Seed::BitBucket.new
          seed.url = "https://bitbucket.org/#{repo}"
          seed.name = repo.split('/')[1]
          if tag.is_a?(String)
            if options[:commit]
              raise Seeds::Exception.new\
                "#{repo}: Version and commit are both specified."
            end
            seed.version = tag
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          elsif tag.is_a?(Hash)
            options.merge!(tag)
            seed.commit = options[:commit][0..6]
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          end
          if seed.files.kind_of?(String)
            seed.files = [seed.files]
          end
          if seed.exclude_files.kind_of?(String)
            seed.exclude_files = [seed.exclude_files]
          end
          self.seeds[seed.name] = seed
          self.targets[seed.name] ||= []
          self.targets[seed.name] << @current_target_name.to_s
        end
      end

      def git(repo, tag, options={})
        self.validate_project
        if not @current_target_name
          target *self.project.targets.map(&:name) do
            send(__callee__, repo, tag, options)
          end
        elsif not repo.end_with? ".git"
          raise Seeds::Exception.new\
          "#{repo}: is not a valid git repo.\n"
        else
          seed = Seeds::Seed::CustomSeed.new
          seed.url = repo
          seed.name = repo.split('/').last.sub /.git$/, ''
          if tag.is_a? String
            if options[:commit]
              raise Seeds::Exception.new\
              "#{repo}: Version and commit are both specified."
            end
            seed.version = tag
            seed.files = options[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          elsif tag.is_a? Hash
            seed.commit = tag[:commit][0..6]
            seed.files = tag[:files] || '**/*.{h,m,mm,swift}'
            seed.exclude_files = options[:exclude_files] || []
          end
          if seed.files.kind_of? String
            seed.files = [seed.files]
          end
          if seed.exclude_files.kind_of? String
            seed.exclude_files = [seed.exclude_files]
          end
          self.seeds[seed.name] = seed
          self.targets[seed.name] ||= []
          self.targets[seed.name] << @current_target_name.to_s
        end
      end

      eval seedfile
    end
Executes {#seedfile} using `eval`

 @!visibility private