diff --git a/lib/datasource/dart/index.js b/lib/datasource/dart/index.js new file mode 100644 index 0000000000000000000000000000000000000000..40e5ce04de64590f96e266b4241ea6cf433c66bf --- /dev/null +++ b/lib/datasource/dart/index.js @@ -0,0 +1,57 @@ +const got = require('../../util/got'); + +async function getPkgReleases({ lookupName }) { + let result = null; + const pkgUrl = `https://pub.dartlang.org/api/packages/${lookupName}`; + let raw = null; + try { + raw = await got(pkgUrl, { + json: true, + }); + } catch (err) { + if (err.statusCode === 404 || err.code === 'ENOTFOUND') { + logger.info({ lookupName }, `Dependency lookup failure: not found`); + logger.debug({ err }, 'Dart lookup error'); + return null; + } + if ( + err.statusCode === 429 || + (err.statusCode > 500 && err.statusCode < 600) + ) { + logger.warn({ lookupName, err }, `pub.dartlang.org registry failure`); + throw new Error('registry-failure'); + } + logger.warn( + { err, lookupName }, + 'pub.dartlang.org lookup failure: Unknown error' + ); + return null; + } + + const body = raw && raw.body; + if (body) { + const { versions, latest } = body; + if (versions && latest) { + result = { + releases: body.versions.map(({ version }) => ({ version })), + }; + + const pubspec = latest.pubspec; + if (pubspec) { + if (pubspec.homepage) { + result.homepage = pubspec.homepage; + } + + if (pubspec.repository) { + result.sourceUrl = pubspec.repository; + } + } + } + } + + return result; +} + +module.exports = { + getPkgReleases, +}; diff --git a/lib/datasource/index.js b/lib/datasource/index.js index 403cbb85e84572f691aa6f408dec7c4d7e88dd18..c874c964d8dc9d87c22ea3d61cb2a1c38e4aefd0 100644 --- a/lib/datasource/index.js +++ b/lib/datasource/index.js @@ -2,6 +2,7 @@ const { addMetaData } = require('./metadata'); const versioning = require('../versioning'); const cargo = require('./cargo'); +const dart = require('./dart'); const docker = require('./docker'); const hex = require('./hex'); const github = require('./github'); @@ -20,6 +21,7 @@ const terraform = require('./terraform'); const datasources = { cargo, + dart, docker, hex, github, diff --git a/test/datasource/__snapshots__/dart.spec.js.snap b/test/datasource/__snapshots__/dart.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..198c90be543326bed79d1d06654df93a2af94e04 --- /dev/null +++ b/test/datasource/__snapshots__/dart.spec.js.snap @@ -0,0 +1,63 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`datasource/dart getPkgReleases processes real data 1`] = ` +Object { + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "releases": Array [ + Object { + "version": "0.1.1", + }, + Object { + "version": "0.2.0", + }, + Object { + "version": "0.2.0+1", + }, + Object { + "version": "0.2.3", + }, + Object { + "version": "0.2.4", + }, + Object { + "version": "0.2.4+1", + }, + Object { + "version": "0.2.5", + }, + Object { + "version": "0.3.0", + }, + Object { + "version": "0.3.1", + }, + Object { + "version": "0.3.2", + }, + Object { + "version": "0.3.3", + }, + Object { + "version": "0.4.0", + }, + Object { + "version": "0.4.1", + }, + Object { + "version": "0.4.2", + }, + Object { + "version": "0.4.3", + }, + Object { + "version": "0.5.0", + }, + Object { + "version": "0.5.1+1", + }, + ], + "sourceUrl": "http://example.com", +} +`; + +exports[`datasource/dart getPkgReleases throws for 5xx 1`] = `[Error: registry-failure]`; diff --git a/test/datasource/dart.spec.js b/test/datasource/dart.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..37a73f825a91e0e48c6470dc4d5f41292f80e24f --- /dev/null +++ b/test/datasource/dart.spec.js @@ -0,0 +1,83 @@ +const fs = require('fs'); +const got = require('../../lib/util/got'); +const { getPkgReleases } = require('../../lib/datasource/dart'); + +const body = JSON.parse( + fs.readFileSync( + 'test/datasource/dart/_fixtures/shared_preferences.json', + 'utf8' + ) +); + +jest.mock('../../lib/util/got'); + +describe('datasource/dart', () => { + describe('getPkgReleases', () => { + beforeEach(() => { + global.repoCache = {}; + }); + it('returns null for empty result', async () => { + got.mockReturnValueOnce(null); + expect(await getPkgReleases({ lookupName: 'non_sense' })).toBeNull(); + }); + it('returns null for empty fields', async () => { + const withoutVersions = { + ...body, + versions: undefined, + }; + got.mockReturnValueOnce({ body: withoutVersions }); + expect( + await getPkgReleases({ lookupName: 'shared_preferences' }) + ).toBeNull(); + + const withoutLatest = { + ...body, + latest: undefined, + }; + got.mockReturnValueOnce({ body: withoutLatest }); + expect( + await getPkgReleases({ lookupName: 'shared_preferences' }) + ).toBeNull(); + }); + it('returns null for 404', async () => { + got.mockImplementationOnce(() => + Promise.reject({ + statusCode: 404, + }) + ); + expect( + await getPkgReleases({ lookupName: 'shared_preferences' }) + ).toBeNull(); + }); + it('throws for 5xx', async () => { + got.mockImplementationOnce(() => + Promise.reject({ + statusCode: 502, + }) + ); + let e; + try { + await getPkgReleases({ lookupName: 'shared_preferences' }); + } catch (err) { + e = err; + } + expect(e).toBeDefined(); + expect(e).toMatchSnapshot(); + }); + it('returns null for unknown error', async () => { + got.mockImplementationOnce(() => { + throw new Error(); + }); + expect( + await getPkgReleases({ lookupName: 'shared_preferences' }) + ).toBeNull(); + }); + it('processes real data', async () => { + got.mockReturnValueOnce({ body }); + const res = await getPkgReleases({ + lookupName: 'shared_preferences', + }); + expect(res).toMatchSnapshot(); + }); + }); +}); diff --git a/test/datasource/dart/_fixtures/shared_preferences.json b/test/datasource/dart/_fixtures/shared_preferences.json new file mode 100644 index 0000000000000000000000000000000000000000..ececa50f01cf87c281834827811769260c0a8946 --- /dev/null +++ b/test/datasource/dart/_fixtures/shared_preferences.json @@ -0,0 +1,549 @@ +{ + "name": "shared_preferences", + "latest": { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.5.1%2B1.tar.gz", + "pubspec": { + "version": "0.5.1+1", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "repository": "http://example.com", + "environment": { + "sdk": ">=2.0.0-dev.28.0 <3.0.0", + "flutter": ">=0.1.4 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.5.1+1" + }, + "versions": [ + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.1.1.tar.gz", + "pubspec": { + "version": "0.1.1", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + } + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.shared_preferences", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "A Flutter plugin for reading and writing simple key-value pairs", + "homepage": "https://github.com/flutter/plugins" + }, + "version": "0.1.1" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.2.0.tar.gz", + "pubspec": { + "version": "0.2.0", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + } + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.shared_preferences", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "A Flutter plugin for reading and writing simple key-value pairs", + "homepage": "https://github.com/flutter/plugins" + }, + "version": "0.2.0" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.2.0%2B1.tar.gz", + "pubspec": { + "version": "0.2.0+1", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + } + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.shared_preferences", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "A Flutter plugin for reading and writing simple key-value pairs.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=1.8.0 <2.0.0" + } + }, + "version": "0.2.0+1" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.2.3.tar.gz", + "pubspec": { + "version": "0.2.3", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + } + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.shared_preferences", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "A Flutter plugin for reading and writing simple key-value pairs.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=1.8.0 <2.0.0" + } + }, + "version": "0.2.3" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.2.4.tar.gz", + "pubspec": { + "version": "0.2.4", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "A Flutter plugin for reading and writing simple key-value pairs.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=1.8.0 <2.0.0" + }, + "dev_dependencies": { + "test": "^0.12.20", + "mockito": "^2.0.2" + } + }, + "version": "0.2.4" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.2.4%2B1.tar.gz", + "pubspec": { + "version": "0.2.4+1", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "A Flutter plugin for reading and writing simple key-value pairs.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=1.8.0 <2.0.0" + }, + "dev_dependencies": { + "test": "^0.12.20", + "mockito": "^2.0.2" + } + }, + "version": "0.2.4+1" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.2.5.tar.gz", + "pubspec": { + "version": "0.2.5", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "A Flutter plugin for reading and writing simple key-value pairs.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=1.8.0 <2.0.0" + }, + "dev_dependencies": { + "test": "0.12.21", + "mockito": "^2.0.2" + } + }, + "version": "0.2.5" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.3.0.tar.gz", + "pubspec": { + "version": "0.3.0", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "A Flutter plugin for reading and writing simple key-value pairs.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=1.8.0 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.3.0" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.3.1.tar.gz", + "pubspec": { + "version": "0.3.1", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=1.8.0 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.3.1" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.3.2.tar.gz", + "pubspec": { + "version": "0.3.2", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=1.8.0 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.3.2" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.3.3.tar.gz", + "pubspec": { + "version": "0.3.3", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=1.8.0 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.3.3" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.4.0.tar.gz", + "pubspec": { + "version": "0.4.0", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=2.0.0-dev.28.0 <3.0.0", + "flutter": ">=0.1.4 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.4.0" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.4.1.tar.gz", + "pubspec": { + "version": "0.4.1", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=2.0.0-dev.28.0 <3.0.0", + "flutter": ">=0.1.4 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.4.1" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.4.2.tar.gz", + "pubspec": { + "version": "0.4.2", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=2.0.0-dev.28.0 <3.0.0", + "flutter": ">=0.1.4 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.4.2" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.4.3.tar.gz", + "pubspec": { + "version": "0.4.3", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=2.0.0-dev.28.0 <3.0.0", + "flutter": ">=0.1.4 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.4.3" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.5.0.tar.gz", + "pubspec": { + "version": "0.5.0", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=2.0.0-dev.28.0 <3.0.0", + "flutter": ">=0.1.4 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.5.0" + }, + { + "archive_url": "https://pub.dartlang.org/packages/shared_preferences/versions/0.5.1%2B1.tar.gz", + "pubspec": { + "version": "0.5.1+1", + "name": "shared_preferences", + "dependencies": { + "flutter": { + "sdk": "flutter" + }, + "meta": "^1.0.4" + }, + "author": "Flutter Team <flutter-dev@googlegroups.com>", + "flutter": { + "plugin": { + "androidPackage": "io.flutter.plugins.sharedpreferences", + "iosPrefix": "FLT", + "pluginClass": "SharedPreferencesPlugin" + } + }, + "description": "Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.", + "homepage": "https://github.com/flutter/plugins/tree/master/packages/shared_preferences", + "environment": { + "sdk": ">=2.0.0-dev.28.0 <3.0.0", + "flutter": ">=0.1.4 <2.0.0" + }, + "dev_dependencies": { + "flutter_test": { + "sdk": "flutter" + } + } + }, + "version": "0.5.1+1" + } + ] +}