From 468f32bd8063fcc67a38480fb19c06ef4e89da53 Mon Sep 17 00:00:00 2001 From: Slava Kim Date: Tue, 4 Mar 2014 23:08:38 -0800 Subject: [PATCH] package-version-parser package first version of a package that parses smart package version string --- packages/package-version-parser/.gitignore | 1 + .../.npm/package/.gitignore | 1 + .../.npm/package/README | 7 +++ .../.npm/package/npm-shrinkwrap.json | 7 +++ .../package-version-parser-tests.js | 54 +++++++++++++++++++ .../package-version-parser.js | 39 ++++++++++++++ packages/package-version-parser/package.js | 19 +++++++ 7 files changed, 128 insertions(+) create mode 100644 packages/package-version-parser/.gitignore create mode 100644 packages/package-version-parser/.npm/package/.gitignore create mode 100644 packages/package-version-parser/.npm/package/README create mode 100644 packages/package-version-parser/.npm/package/npm-shrinkwrap.json create mode 100644 packages/package-version-parser/package-version-parser-tests.js create mode 100644 packages/package-version-parser/package-version-parser.js create mode 100644 packages/package-version-parser/package.js diff --git a/packages/package-version-parser/.gitignore b/packages/package-version-parser/.gitignore new file mode 100644 index 0000000000..677a6fc263 --- /dev/null +++ b/packages/package-version-parser/.gitignore @@ -0,0 +1 @@ +.build* diff --git a/packages/package-version-parser/.npm/package/.gitignore b/packages/package-version-parser/.npm/package/.gitignore new file mode 100644 index 0000000000..3c3629e647 --- /dev/null +++ b/packages/package-version-parser/.npm/package/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/packages/package-version-parser/.npm/package/README b/packages/package-version-parser/.npm/package/README new file mode 100644 index 0000000000..3d492553a4 --- /dev/null +++ b/packages/package-version-parser/.npm/package/README @@ -0,0 +1,7 @@ +This directory and the files immediately inside it are automatically generated +when you change this package's NPM dependencies. Commit the files in this +directory (npm-shrinkwrap.json, .gitignore, and this README) to source control +so that others run the same versions of sub-dependencies. + +You should NOT check in the node_modules directory that Meteor automatically +creates; if you are using git, the .gitignore file tells git to ignore it. diff --git a/packages/package-version-parser/.npm/package/npm-shrinkwrap.json b/packages/package-version-parser/.npm/package/npm-shrinkwrap.json new file mode 100644 index 0000000000..c9038d7d6c --- /dev/null +++ b/packages/package-version-parser/.npm/package/npm-shrinkwrap.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "semver": { + "version": "2.2.1" + } + } +} diff --git a/packages/package-version-parser/package-version-parser-tests.js b/packages/package-version-parser/package-version-parser-tests.js new file mode 100644 index 0000000000..ac57d89813 --- /dev/null +++ b/packages/package-version-parser/package-version-parser-tests.js @@ -0,0 +1,54 @@ +var currentTest = null; + +var t = function (versionString, expected, descr) { + currentTest.equal(PackageVersion.parse(versionString), expected, descr); +}; + +var FAIL = function (versionString) { + currentTest.throws(function () { + PackageVersion.parse(versionString); + }); +}; + +Tinytest.add("Smart Package version string parsing - old format", function (test) { + currentTest = test; + + t("foo", { name: "foo", version: null, sticky: false }); + t("foo-1234", { name: "foo-1234", version: null, sticky: false }); + FAIL("my_awesome_InconsitentPackage123"); +}); + +Tinytest.add("Smart Package version string parsing - compatible version", function (test) { + currentTest = test; + + t("foo@1.2.3", { name: "foo", version: "1.2.3", sticky: false }); + t("foo-1233@1.2.3", { name: "foo-1233", version: "1.2.3", sticky: false }); + t("foo-bar@3.2.1", { name: "foo-bar", version: "3.2.1", sticky: false }); + t("42@0.2.0", { name: "42", version: "0.2.0", sticky: false }); + FAIL("foo@1.2.3.4"); + FAIL("foo@1.4"); + FAIL("foo@1"); + FAIL("foo@"); + FAIL("foo@@"); + FAIL("foo@x.y.z"); + FAIL("foo@<1.2"); + FAIL("foo<1.2"); +}); + +Tinytest.add("Smart Package version string parsing - compatible version sticky", function (test) { + currentTest = test; + + t("foo@=1.2.3", { name: "foo", version: "1.2.3", sticky: true }); + t("foo-bar@=3.2.1", { name: "foo-bar", version: "3.2.1", sticky: true }); + t("42@=0.2.0", { name: "42", version: "0.2.0", sticky: true }); + FAIL("foo@=1.2.3.4"); + FAIL("foo@=1.4"); + FAIL("foo@=1"); + FAIL("foo@@="); + FAIL("foo@=@"); + FAIL("foo@=x.y.z"); + FAIL("foo@=<1.2"); + FAIL("foo@<=1.2"); + FAIL("foo<=1.2"); +}); + diff --git a/packages/package-version-parser/package-version-parser.js b/packages/package-version-parser/package-version-parser.js new file mode 100644 index 0000000000..182383d44f --- /dev/null +++ b/packages/package-version-parser/package-version-parser.js @@ -0,0 +1,39 @@ +var semver = Npm.require('semver'); + +PackageVersion = {}; + +PackageVersion.parse = function (versionString) { + if (typeof versionString !== "string") + throw new TypeError("versionString must be a string"); + + var splitted = versionString.split('@'); + + var versionDesc = { name: "", version: null, sticky: false }; + var name = splitted[0]; + var version = splitted[1]; + + if (! /^[a-z0-9-]+$/.test(name) || splitted.length > 2) + throw new Error("Package name must contain lowercase latin letters, digits or dashes"); + + versionDesc.name = name; + + if (splitted.length === 2 && !version) + throw new Error("semver version cannot be empty"); + + if (version) { + if (version.charAt(0) === '=') { + versionDesc.sticky = true; + version = version.substr(1); + } + + // XXX check for a dash in the version in case of foo@1.2.3-rc0 + + if (! semver.valid(version)) + throw new Error(version + " doesn't look like a semver version (e.g. 1.2.0)"); + + versionDesc.version = version; + } + + return versionDesc; +}; + diff --git a/packages/package-version-parser/package.js b/packages/package-version-parser/package.js new file mode 100644 index 0000000000..416d1b6404 --- /dev/null +++ b/packages/package-version-parser/package.js @@ -0,0 +1,19 @@ +Package.describe({ + summary: "Parses Meteor Smart Package version string", + internal: true +}); + +Npm.depends({ + 'semver': '2.2.1' +}); + +Package.on_use(function (api) { + api.export('PackageVersion'); + api.add_files([ 'package-version-parser.js' ], ['client', 'server']); +}); + +Package.on_test(function (api) { + api.use('package-version-parser', ['client', 'server']); + api.use(['tinytest']); + api.add_files('package-version-parser-tests.js', ['client', 'server']); +});