Skip to content

Commit 21bf8ce

Browse files
committed
More changes related to CLI
1 parent e9972e6 commit 21bf8ce

7 files changed

+139
-68
lines changed

bin/dacsslide.dart

+103-62
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,92 @@
11
import 'dart:io';
22
import 'package:resource/resource.dart' show Resource;
3-
import 'dart:convert' show UTF8;
3+
import 'dart:convert' show UTF8, JsonEncoder, JsonDecoder;
44
import 'dart:async';
5+
import 'package:args/command_runner.dart';
6+
import 'package:path/path.dart' as path;
57

6-
7-
abstract class Command {
8-
String get name;
9-
String get help;
10-
Future<int> execute(List<String> arguments);
11-
const Command();
8+
String ask(String prompt,String defaultsTo) {
9+
stdout.write("${prompt} [${defaultsTo}]:");
10+
var result = stdin.readLineSync();
11+
if (result == "") return defaultsTo;
12+
return result;
1213
}
14+
class Config {
15+
String _homePath() {
16+
String os = Platform.operatingSystem;
17+
String home = "";
18+
Map<String, String> envVars = Platform.environment;
19+
if (Platform.isMacOS) {
20+
home = envVars['HOME'];
21+
} else if (Platform.isLinux) {
22+
home = envVars['HOME'];
23+
} else if (Platform.isWindows) {
24+
home = envVars['UserProfile'];
25+
}
26+
return home;
27+
}
28+
Map<String, String> _data={"ghaccount":"github-name","author":"Anonymous","email":"[email protected]"};
29+
bool _modified = false;
30+
31+
String get configFileName => path.join(_homePath(),".dacsslide.json");
32+
33+
Config._() {
34+
35+
var file = new File(configFileName);
36+
if (file.existsSync()) {
37+
_data = new JsonDecoder().convert(file.readAsStringSync());
38+
}
39+
}
40+
static Config _instance;
41+
operator[](String key) => _data[key];
42+
operator[]=(String key, String value) {
43+
if (_data[key]!=value) {
44+
_modified = true;
45+
_data[key] = value;
46+
}
47+
}
48+
void save() {
49+
if (_modified) {
50+
new File(configFileName).writeAsStringSync(new JsonEncoder().convert(_data));
51+
_modified = false;
52+
}
53+
}
54+
55+
factory Config() {
56+
if (_instance==null) _instance = new Config._();
57+
return _instance;
58+
}
1359

14-
class CreationParameter {
15-
final String name;
16-
final String defaultValue;
17-
final String description;
18-
const CreationParameter(this.name, this.defaultValue, this.description);
1960
}
61+
62+
2063
class CreateCommand extends Command {
21-
CreateCommand();
22-
23-
static const List<String> templatableExtensions = const ['.yaml','.html'];
24-
static const List<String> parameters = const [
25-
const CreationParameter("name", "new_presentation", "Presentation name"),
26-
const CreationParameter("title", "Great New Presentation","Presentation title"),
27-
const CreationParameter("ghaccount", "mygithubaccount","GitHub account"),
28-
const CreationParameter("author", "Anonymous","Authour's name"),
29-
const CreationParameter("email", "[email protected]","Author's email"),
30-
];
31-
32-
final Map<String,String> parametersValues = {};
64+
final name = "create";
65+
final description = "Creates new project";
66+
final config = new Config();
67+
68+
CreateCommand() {
69+
argParser
70+
..addOption('title',defaultsTo: "Great New Presentation",help:"Presentation title")
71+
..addOption('ghaccount',help:'GitHub account', defaultsTo: config["ghaccount"] )
72+
..addOption('author',help:"Author's name", defaultsTo: config["author"])
73+
..addOption('email',help:"Author's email", defaultsTo: config["email"]);
74+
}
75+
76+
static const List<String> templatableExtensions = const ['.yaml','.html','.dart'];
77+
3378
RegExp parameterRegExp;
79+
String projectName;
3480

3581
Future<bool> createFile(String fileName) async {
3682

37-
print("Processing ${fileName}");
38-
var file = await (new File(fileName).create(recursive: true));
39-
if (fileName.endsWith(".template")) fileName = fileName.substring(fileName.length-".templat".length);
4083
var fileResource = new Resource("package:dacsslide/template/${fileName}");
84+
if (fileName.endsWith(".template")) fileName = fileName.substring(0,fileName.length-".template".length);
85+
var file = await (new File(path.join(projectName,fileName)).create(recursive: true));
4186
if (templatableExtensions.any( (ext) => fileName.endsWith(ext))) {
42-
print("Processing template ${fileName}");
4387
var content = await fileResource.readAsString(encoding: UTF8);
44-
var _content = content.replaceAllMapped(parameterRegExp, (m) => parametersValues[m.group(0).substring(1)]);
88+
var _content = content.replaceAllMapped(parameterRegExp, (m) => m.group(0)=="\$name"?projectName:argResults[m.group(0).substring(1)]);
4589
if (content != _content) {
46-
//print("Changed:\n ${_content}");
4790
await file.writeAsString(_content);
4891
return true;
4992
}
@@ -52,47 +95,45 @@ class CreateCommand extends Command {
5295
return true;
5396
}
5497

55-
@override
56-
int execute(List<String> arguments) async {
57-
print("Generating project ${arguments.join('-')}");
58-
for (CreationParameter parameter in parameters) {
59-
parametersValues[parameter.name] = parameter.defaultValue;
98+
void _askArgument(String name, String prompt) {
99+
if (!argResults.wasParsed(name)) {
100+
config[name] = ask("Enter ${prompt}",config[name]);
101+
} else {
102+
config[name] = argResults[name];
60103
}
61-
parameterRegExp = new RegExp("\\\$(${parameters.map( (p) => p.name).join('|')})");
104+
}
105+
106+
Future<int> run() async {
107+
projectName = argResults.rest.length>0?argResults.rest.first:ask('Enter project name','some-name');
108+
_askArgument('ghaccount','GitHub account');
109+
_askArgument('author',"author's full name");
110+
_askArgument('email',"author's email");
111+
112+
113+
print("Generating project '${projectName}'");
114+
await new Directory(projectName).create();
115+
116+
parameterRegExp = new RegExp("\\\$(${argResults.options.join('|')}|name)");
62117

63118
var resource = new Resource("package:dacsslide/template/.files.txt");
64119
var fileNames = (await resource.readAsString(encoding: UTF8)).split("\n")
65120
.where( (f) => f.length>0).map( (f) => f.substring(2));
66121
await Future.wait(fileNames.map(createFile));
67-
print("Project generated");
122+
print("Project ${projectName} generated.");
123+
124+
config.save();
125+
68126
return 0;
69127
}
70128

71-
@override
72-
String get help => "Use 'create' command to initialize new presentation project.";
73-
74-
@override
75-
String get name => "create";
76129
}
77130

78-
//T commandCreator<T>() => new T();
79-
80-
List<Command> commands = [new CreateCommand()];
81-
82-
void main(List<String> arguments) async {
83-
if (arguments.length<1) {
84-
var commandList = commands.map((Command c) => c.name).join(",");
85-
stderr.write("Usage: dacsslide [command]\nWhere [command] is one of: ${commandList}");
86-
exitCode = 2;
87-
return;
88-
}
89-
90-
var command = commands.firstWhere((Command c) => c.name==arguments.first, orElse: () => null);
91-
if (command == null) {
92-
var commandList = commands.map((Command c) => c.name).join(",");
93-
stderr.write("Invalid command '${arguments.first}'\nAwailable commands are: ${commandList}");
94-
exitCode = 2;
95-
return;
96-
}
97-
exitCode = await command.execute(arguments.sublist(1));
131+
void main(List<String> arguments) {
132+
var runner = new CommandRunner("dacsslide","CLI for DaCSSlide presentation library")
133+
..addCommand(new CreateCommand());
134+
runner.run(arguments).catchError((error) {
135+
if (error is! UsageException) throw error;
136+
print(error);
137+
exit(64); // Exit code 64 indicates a usage error.
138+
});
98139
}

lib/template/.files.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
./CHANGELOG.md
33
./web/index.html
44
./web/styles.css
5-
./web/main.dart
5+
./web/main.dart.template
66
./web/favicon.png
77
./README.md
8-
./pubspec.yaml
8+
./pubspec.yaml.template
99
./.gitignore
10-
./lib/app_component.dart
10+
./lib/app_component.dart.template
1111
./lib/app_component.scss
1212
./lib/app_component.html
1313
./analysis_options.yaml

lib/template/lib/app_component.dart.template

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import 'package:dacsslide/sample_directive.dart';
1515
templateUrl: 'app_component.html',
1616
encapsulation: ViewEncapsulation.None,
1717
directives: const [PresentationComponent, SymbolComponent, SampleDirective],
18-
providers: const [SampleService],
18+
providers: const [SampleService, SlideService],
1919
)
2020
class AppComponent {
2121
}

lib/template/lib/app_component.html

+4
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
<presentation slides="2">
2+
<symbol name="intro">$title</symbol>
3+
<symbol name="auth">$author</symbol>
4+
<symbol name="email">$email</symbol>
5+
<symbol name="pres_url">http://$ghaccount.github.io/$name/</symbol>
26
</presentation>

lib/template/lib/app_component.scss

+25
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,28 @@ my-app presentation symbol div {
22
font-size: 4vw;
33
}
44

5+
#intro {
6+
font-size: 4vw;
7+
}
8+
#auth,#email,#pres_url {
9+
font-size: 2vw;
10+
width: 80vw;
11+
text-align: right;
12+
}
13+
#auth: down(160);
14+
#email: down(195);
15+
#pres_url: down(230);
16+
17+
.s1 {
18+
#intro: show;
19+
#auth: show;
20+
#email: show;
21+
#pres_url: show;
22+
}
23+
.s2 {
24+
#intro: down(300) rotateX(-60) hide;
25+
#auth: down(300) hide delay(0.4);
26+
#email: down(300) hide delay(0.3);
27+
#pres_url: down(300) hide delay(0.2);
28+
29+
}

lib/template/pubspec.yaml.template

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ environment:
99

1010
dependencies:
1111
angular: "^5.0.0-alpha"
12-
dacsslide: "^0.3.1"
12+
dacsslide: "^0.3.0-alpha"
1313
csslib_transform: any
1414

1515
dev_dependencies:

pubspec.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ dependencies:
1313
test: '>0.12.0 <1.0.0'
1414
http: '>0.10.0 <1.0.0'
1515
barback: '>0.10.0 < 1.0.0'
16-
'resource': '>=2.1.2 < 3.0.0'
16+
resource: '>=2.1.2 < 3.0.0'
17+
path: '>1.4.0 < 2.0.0'
1718
transformers:
1819
- dacsslide
1920
- csslib_transform

0 commit comments

Comments
 (0)