Skip to content

Commit

Permalink
Merge pull request #875 from etiennecadicidean/feature/pub_pm_support
Browse files Browse the repository at this point in the history
Provide new package manager support : Pub for Flutter projects
  • Loading branch information
xtreme-shane-lattanzio authored Feb 23, 2022
2 parents ad1c247 + 3890120 commit 791faf1
Show file tree
Hide file tree
Showing 14 changed files with 511 additions and 1 deletion.
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,25 @@ RUN apt-get -q install -y \
pkg-config \
&& rm -r /var/lib/apt/lists/*

#install flutter
ENV FLUTTER_HOME=/root/flutter
RUN curl -o flutter_linux_2.8.1-stable.tar.xz https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_2.8.1-stable.tar.xz \
&& tar xf flutter_linux_2.8.1-stable.tar.xz \
&& mv flutter ${FLUTTER_HOME} \
&& rm flutter_linux_2.8.1-stable.tar.xz

ENV PATH=$PATH:${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin
RUN flutter doctor -v \
&& flutter update-packages \
&& flutter precache
# Accepting all licences
RUN yes | flutter doctor --android-licenses -v
# Creating Flutter sample projects to put binaries in cache fore each template type
RUN flutter create --template=app ${TEMP}/app_sample \
&& flutter create --template=package ${TEMP}/package_sample \
&& flutter create --template=plugin ${TEMP}/plugin_sample


# pub 4096R/ED3D1561 2019-03-22 [SC] [expires: 2023-03-23]
# Key fingerprint = A62A E125 BBBF BB96 A6E0 42EC 925C C1CC ED3D 1561
# uid Swift 5.x Release Signing Key <swift-infrastructure@swift.org
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ and give you an actionable exception report.
* Go Modules (via `go mod`)
* PHP (via `composer`)
* Python (via Conda [Conda 4.8.3, Python 3.7, Bash; requires an `environment.yml` or `environment.yaml`])
* Flutter (via `flutter pub, requires pubspec.yaml & .pub cache locaton through ENV variable`)

## Installation

Expand Down
16 changes: 16 additions & 0 deletions features/features/package_managers/pub_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

require_relative '../../support/feature_helper'

describe 'Pubspec Dependencies' do
# As a developer on Flutter platform
# I want to be able to manage Pub Package Manager dependencies

let(:flutter_developer) { LicenseFinder::TestingDSL::User.new }

specify 'are shown in reports' do
LicenseFinder::TestingDSL::FlutterProject.create
flutter_developer.run_license_finder
expect(flutter_developer).to be_seeing_line 'device_info, 2.0.3, "New BSD"'
end
end
25 changes: 25 additions & 0 deletions features/fixtures/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: test_app
description: Test app for Flutter license_finder evolution

publish_to: 'none' # Remove this line if you wish to publish to pub.dev

version: 1.0.0+1

environment:
sdk: ">=2.12.0 <3.0.0"

dependencies:
flutter:
sdk: flutter
device_info: ^2.0.3

dev_dependencies:
flutter_test:
sdk: flutter

flutter:
generate: true
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
11 changes: 11 additions & 0 deletions features/support/testing_dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,17 @@ def install
end
end

class FlutterProject < Project
def add_dep
install_fixture('pubspec.yaml')
end

def install
ENV['PUB_CACHE'] = '~/flutter/.pub-cache/'
shell_out('flutter pub get')
end
end

class ConanProject < Project
def add_dep
install_fixture('conanfile.txt')
Expand Down
1 change: 1 addition & 0 deletions lib/license_finder/package.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,4 @@ def log_activation(activation)
require 'license_finder/packages/cargo_package'
require 'license_finder/packages/composer_package'
require 'license_finder/packages/conda_package'
require 'license_finder/packages/pubspec_package'
1 change: 1 addition & 0 deletions lib/license_finder/package_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,6 @@ def log_to_file(prep_cmd, contents)
require 'license_finder/package_managers/cargo'
require 'license_finder/package_managers/composer'
require 'license_finder/package_managers/conda'
require 'license_finder/package_managers/pub'

require 'license_finder/package'
86 changes: 86 additions & 0 deletions lib/license_finder/package_managers/pub.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# frozen_string_literal: true

require 'json'
require 'yaml'

module LicenseFinder
class Pub < PackageManager
class PubError < RuntimeError; end

def current_packages
unless File.exist?('pubspec.lock')
raise PubError, "No checked-out Pub packages found.
Please install your dependencies first."
end

if ENV['PUB_CACHE'].nil? || ENV['PUB_CACHE'].eql?('')
raise PubError, 'While PUB_CACHE environment variable is empty, retrieving package licenses is impossible. Please set the PUB_CACHE env variable (default: ~/.pub)'
end

stdout, _stderr, _status = Cmd.run('flutter pub deps --json')
yaml_deps = JSON.parse(stdout)
yaml_deps['packages'].map do |dependency|
package_name = dependency['name']
subpath = "#{dependency['name']}-#{dependency['version']}"
package_version = dependency['version']

project_repo = dependency['source'] == 'git' ? Pathname("#{ENV['PUB_CACHE']}/git/#{dependency['name']}-*/") : Pathname("#{ENV['PUB_CACHE']}/hosted/pub.dartlang.org/#{subpath}")

homepage = read_repository_home(project_repo)
homepage = "https://pub.dev/packages/#{package_name}" if homepage.nil? || homepage.empty?
PubPackage.new(
package_name,
package_version,
license_text(project_repo),
logger: logger,
install_path: project_repo,
homepage: homepage
)
end
end

def possible_package_paths
[project_path.join('pubspec.lock')]
end

def package_management_command
'flutter'
end

def prepare_command
'flutter pub get'
end

def prepare
prep_cmd = "#{prepare_command} #{production_flag}"
_stdout, stderr, status = Dir.chdir(project_path) { Cmd.run(prep_cmd) }

return if status.success?

log_errors stderr
raise "Prepare command '#{prep_cmd}' failed" unless @prepare_no_fail
end

private

def license_text(subpath)
license_path = license_pattern(subpath).find { |f| File.exist?(f) }
license_path.nil? ? nil : IO.read(license_path)
end

def license_pattern(subpath)
Dir.glob(subpath.join('LICENSE*'), File::FNM_CASEFOLD)
end

def production_flag
return '' if @ignored_groups.nil?

@ignored_groups.include?('devDependencies') ? '' : 'no-'
end

def read_repository_home(project_repo)
package_yaml = project_repo.join('pubspec.yaml')
YAML.load(IO.read(package_yaml))['repository'] if Dir.exist?(project_repo) && File.exist?(package_yaml)
end
end
end
18 changes: 18 additions & 0 deletions lib/license_finder/packages/pubspec_package.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module LicenseFinder
class PubPackage < Package
def initialize(name, version, license_text, options = {})
super(name, version, options)
@license = License.find_by_text(license_text.to_s)
end

def licenses_from_spec
[@license].compact
end

def package_manager
'Pub'
end
end
end
2 changes: 1 addition & 1 deletion lib/license_finder/scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Scanner
PACKAGE_MANAGERS = [
GoModules, GoDep, GoWorkspace, Go15VendorExperiment, Glide, Gvt, Govendor, Trash, Dep, Bundler, NPM, Pip,
Yarn, Bower, Maven, Gradle, CocoaPods, Rebar, Erlangmk, Nuget, Carthage, Mix, Conan, Sbt, Cargo, Dotnet, Composer, Pipenv,
Conda, Spm
Conda, Spm, Pub
].freeze

class << self
Expand Down
168 changes: 168 additions & 0 deletions spec/fixtures/all_pms/pubspec.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
device_info:
dependency: "direct main"
description:
name: device_info
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
device_info_platform_interface:
dependency: transitive
description:
name: device_info_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.10"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.12.13+hotfix.5"
Loading

0 comments on commit 791faf1

Please sign in to comment.