dart-sass/tool/grind/chocolatey.dart
2018-12-06 17:08:59 -08:00

169 lines
6.5 KiB
Dart

// Copyright 2018 Google Inc. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'dart:io';
import 'package:archive/archive.dart';
import 'package:grinder/grinder.dart';
import 'package:http/http.dart' as http;
import 'package:xml/xml.dart' as xml;
import 'standalone.dart';
import 'utils.dart';
@Task('Build a Chocolatey package.')
@Depends(snapshot)
chocolateyPackage() {
ensureBuild();
var nuspec = _nuspec();
var archive = Archive()
..addFile(fileFromString("sass.nuspec", nuspec.toString()))
..addFile(
file("[Content_Types].xml", "package/chocolatey/[Content_Types].xml"))
..addFile(file("_rels/.rels", "package/chocolatey/rels.xml"))
..addFile(fileFromString(
"package/services/metadata/core-properties/properties.psmdcp",
_nupkgProperties(nuspec)))
..addFile(file("tools/LICENSE", "LICENSE"))
..addFile(file("tools/sass.dart.snapshot", "build/sass.dart.snapshot"))
..addFile(file("tools/chocolateyInstall.ps1",
"package/chocolatey/chocolateyInstall.ps1"))
..addFile(file("tools/chocolateyUninstall.ps1",
"package/chocolatey/chocolateyUninstall.ps1"))
..addFile(fileFromString("tools/sass.bat",
readAndReplaceVersion("package/chocolatey/sass.bat")));
var output = "build/sass.${_chocolateyVersion()}.nupkg";
log("Creating $output...");
File(output).writeAsBytesSync(ZipEncoder().encode(archive));
}
/// Creates a `sass.nuspec` file's contents.
xml.XmlDocument _nuspec() {
String sdkVersion;
if (isDevSdk) {
assert(dartVersion.preRelease[0] == "dev");
assert(dartVersion.preRelease[1] is int);
sdkVersion = "${dartVersion.major}.${dartVersion.minor}."
"${dartVersion.patch}.${dartVersion.preRelease[1]}-dev-"
"${dartVersion.preRelease[2]}";
} else {
sdkVersion = dartVersion.toString();
}
var builder = xml.XmlBuilder();
builder.processing("xml", 'version="1.0"');
builder.element("package", nest: () {
builder
.namespace("http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd");
builder.element("metadata", nest: () {
builder.element("id", nest: "sass");
builder.element("title", nest: "Sass");
builder.element("version", nest: _chocolateyVersion());
builder.element("authors", nest: "Natalie Weizenbaum");
builder.element("owners", nest: "nex3");
builder.element("projectUrl", nest: "https://github.com/sass/dart-sass");
builder.element("licenseUrl",
nest: "https://github.com/sass/dart-sass/blob/$version/LICENSE");
builder.element("iconUrl",
nest: "https://cdn.rawgit.com/sass/sass-site/"
"f99ee33e4f688e244c7a5902c59d61f78daccc55/source/assets/img/"
"logos/logo-seal.png");
builder.element("bugTrackerUrl",
nest: "https://github.com/sass/dart-sass/issues");
builder.element("description", nest: """
**Sass makes CSS fun again**. Sass is an extension of CSS, adding nested rules, variables, mixins, selector inheritance, and more. It's translated to well-formatted, standard CSS using the command line tool or a web-framework plugin.
This package is Dart Sass, the new Dart implementation of Sass.
""");
builder.element("summary", nest: "Sass makes CSS fun again.");
builder.element("tags", nest: "css preprocessor style sass");
builder.element("copyright",
nest: "Copyright ${DateTime.now().year} Google, Inc.");
builder.element("dependencies", nest: () {
builder.element("dependency", attributes: {
"id": "dart-sdk",
// Unfortunately we need the exact same Dart version as we built with,
// since we ship a snapshot which isn't cross-version compatible. Once
// we switch to native compilation this won't be an issue.
"version": "[$sdkVersion]",
});
});
});
});
return builder.build() as xml.XmlDocument;
}
@Task('Upload the Chocolatey package to the current version.')
@Depends(chocolateyPackage)
updateChocolatey() async {
// For some reason, although Chrome seems able to access it just fine,
// command-line tools don't seem to be able to verify the certificate for
// Chocolatey, so we need to manually add the intermediate GoDaddy certificate
// to the security context.
SecurityContext.defaultContext.setTrustedCertificates("tool/godaddy.pem");
var request = http.MultipartRequest(
"PUT", Uri.parse("https://chocolatey.org/api/v2/package"));
request.headers["X-NuGet-Protocol-Version"] = "4.1.0";
request.headers["X-NuGet-ApiKey"] = environment("CHOCO_TOKEN");
request.files.add(await http.MultipartFile.fromPath(
"package", "build/sass.${_chocolateyVersion()}.nupkg"));
var response = await request.send();
if (response.statusCode ~/ 100 != 2) {
fail("${response.statusCode} error creating release:\n"
"${await response.stream.bytesToString()}");
} else {
log("Released Dart Sass ${_chocolateyVersion()} to Chocolatey.");
response.stream.listen(null).cancel();
}
}
/// The current Sass version, formatted for Chocolatey which doesn't allow dots
/// in prerelease versions.
String _chocolateyVersion() {
var components = version.split("-");
if (components.length == 1) return components.first;
assert(components.length == 2);
var first = true;
var prerelease = components.last.replaceAllMapped('.', (_) {
if (first) {
first = false;
return '';
} else {
return '-';
}
});
return "${components.first}-$prerelease";
}
/// Returns the contents of the `properties.psmdcp` file, computed from the
/// nuspec's XML.
String _nupkgProperties(xml.XmlDocument nuspec) {
var builder = xml.XmlBuilder();
builder.processing("xml", 'version="1.0"');
builder.element("coreProperties", nest: () {
builder.namespace(
"http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
builder.namespace("http://purl.org/dc/elements/1.1/", "dc");
builder.element("dc:creator",
nest: nuspec.findAllElements("authors").first.text);
builder.element("dc:description",
nest: nuspec.findAllElements("description").first.text);
builder.element("dc:identifier",
nest: nuspec.findAllElements("id").first.text);
builder.element("version",
nest: nuspec.findAllElements("version").first.text);
builder.element("keywords",
nest: nuspec.findAllElements("tags").first.text);
builder.element("dc:title",
nest: nuspec.findAllElements("title").first.text);
});
return builder.build().toString();
}