2016-08-29 00:04:48 +02:00
// Copyright 2016 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.
2020-01-24 22:05:04 +01:00
import ' dart:convert ' ;
import ' dart:io ' ;
import ' package:charcode/charcode.dart ' ;
import ' package:cli_pkg/cli_pkg.dart ' as pkg ;
2016-08-29 00:04:48 +02:00
import ' package:grinder/grinder.dart ' ;
2020-01-24 22:05:04 +01:00
import ' package:path/path.dart ' as p ;
import ' package:source_span/source_span.dart ' ;
2017-10-12 21:22:01 +02:00
2018-05-04 02:37:25 +02:00
import ' grind/synchronize.dart ' ;
2021-12-03 00:01:14 +01:00
import ' grind/utils.dart ' ;
2016-10-15 00:48:34 +02:00
2020-02-25 23:05:01 +01:00
export ' grind/bazel.dart ' ;
2018-06-15 20:29:42 +02:00
export ' grind/benchmark.dart ' ;
2021-09-22 01:22:13 +02:00
export ' grind/double_check.dart ' ;
2021-09-18 01:17:41 +02:00
export ' grind/frameworks.dart ' ;
2021-07-29 03:28:00 +02:00
export ' grind/subpackages.dart ' ;
2018-05-04 02:37:25 +02:00
export ' grind/synchronize.dart ' ;
2018-02-02 03:54:42 +01:00
2020-01-24 22:05:04 +01:00
void main ( List < String > args ) {
2020-10-14 02:37:22 +02:00
pkg . humanName . value = " Dart Sass " ;
pkg . botName . value = " Sass Bot " ;
pkg . botEmail . value = " sass.bot.beep.boop@gmail.com " ;
pkg . executables . value = { " sass " : " bin/sass.dart " } ;
pkg . chocolateyNuspec . value = _nuspec ;
pkg . homebrewRepo . value = " sass/homebrew-sass " ;
2023-06-08 02:15:18 +02:00
pkg . homebrewFormula . value = " Formula/sass.rb " ;
2021-10-12 21:15:56 +02:00
pkg . jsRequires . value = [
2023-05-19 22:22:44 +02:00
pkg . JSRequire ( " immutable " , target: pkg . JSRequireTarget . all ) ,
2021-10-12 21:15:56 +02:00
pkg . JSRequire ( " chokidar " , target: pkg . JSRequireTarget . cli ) ,
2021-11-30 01:10:47 +01:00
pkg . JSRequire ( " readline " , target: pkg . JSRequireTarget . cli ) ,
2023-05-19 22:22:44 +02:00
pkg . JSRequire ( " fs " , target: pkg . JSRequireTarget . node ) ,
pkg . JSRequire ( " stream " , target: pkg . JSRequireTarget . node ) ,
pkg . JSRequire ( " util " , target: pkg . JSRequireTarget . node ) ,
2021-10-12 21:15:56 +02:00
] ;
2023-07-21 23:36:12 +02:00
pkg . jsModuleMainLibrary . value = " lib/src/js.dart " ;
2020-10-14 02:37:22 +02:00
pkg . npmPackageJson . fn = ( ) = >
2020-01-24 22:05:04 +01:00
json . decode ( File ( " package/package.json " ) . readAsStringSync ( ) )
2021-03-17 04:51:32 +01:00
as Map < String , dynamic > ;
2020-10-14 02:37:22 +02:00
pkg . npmReadme . fn = ( ) = > _readAndResolveMarkdown ( " package/README.npm.md " ) ;
2021-12-03 00:01:14 +01:00
pkg . npmAdditionalFiles . fn = _fetchJSTypes ;
2020-10-14 02:37:22 +02:00
pkg . standaloneName . value = " dart-sass " ;
2021-09-18 01:17:41 +02:00
pkg . githubUser . fn = ( ) = > Platform . environment [ " GH_USER " ] ;
pkg . githubPassword . fn = ( ) = > Platform . environment [ " GH_TOKEN " ] ;
2023-05-19 22:22:44 +02:00
pkg . jsEsmExports . value = {
' compile ' ,
' compileAsync ' ,
' compileString ' ,
' compileStringAsync ' ,
' Logger ' ,
' SassArgumentList ' ,
' SassBoolean ' ,
2023-07-19 23:36:22 +02:00
' SassCalculation ' ,
' CalculationOperation ' ,
' CalculationInterpolation ' ,
2023-05-19 22:22:44 +02:00
' SassColor ' ,
' SassFunction ' ,
' SassList ' ,
' SassMap ' ,
' SassNumber ' ,
' SassString ' ,
' Value ' ,
' CustomFunction ' ,
' ListSeparator ' ,
' sassFalse ' ,
' sassNull ' ,
' sassTrue ' ,
' Exception ' ,
' PromiseOr ' ,
' info ' ,
' render ' ,
' renderSync ' ,
2023-06-13 23:23:23 +02:00
' TRUE ' ,
' FALSE ' ,
' NULL ' ,
' types ' ,
2023-05-19 22:22:44 +02:00
} ;
2020-01-24 22:05:04 +01:00
2020-10-14 02:37:22 +02:00
pkg . githubReleaseNotes . fn = ( ) = >
" To install Sass ${ pkg . version } , download one of the packages below "
" and [add it to your PATH][], or see [the Sass website][] for full "
" installation instructions. \n "
" \n "
" [add it to your PATH]: https://katiek2.github.io/path-doc/ \n "
" [the Sass website]: https://sass-lang.com/install \n "
" \n "
" # Changes \n "
" \n "
2020-10-29 21:43:27 +01:00
" ${ pkg . githubReleaseNotes . defaultValue } " ;
2020-03-09 20:17:09 +01:00
2023-05-10 22:57:32 +02:00
pkg . environmentConstants . fn = ( ) {
2023-05-17 22:12:44 +02:00
if ( ! Directory ( ' build/language ' ) . existsSync ( ) ) {
2023-05-10 22:57:32 +02:00
fail ( ' Run `dart run grinder protobuf` before building Dart Sass '
' executables. ' ) ;
}
2021-06-14 21:51:01 +02:00
2023-05-10 22:57:32 +02:00
return {
. . . pkg . environmentConstants . defaultValue ,
2023-05-17 22:12:44 +02:00
" protocol-version " : File ( ' build/language/spec/EMBEDDED_PROTOCOL_VERSION ' )
. readAsStringSync ( )
. trim ( ) ,
2023-05-10 22:57:32 +02:00
" compiler-version " : pkg . pubspec . version ! . toString ( ) ,
} ;
} ;
2020-01-24 22:05:04 +01:00
pkg . addAllTasks ( ) ;
2023-06-14 00:28:49 +02:00
afterTask ( " pkg-npm-dev " , _addDefaultExport ) ;
afterTask ( " pkg-npm-release " , _addDefaultExport ) ;
2020-01-24 22:05:04 +01:00
grind ( args ) ;
}
2016-08-29 00:04:48 +02:00
2017-11-20 23:30:42 +01:00
@ DefaultTask ( ' Compile async code and reformat. ' )
2017-12-01 23:20:49 +01:00
@ Depends ( format , synchronize )
2019-11-06 01:28:26 +01:00
void all ( ) { }
2017-11-20 23:30:42 +01:00
@ Task ( ' Run the Dart formatter. ' )
2019-11-06 01:28:26 +01:00
void format ( ) {
2023-08-02 02:34:45 +02:00
run ( ' dart ' , arguments: [ ' format ' , ' --fix ' , ' . ' ] ) ;
2016-08-29 00:04:48 +02:00
}
2016-10-05 10:04:51 +02:00
2017-12-01 23:20:49 +01:00
@ Task ( ' Installs dependencies from npm. ' )
2020-09-08 18:23:46 +02:00
void npmInstall ( ) = >
run ( Platform . isWindows ? " npm.cmd " : " npm " , arguments: [ " install " ] ) ;
2017-12-01 23:20:49 +01:00
@ Task ( ' Runs the tasks that are required for running tests. ' )
2023-05-10 22:57:32 +02:00
@ Depends ( format , synchronize , protobuf , " pkg-npm-dev " , npmInstall ,
" pkg-standalone-dev " )
2019-11-06 01:28:26 +01:00
void beforeTest ( ) { }
2020-01-24 22:05:04 +01:00
String get _nuspec = > """
< ? xml version = " 1.0 " ? >
< package xmlns = " http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd " >
< metadata >
< id > sass < / id >
< title > Sass < / title >
< authors > Natalie Weizenbaum < / authors >
< owners > nex3 < / owners >
< projectUrl > https: //github.com/sass/dart-sass</projectUrl>
2020-02-07 22:05:21 +01:00
< licenseUrl > https: //github.com/sass/dart-sass/blob/${pkg.version}/LICENSE</licenseUrl>
2020-01-24 22:05:04 +01:00
< iconUrl > https: //cdn.rawgit.com/sass/sass-site/f99ee33e4f688e244c7a5902c59d61f78daccc55/source/assets/img/logos/logo-seal.png</iconUrl>
< bugTrackerUrl > https: //github.com/sass/dart-sass/issues</bugTrackerUrl>
< description > * * 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 . < / description >
< summary > Sass makes CSS fun again . < / summary >
< tags > css preprocessor style sass < / tags >
< copyright > Copyright $ { DateTime . now ( ) . year } Google , Inc . < / copyright >
< / metadata >
< / package >
""" ;
final _readAndResolveRegExp = RegExp (
r"^<!-- +#include +([^\s]+) +"
' "([^" \n ]+)" '
r" +-->$" ,
multiLine: true ) ;
/// Reads a Markdown file from [path] and resolves include directives.
///
/// Include directives have the syntax `"<!-- #include" PATH HEADER "-->"`,
/// which must appear on its own line. PATH is a relative file: URL to another
/// Markdown file, and HEADER is the name of a header in that file whose
/// contents should be included as-is.
String _readAndResolveMarkdown ( String path ) = > File ( path )
. readAsStringSync ( )
. replaceAllMapped ( _readAndResolveRegExp , ( match ) {
2021-03-17 03:25:39 +01:00
late String included ;
2020-01-24 22:05:04 +01:00
try {
included = File ( p . join ( p . dirname ( path ) , p . fromUri ( match [ 1 ] ) ) )
. readAsStringSync ( ) ;
} catch ( error ) {
_matchError ( match , error . toString ( ) , url: p . toUri ( path ) ) ;
}
2021-03-17 03:25:39 +01:00
late Match headerMatch ;
2020-01-24 22:05:04 +01:00
try {
headerMatch = " # ${ match [ 2 ] } " . allMatches ( included ) . first ;
} on StateError {
_matchError ( match , " Could not find header. " , url: p . toUri ( path ) ) ;
}
var headerLevel = 0 ;
var index = headerMatch . start ;
while ( index > = 0 & & included . codeUnitAt ( index ) = = $hash ) {
headerLevel + + ;
index - - ;
}
// The section goes until the next header of the same level, or the end
// of the document.
var sectionEnd = included . indexOf ( " # " * headerLevel , headerMatch . end ) ;
if ( sectionEnd = = - 1 ) sectionEnd = included . length ;
return included . substring ( headerMatch . end , sectionEnd ) . trim ( ) ;
} ) ;
2021-12-03 00:01:14 +01:00
/// Returns a map from JS type declaration file names to their contnets.
Map < String , String > _fetchJSTypes ( ) {
var languageRepo =
cloneOrCheckout ( " https://github.com/sass/sass " , " main " , name: ' language ' ) ;
var typeRoot = p . join ( languageRepo , ' js-api-doc ' ) ;
return {
for ( var entry in Directory ( typeRoot ) . listSync ( recursive: true ) )
if ( entry is File & & entry . path . endsWith ( ' .d.ts ' ) )
p . join ( ' types ' , p . relative ( entry . path , from: typeRoot ) ) :
entry . readAsStringSync ( )
} ;
}
2020-01-24 22:05:04 +01:00
/// Throws a nice [SourceSpanException] associated with [match].
2021-03-17 03:25:39 +01:00
void _matchError ( Match match , String message , { Object ? url } ) {
2020-01-24 22:05:04 +01:00
var file = SourceFile . fromString ( match . input , url: url ) ;
throw SourceSpanException ( message , file . span ( match . start , match . end ) ) ;
}
2021-06-14 21:51:01 +02:00
2019-10-17 01:25:37 +02:00
@ Task ( ' Compile the protocol buffer definition to a Dart library. ' )
2022-01-26 02:16:17 +01:00
Future < void > protobuf ( ) async {
2019-10-17 01:25:37 +02:00
Directory ( ' build ' ) . createSync ( recursive: true ) ;
// Make sure we use the version of protoc_plugin defined by our pubspec,
// rather than whatever version the developer might have globally installed.
log ( " Writing protoc-gen-dart " ) ;
if ( Platform . isWindows ) {
File ( ' build/protoc-gen-dart.bat ' ) . writeAsStringSync ( '''
@ echo off
2023-02-09 02:30:05 +01:00
dart run protoc_plugin % *
2019-10-17 01:25:37 +02:00
''' );
} else {
2023-02-09 02:30:05 +01:00
File ( ' build/protoc-gen-dart ' ) . writeAsStringSync ( '''
#!/bin/sh
dart run protoc_plugin " \$ @ "
''' );
2019-11-05 04:50:50 +01:00
run ( ' chmod ' , arguments: [ ' a+x ' , ' build/protoc-gen-dart ' ] ) ;
2019-10-17 01:25:37 +02:00
}
2022-01-25 03:29:11 +01:00
if ( Platform . environment [ ' UPDATE_SASS_PROTOCOL ' ] ! = ' false ' ) {
2023-05-17 22:12:44 +02:00
cloneOrCheckout ( " https://github.com/sass/sass.git " , " main " ,
name: ' language ' ) ;
2022-01-25 03:29:11 +01:00
}
2023-02-09 02:30:05 +01:00
await runAsync ( " buf " ,
arguments: [ " generate " ] ,
2019-10-17 01:25:37 +02:00
runOptions: RunOptions ( environment: {
" PATH " : ' build ' +
( Platform . isWindows ? " ; " : " : " ) +
2021-05-18 05:57:37 +02:00
Platform . environment [ " PATH " ] !
2019-10-17 01:25:37 +02:00
} ) ) ;
}
2023-06-14 00:28:49 +02:00
/// After building the NPM package, add default exports to
/// `build/npm/sass.node.mjs`.
///
/// See sass/dart-sass#2008.
void _addDefaultExport ( ) {
var buffer = StringBuffer ( ) ;
buffer . writeln ( File ( " build/npm/sass.node.mjs " ) . readAsStringSync ( ) ) ;
buffer . writeln ( """
let printedDefaultExportDeprecation = false ;
function defaultExportDeprecation ( ) {
if ( printedDefaultExportDeprecation ) return ;
printedDefaultExportDeprecation = true ;
console . error (
" `import sass from 'sass'` is deprecated. \\ n " +
" Please use `import * as sass from 'sass'` instead. " ) ;
}
""" );
buffer . writeln ( " export default { " ) ;
for ( var export in pkg . jsEsmExports . value ! ) {
buffer . write ( """
get $export ( ) {
defaultExportDeprecation ( ) ;
2023-06-21 22:30:11 +02:00
return cjs . $export ;
2023-06-14 00:28:49 +02:00
} ,
""" );
}
buffer . writeln ( " }; " ) ;
File ( " build/npm/sass.node.mjs " ) . writeAsStringSync ( buffer . toString ( ) ) ;
}