Compare commits

...

41 commits

Author SHA1 Message Date
Thomas
6dd993cd3b
Merge pull request #4 from dukefirehawk/feature/update_links
Updated repository links
2023-12-25 12:40:45 +08:00
thomashii@dukefirehawk.com
91bd1bf314 Updated repository links 2023-12-25 12:40:00 +08:00
Thomas Hii
ff197d984e
Update README.md 2023-10-21 13:35:36 +08:00
thomashii@dukefirehawk.com
383fdfb8f9 Updated README 2023-10-21 10:27:39 +08:00
thomashii@dukefirehawk.com
78c7076745 Updated change log 2023-10-12 22:47:51 +08:00
thomashii@dukefirehawk.com
0137402f89 Added white logo 2023-10-09 23:52:44 +08:00
thomashii@dukefirehawk.com
3b09470606 Updated logo 2023-10-08 23:51:07 +08:00
Thomas Hii
4154deface
Merge pull request #3 from dukefirehawk/feature/v8
Feature/v8
2023-10-08 11:16:01 +08:00
thomashii@dukefirehawk.com
4405b41acd Merge branch 'master' into feature/v8 2023-10-08 11:14:12 +08:00
thomashii@dukefirehawk.com
8682da1aef Ignore .DS_Store 2023-10-08 10:27:09 +08:00
thomashii@dukefirehawk.com
be3e91927d Updated dependencies 2023-10-08 10:25:40 +08:00
thomashii
00b0304af1 Removed deprecated code 2023-06-10 20:28:00 +08:00
thomashii
9619342ab8 Updated dependencies 2023-06-10 20:21:24 +08:00
Thomas Hii
1bc6641651
Merge pull request #2 from dukefirehawk/bug-fix/deprecated
Upgaded libraries
2022-12-03 13:11:11 +08:00
thomashii@dukefirehawk.com
f117469949 Upgaded libraries 2022-12-03 13:09:44 +08:00
thomashii@dukefirehawk.com
883f034140 Updated to version 7.0.0 2022-08-31 00:56:09 +08:00
Thomas Hii
e0548f997a
Merge pull request #1 from dukefirehawk/feature/upgrade-dependencies
Updated dependencies
2022-05-29 08:16:44 +08:00
thomashii@dukefirehawk.com
9123a77057 Updated dependencies 2022-05-29 08:13:58 +08:00
thomashii
b26b5c3054 Updated .pubignore 2022-05-01 18:06:02 +08:00
thomashii
8236775e73 Updated gitignore 2022-05-01 18:02:17 +08:00
thomashii
7e2d693164 Added mysql orm boilerplate 2022-05-01 18:00:33 +08:00
thomashii
d33edd4bb5 Updated ChangeLog 2022-04-26 09:32:24 +08:00
thomashii
9141e0c735 Update to SDK 2.16 2022-04-26 09:29:35 +08:00
thomashii
18ea483330 Added pubignore 2022-01-13 23:03:44 +08:00
thomashii
b9079bbe5f Fixed init 2022-01-13 22:51:04 +08:00
thomashii
f4b38337e0 Updated the SDK 2.14.0 2022-01-13 22:32:40 +08:00
thomashii
64104653a0 Updated gitignore 2021-09-16 10:17:24 +08:00
thomashii
e87d86eece Updated gitignore 2021-09-16 10:15:34 +08:00
thomashii
ac592ceb1a Updated linter 2021-09-16 10:14:04 +08:00
thomashii
422c92098a Fixed NNBD issues 2021-09-07 08:11:42 +08:00
thomashii
3bfdf05c0e Updated analyzer 2021-08-17 15:49:48 +08:00
thomashii
d8efcdef28 Updated README 2021-07-18 16:02:41 +08:00
thomashii
aa57f3b301 Updated CLI 2021-07-18 16:00:08 +08:00
thomashii
fe5b7ecd47 Updated screenshot 2021-07-18 12:34:31 +08:00
thomashii
c1ec1e3966 Updated screenshot 2021-07-18 12:31:03 +08:00
thomashii
5fc441825e Fixed init 2021-07-18 12:22:11 +08:00
thomashii
7e4aa24ce0 Updated NNBD 2021-07-17 13:10:35 +08:00
thomashii
6254a8a471 Updated README 2021-06-13 17:28:15 +08:00
thomashii
ac607e636a Updated README 2021-06-12 12:23:33 +08:00
thomashii
a71e02d7bd Migrated to NNBD 2021-06-12 12:10:34 +08:00
thomashii
dcd001fc65 Migrated to angel3 2021-06-11 13:07:53 +08:00
54 changed files with 980 additions and 653 deletions

BIN
.DS_Store vendored

Binary file not shown.

27
.gitignore vendored
View file

@ -3,38 +3,17 @@
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
# Sensitive or high-churn files:
.idea/dataSources.ids
.idea/dataSources.xml
.idea/dataSources.local.xml
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml
# Gradle:
.idea/gradle.xml
.idea/libraries
# Mongo Explorer plugin:
.idea/mongoSettings.xml
## File-based project format: ## File-based project format:
*.iws *.iws
.DS_Store
## Plugin-specific files: ## Plugin-specific files:
# IntelliJ # IntelliJ
/out/ /out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin # JIRA plugin
atlassian-ide-plugin.xml atlassian-ide-plugin.xml
@ -78,3 +57,7 @@ pubspec.lock
sample_project/ sample_project/
sample-project sample-project
.dart_tool .dart_tool
.metals
#.vscode
#!.vscode/settings.json

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/sample_project/.pub" />
<excludeFolder url="file://$MODULE_DIR$/sample_project/build" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/angel_cli.iml" filepath="$PROJECT_DIR$/.idea/angel_cli.iml" />
</modules>
</component>
</project>

View file

@ -1,8 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Controller" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="controller" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<option name="workingDirectory" value="$PROJECT_DIR$/sample_project" />
<method />
</configuration>
</component>

View file

@ -1,7 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Doctor" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="doctor" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<method />
</configuration>
</component>

View file

@ -1,8 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Init" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="init sample_project" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<option name="workingDirectory" value="$PROJECT_DIR$" />
<method />
</configuration>
</component>

View file

@ -1,7 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Show Help" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="--help" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<method />
</configuration>
</component>

View file

@ -1,8 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Update" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="update" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<option name="workingDirectory" value="$PROJECT_DIR$" />
<method />
</configuration>
</component>

View file

@ -1,7 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Version" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
<option name="arguments" value="version" />
<option name="filePath" value="$PROJECT_DIR$/bin/angel.dart" />
<method />
</configuration>
</component>

3
.pubignore Normal file
View file

@ -0,0 +1,3 @@
# Pub Ignore
.vscode

View file

@ -1 +0,0 @@
language: dart

6
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,6 @@
{
"files.watcherExclude": {
"**/target": true
},
"cmake.configureOnOpen": false
}

12
AUTHORS.md Normal file
View file

@ -0,0 +1,12 @@
Primary Authors
===============
* __[Thomas Hii](dukefirehawk.apps@gmail.com)__
Thomas is the current maintainer of the code base. He has refactored and migrated the
code base to support NNBD.
* __[Tobe O](thosakwe@gmail.com)__
Tobe has written much of the original code prior to NNBD migration. He has moved on and
is no longer involved with the project.

View file

@ -1,8 +1,88 @@
# 2.1.7+1 # Change Log
## 8.2.0
* Updated to `analyzer` 6.3.x
* Updated repository link
* Updated `lints` to 3.0.0
## 8.1.1
* Updated README
* Updated to logo
## 8.1.0
* Updated README
* Updated to logo
* Updated to `analyzer` 6.2.x
* Updated to support Dart SDK 3.1.x
## 8.0.0
* Required Dart SDK > 3.0.x
* Updated to `analyzer` 5.0.x
## 7.0.0
* Skipped release
## 6.0.0
* Updated Dart SDK to 2.16.x
## 5.0.0
* Skipped release
## 4.0.0
* Changed `pub` to `dart pub`
* Changed `pub build` to `dart build`
* Updated Dart SDK to 2.14.0
## 3.2.0
* Upgraded from `pedantic` to `lints` linter
## 3.1.1
* Fixed NNBD issues
## 3.1.0
* Upgraded to support `analyzer` 2.0.0
## 3.0.1
* Updated help to use `angel3`
* Updated to use `angel3` packages
* Updated screenshot
## 3.0.0
* Fixed NNBD issues
* Updated to use `angel3` packages
* Fixed incorrect import for new project
* Updated screenshot
## 3.0.0-beta.2
* Updated README
## 3.0.0-beta.1
* Migrated to work with Dart SDK 2.12.x Non NNBD
* Replaced `mustache4dart2` with `mustache_template`
* Replaced `inflection2` with `inflection3`
## 2.1.7+1
* Fix a bug where new directories were not being created in * Fix a bug where new directories were not being created in
`init`. `init`.
# 2.1.7 ## 2.1.7
* Fix a bug where `ArgResults.arguments` was used in `init` instead of the * Fix a bug where `ArgResults.arguments` was used in `init` instead of the
intended `ArgResults.rest`. intended `ArgResults.rest`.
* Stop including `package:angel_model` imports in `make model`. * Stop including `package:angel_model` imports in `make model`.
@ -10,36 +90,45 @@ intended `ArgResults.rest`.
* Fix `make model` to generate ORM + migration by default. * Fix `make model` to generate ORM + migration by default.
* Fix `MakerDependency` logic to print missing dependencies. * Fix `MakerDependency` logic to print missing dependencies.
# 2.1.6 ## 2.1.6
* Fix a bug where models always defaulted to ORM. * Fix a bug where models always defaulted to ORM.
* Add GraphQL boilerplate. * Add GraphQL boilerplate.
* Automatically restore terminal colors on shutdown. * Automatically restore terminal colors on shutdown.
# 2.1.5+1 ## 2.1.5+1
* Update to `inflection2`. * Update to `inflection2`.
# 2.1.5 ## 2.1.5
* Add `shared` boilerplates. * Add `shared` boilerplates.
* Remove uncecessary `angel_model` imports. * Remove uncecessary `angel_model` imports.
# 2.1.4+1 ## 2.1.4+1
* Patch `part of 'path'` renames. * Patch `part of 'path'` renames.
# 2.1.4 ## 2.1.4
* The `migration` argument to `model` just emits an annotation now. * The `migration` argument to `model` just emits an annotation now.
* Add the ORM boilerplate. * Add the ORM boilerplate.
# 2.1.3 ## 2.1.3
* Fix generation of ORM models. * Fix generation of ORM models.
* A `--project-name` to `init` command. * A `--project-name` to `init` command.
# 2.1.2 ## 2.1.2
* No migrations-by-default. * No migrations-by-default.
# 2.1.1 ## 2.1.1
* Edit the way `rename` runs, leaving no corner unturned. * Edit the way `rename` runs, leaving no corner unturned.
# 2.1.0 ## 2.1.0
* Deprecate `angel install`. * Deprecate `angel install`.
* Rename projects using `snake_case`. * Rename projects using `snake_case`.
* `init` now fetches from `master`. * `init` now fetches from `master`.
@ -48,34 +137,43 @@ intended `ArgResults.rest`.
* Replace `{{oldName}}` in the `rename` command. * Replace `{{oldName}}` in the `rename` command.
* `pub get` now runs with `inheritStdio`. * `pub get` now runs with `inheritStdio`.
# 2.0.1 ## 2.0.1
* `deploy systemd` now has an `--install` option, where you can immediately * `deploy systemd` now has an `--install` option, where you can immediately
spawn the service. spawn the service.
# 2.0.0 ## 2.0.0
* `init` can now produce either 1.x or 2.x projects. * `init` can now produce either 1.x or 2.x projects.
* Fixed deps for compatibility with Dart2 stable. * Fixed deps for compatibility with Dart2 stable.
# 1.3.4 ## 1.3.4
* Fix another typo. * Fix another typo.
# 1.3.3 ## 1.3.3
* Fix a small typo in the model generator. * Fix a small typo in the model generator.
# 1.3.2 ## 1.3.2
* Restore `part` directives in generated models. * Restore `part` directives in generated models.
# 1.3.1 ## 1.3.1
* Add `deploy nginx` and `deploy systemd`. * Add `deploy nginx` and `deploy systemd`.
# 1.3.0 ## 1.3.0
* Focus on Dart2 from here on out. * Focus on Dart2 from here on out.
* Update `code_builder`. * Update `code_builder`.
* More changes... * More changes...
# 1.1.5 ## 1.1.5
Deprecated several commands, in favor of the `make` Deprecated several commands, in favor of the `make`
command: command:
* `controller` * `controller`
* `plugin` * `plugin`
* `service` * `service`

42
LICENSE
View file

@ -1,21 +1,29 @@
MIT License BSD 3-Clause License
Copyright (c) [year] [fullname] Copyright (c) 2021, dukefirehawk.com
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy Redistribution and use in source and binary forms, with or without
of this software and associated documentation files (the "Software"), to deal modification, are permitted provided that the following conditions are met:
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all 1. Redistributions of source code must retain the above copyright notice, this
copies or substantial portions of the Software. list of conditions and the following disclaimer.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2. Redistributions in binary form must reproduce the above copyright notice,
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, this list of conditions and the following disclaimer in the documentation
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE and/or other materials provided with the distribution.
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 3. Neither the name of the copyright holder nor the names of its
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE contributors may be used to endorse or promote products derived from
SOFTWARE. this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,26 +1,31 @@
# angel_cli # Angel3 CLI
![Screenshot of Terminal](screenshots/screenshot.png) [![Angel3 Logo](angel3_logo.png)](https://github.com/dart-backend/angel3-cli)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_cli?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)
[![License](https://img.shields.io/github/license/dart-backend/angel3-cli)](https://github.com/dart-backend/angel3-cli/blob/master/LICENSE)
The command line interface for buidling dart backend in [Angel3 framework](https://pub.dev/packages/angel3_framework) that provides the following functionalities:
Command-line tools for the Angel framework.
Includes functionality such as:
* Project scaffolding * Project scaffolding
* Generating service models, plugins, tests and more * Generating service models, plugins, tests and more
* Renaming projects * Renaming projects
* Much more... * Much more...
* To install: ## Installation
```bash ```bash
$ pub global activate angel_cli dart pub global activate angel3_cli
``` ```
* Install development version ## Help
`dart pub global activate --source path ./packages/cli`
`dart pub global activate --source git https://github.com/dukefirehawk/angel/packages/cli`
And then, for information on each command: For information on the available options:
```bash ```bash
$ angel help angel3 help
``` ```
[![Screenshot of Terminal](screenshots/angel3-screenshot.png)](https://github.com/dart-backend/angel3-cli)

View file

@ -1,7 +0,0 @@
# Todo
* `service`
* Add tests
* `migration`
* `deploy`
* Call these from Grinder script :)

View file

@ -1,3 +1 @@
analyzer: include: package:lints/recommended.yaml
strong-mode:
implicit-casts: false

BIN
angel3_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

135
archived/logo128.svg Normal file
View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="128"
height="128"
viewBox="0 0 128 128"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed, 2023-07-21)"
sodipodi:docname="logo128.svg"
inkscape:export-filename="logo_icon_128.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="true"
inkscape:zoom="1.5862247"
inkscape:cx="58.629776"
inkscape:cy="90.466375"
inkscape:window-width="1312"
inkscape:window-height="738"
inkscape:window-x="128"
inkscape:window-y="111"
inkscape:window-maximized="0"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="1"
spacingy="1"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1">
<linearGradient
id="linearGradient15"
inkscape:collect="always">
<stop
style="stop-color:#d81c1c;stop-opacity:1;"
offset="0"
id="stop15" />
<stop
style="stop-color:#d81c1c;stop-opacity:0;"
offset="1"
id="stop16" />
</linearGradient>
<linearGradient
id="swatch13"
inkscape:swatch="solid">
<stop
style="stop-color:#d81c1c;stop-opacity:1;"
offset="0"
id="stop14" />
</linearGradient>
<linearGradient
id="swatch7"
inkscape:swatch="solid">
<stop
style="stop-color:#d81c1c;stop-opacity:1;"
offset="0"
id="stop7" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#swatch13"
id="linearGradient14"
x1="76.307388"
y1="264.40897"
x2="425.84061"
y2="264.40897"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15"
id="linearGradient16"
x1="185.07693"
y1="354.51111"
x2="296.18161"
y2="354.51111"
gradientUnits="userSpaceOnUse" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:137.557px;font-family:'Comic Sans MS';-inkscape-font-specification:'Comic Sans MS, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;opacity:1;fill:#d81c1c;fill-opacity:1;stroke-width:0.716443"
x="13.382875"
y="114.63321"
id="text1"
transform="scale(1.0161156,0.98414)"><tspan
sodipodi:role="line"
id="tspan1"
x="13.382875"
y="114.63321"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:137.557px;font-family:'Comic Sans MS';-inkscape-font-specification:'Comic Sans MS, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#d81c1c;fill-opacity:1;stroke-width:0.716443">A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:54.9757px;font-family:'Comic Sans MS';-inkscape-font-specification:'Comic Sans MS, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;opacity:1;fill:#d81c1c;fill-opacity:1;stroke:#ffffff;stroke-width:0.725;stroke-dasharray:none;stroke-opacity:1"
x="44.028919"
y="108.3848"
id="text2"
transform="scale(1.1577238,0.86376387)"><tspan
sodipodi:role="line"
id="tspan2"
x="44.028919"
y="108.3848"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:54.9757px;font-family:'Comic Sans MS';-inkscape-font-specification:'Comic Sans MS, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#d81c1c;fill-opacity:1;stroke:#ffffff;stroke-width:0.725;stroke-dasharray:none;stroke-opacity:1">3</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
archived/logo3.xcf Normal file

Binary file not shown.

View file

@ -1,55 +0,0 @@
#!/usr/bin/env dart
library angel_cli.tool;
import "dart:io";
import "package:args/command_runner.dart";
import 'package:angel_cli/angel_cli.dart';
import 'package:io/ansi.dart';
final String DOCTOR = "doctor";
main(List<String> args) async {
var runner = new CommandRunner(
"angel",
asciiArt.trim() +
'\n\n' +
"Command-line tools for the Angel framework." +
'\n\n' +
'https://angel-dart.github.io');
runner.argParser
.addFlag('verbose', help: 'Print verbose output.', negatable: false);
runner
..addCommand(new DeployCommand())
..addCommand(new DoctorCommand())
..addCommand(new KeyCommand())
..addCommand(new InitCommand())
..addCommand(new InstallCommand())
..addCommand(new RenameCommand())
..addCommand(new MakeCommand());
return await runner.run(args).catchError((exc, st) {
if (exc is String) {
stdout.writeln(exc);
} else {
stderr.writeln("Oops, something went wrong: $exc");
if (args.contains('--verbose')) {
stderr.writeln(st);
}
}
exitCode = 1;
}).whenComplete(() {
stdout.write(resetAll.wrap(''));
});
}
const String asciiArt = '''
____________ ________________________
___ |__ | / /_ ____/__ ____/__ /
__ /| |_ |/ /_ / __ __ __/ __ /
_ ___ | /| / / /_/ / _ /___ _ /___
/_/ |_/_/ |_/ \____/ /_____/ /_____/
''';

76
bin/angel3.dart Normal file
View file

@ -0,0 +1,76 @@
#!/usr/bin/env dart
library angel3_cli.tool;
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:angel3_cli/angel3_cli.dart';
import 'package:io/ansi.dart';
void main(List<String> args) async {
var runner = CommandRunner('angel3',
'$asciiArt\n\nCommand-line tools for the Angel3 framework.\n\nhttps://angel3-framework.web.app');
runner.argParser
.addFlag('verbose', help: 'Print verbose output.', negatable: false);
runner
..addCommand(DeployCommand())
..addCommand(DoctorCommand())
..addCommand(KeyCommand())
..addCommand(InitCommand())
// ..addCommand(InstallCommand())
..addCommand(RenameCommand())
..addCommand(MakeCommand());
await runner.run(args).catchError((exc, st) {
if (exc is String) {
stdout.writeln(exc);
} else {
stderr.writeln('Oops, something went wrong: $exc');
if (args.contains('--verbose')) {
stderr.writeln(st);
}
}
exitCode = 1;
}).whenComplete(() {
stdout.write(resetAll.wrap(''));
});
}
const String asciiArt2 = '''
___ _ ________________ _____
/ | / | / / ____/ ____/ / |__ /
/ /| | / |/ / / __/ __/ / / /_ <
/ ___ |/ /| / /_/ / /___/ /______/ /
/_/ |_/_/ |_/\\____/_____/_____/____/
''';
const String asciiArt = '''
_ _ _ ____ _____ _ _____
/ \\ | \\ | |/ ___| ____| | |___ /
/ _ \\ | \\| | | _| _| | | |_ \\
/ ___ \\| |\\ | |_| | |___| |___ ___) |
/_/ \\_\\_| \\_|\\____|_____|_____|____/
''';
const String asciiArt3 = '''
\\ \\ | ___| ____| | ___ /
_ \\ \\ | | __| | _ \\
___ \\ |\\ | | | | | ) |
_/ _\\ _| \\_| \\____| _____| _____| ____/
''';
const String asciiArtOld = '''
____________ ________________________
___ |__ | / /_ ____/__ ____/__ /
__ /| |_ |/ /_ / __ __ __/ __ /
_ ___ | /| / / /_/ / _ /___ _ /___
/_/ |_/_/ |_/ \\____/ /_____/ /_____/
''';

View file

@ -1,3 +1,3 @@
library angel_cli; library angel3_cli;
export 'src/commands/commands.dart'; export 'src/commands/commands.dart';

View file

@ -1,9 +1,9 @@
library angel_cli.commands; library angel3_cli.commands;
export "deploy.dart"; export 'deploy.dart';
export "doctor.dart"; export 'doctor.dart';
export "key.dart"; export 'key.dart';
export "init.dart"; export 'init.dart';
export "install.dart"; export 'install.dart';
export "make.dart"; export 'make.dart';
export "rename.dart"; export 'rename.dart';

View file

@ -20,7 +20,7 @@ class NginxCommand extends Command {
} }
@override @override
run() async { Future run() async {
var webPath = p.join(p.current, 'web'); var webPath = p.join(p.current, 'web');
var nginxText = ''' var nginxText = '''
server { server {
@ -28,7 +28,7 @@ server {
root ${p.absolute(webPath)}; # Set to your static files directory root ${p.absolute(webPath)}; # Set to your static files directory
location / { location / {
try_files \$uri @proxy; # Try to serve static files; fallback to proxied Angel server try_files \$uri @proxy; # Try to serve static files; fallback to proxied Angel3 server
} }
location @proxy { location @proxy {
@ -39,10 +39,10 @@ server {
''' '''
.trim(); .trim();
if (!argResults.wasParsed('out')) { if (!argResults!.wasParsed('out')) {
print(nginxText); print(nginxText);
} else { } else {
var file = new File(argResults['out'] as String); var file = File(argResults!['out'] as String);
await file.create(recursive: true); await file.create(recursive: true);
await file.writeAsString(nginxText); await file.writeAsString(nginxText);
print(green.wrap( print(green.wrap(

View file

@ -27,10 +27,10 @@ class SystemdCommand extends Command {
} }
@override @override
run() async { Future run() async {
var projectPath = p.absolute(p.current); var projectPath = p.absolute(p.current);
var pubspec = await loadPubspec(); var pubspec = await loadPubspec();
var user = argResults['user']; var user = argResults?['user'];
var systemdText = ''' var systemdText = '''
[Unit] [Unit]
Description=`${pubspec.name}` server Description=`${pubspec.name}` server
@ -47,15 +47,16 @@ WantedBy=multi-user.target
''' '''
.trim(); .trim();
if (!argResults.wasParsed('out') && !argResults.wasParsed('install')) { if (argResults?.wasParsed('out') != true &&
argResults?.wasParsed('install') != true) {
print(systemdText); print(systemdText);
} else if (argResults.wasParsed('install')) { } else if (argResults?.wasParsed('install') == true) {
var systemdPath = argResults.wasParsed('out') var systemdPath = argResults?.wasParsed('out') == true
? argResults['out'] as String ? (argResults?['out'] as String)
: p.join('etc', 'systemd', 'system'); : p.join('etc', 'systemd', 'system');
var serviceFilename = p.join(systemdPath, var serviceFilename = p.join(systemdPath,
p.setExtension(argResults['install'] as String, '.service')); p.setExtension(argResults?['install'] as String, '.service'));
var file = new File(serviceFilename); var file = File(serviceFilename);
await file.create(recursive: true); await file.create(recursive: true);
await file.writeAsString(systemdText); await file.writeAsString(systemdText);
print(green.wrap( print(green.wrap(
@ -76,7 +77,7 @@ WantedBy=multi-user.target
print(red.wrap('$ballot Failed to install service system-wide.')); print(red.wrap('$ballot Failed to install service system-wide.'));
} }
} else { } else {
var file = new File(argResults['out'] as String); var file = File(argResults?['out'] as String);
await file.create(recursive: true); await file.create(recursive: true);
await file.writeAsString(systemdText); await file.writeAsString(systemdText);
print(green.wrap( print(green.wrap(

View file

@ -1,34 +1,35 @@
import "dart:convert"; import 'dart:convert';
import "dart:io"; import 'dart:io';
import "package:args/command_runner.dart"; import 'package:args/command_runner.dart';
import 'package:io/ansi.dart'; import 'package:io/ansi.dart';
import '../util.dart'; import '../util.dart';
class DoctorCommand extends Command { class DoctorCommand extends Command {
@override @override
String get name => "doctor"; String get name => 'doctor';
@override @override
String get description => String get description =>
"Ensures that the current system is capable of running Angel."; 'Ensures that the current system is capable of running Angel3.';
@override @override
run() async { Future run() async {
print("Checking your system for dependencies..."); print('Checking your system for dependencies...');
await _checkForGit(); await _checkForGit();
} }
_checkForGit() async { Future _checkForGit() async {
try { try {
var git = await Process.start("git", ["--version"]); var git = await Process.start('git', ['--version']);
if (await git.exitCode == 0) { if (await git.exitCode == 0) {
var version = await git.stdout.transform(utf8.decoder).join(); var version = await git.stdout.transform(utf8.decoder).join();
print(green.wrap( print(green.wrap(
"$checkmark Git executable found: v${version.replaceAll('git version', '').trim()}")); "$checkmark Git executable found: v${version.replaceAll('git version', '').trim()}"));
} else } else {
throw Exception("Git executable exit code not 0"); throw Exception('Git executable exit code not 0');
}
} catch (exc) { } catch (exc) {
print(red.wrap("$ballot Git executable not found")); print(red.wrap('$ballot Git executable not found'));
} }
} }
} }

View file

@ -1,6 +1,6 @@
import 'dart:async'; import 'dart:async';
import "dart:io"; import 'dart:io';
import "package:args/command_runner.dart"; import 'package:args/command_runner.dart';
import 'package:io/ansi.dart'; import 'package:io/ansi.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:prompts/prompts.dart' as prompts; import 'package:prompts/prompts.dart' as prompts;
@ -8,18 +8,17 @@ import 'package:recase/recase.dart';
import '../random_string.dart' as rs; import '../random_string.dart' as rs;
import '../util.dart'; import '../util.dart';
import 'key.dart'; import 'key.dart';
import 'pub.dart';
import 'rename.dart'; import 'rename.dart';
class InitCommand extends Command { class InitCommand extends Command {
final KeyCommand _key = KeyCommand(); final KeyCommand _key = KeyCommand();
@override @override
String get name => "init"; String get name => 'init';
@override @override
String get description => String get description =>
"Initializes a new Angel project in the current directory."; 'Initializes a new Angel3 project in the current directory.';
InitCommand() { InitCommand() {
argParser argParser
@ -33,10 +32,15 @@ class InitCommand extends Command {
} }
@override @override
run() async { void run() async {
Directory projectDir = if (argResults == null) {
Directory(argResults.rest.isEmpty ? "." : argResults.rest[0]); print('Invalid arguements');
print("Creating new Angel project in ${projectDir.absolute.path}..."); return;
}
var projectDir =
Directory(argResults!.rest.isEmpty ? '.' : argResults!.rest[0]);
print('Creating new Angel3 project in ${projectDir.absolute.path}...');
await _cloneRepo(projectDir); await _cloneRepo(projectDir);
// await preBuild(projectDir); // await preBuild(projectDir);
var secret = rs.randomAlphaNumeric(32); var secret = rs.randomAlphaNumeric(32);
@ -49,8 +53,8 @@ class InitCommand extends Command {
await _key.changeSecret( await _key.changeSecret(
File.fromUri(projectDir.uri.resolve('config/production.yaml')), secret); File.fromUri(projectDir.uri.resolve('config/production.yaml')), secret);
var name = argResults.wasParsed('project-name') var name = argResults!.wasParsed('project-name')
? argResults['project-name'] as String ? (argResults!['project-name'] as String)
: p.basenameWithoutExtension( : p.basenameWithoutExtension(
projectDir.absolute.uri.normalizePath().toFilePath()); projectDir.absolute.uri.normalizePath().toFilePath());
@ -58,50 +62,57 @@ class InitCommand extends Command {
print('Renaming project from "angel" to "$name"...'); print('Renaming project from "angel" to "$name"...');
await renamePubspec(projectDir, 'angel', name); await renamePubspec(projectDir, 'angel', name);
await renameDartFiles(projectDir, 'angel', name); await renameDartFiles(projectDir, 'angel', name);
// Renaming executable files
if (argResults['pub-get'] != false && argResults['offline'] == false) { if (argResults!['pub-get'] != false && argResults!['offline'] == false) {
print('Now running pub get...'); print('Now running dart pub get...');
await _pubGet(projectDir); await _pubGet(projectDir);
} }
print(green.wrap("$checkmark Successfully initialized Angel project.")); print(green.wrap('$checkmark Successfully initialized Angel3 project.'));
stdout stdout
..writeln() ..writeln()
..writeln( ..writeln(
'Congratulations! You are ready to start developing with Angel!') 'Congratulations! You are ready to start developing with Angel3!')
..write('To start the server (with ') ..write('To start the server (with ')
..write(cyan.wrap('hot-reloading')) ..write(cyan.wrap('hot-reloading'))
..write('), run ') ..write('), run ')
..write(magenta.wrap('`dart --observe bin/dev.dart`')) ..write(magenta.wrap('`dart --observe bin/dev.dart`'))
..writeln(' in your terminal.') ..writeln(' in your terminal.')
..writeln() ..writeln()
..writeln('Find more documentation about Angel:') ..writeln('Find more documentation about Angel3:')
..writeln(' * https://angel-dart.github.io') ..writeln(' * https://angel3-framework.web.app')
..writeln(' * https://github.com/angel-dart/angel/wiki') ..writeln(' * https://angel3-docs.dukefirehawk.com')
..writeln( // ..writeln(
' * https://www.youtube.com/playlist?list=PLl3P3tmiT-frEV50VdH_cIrA2YqIyHkkY') // ' * https://www.youtube.com/playlist?list=PLl3P3tmiT-frEV50VdH_cIrA2YqIyHkkY')
..writeln(' * https://medium.com/the-angel-framework') // ..writeln(' * https://medium.com/the-angel-framework')
..writeln(' * https://dart.academy/tag/angel') // ..writeln(' * https://dart.academy/tag/angel')
..writeln() ..writeln()
..writeln('Happy coding!'); ..writeln('Happy coding!');
} }
_deleteRecursive(FileSystemEntity entity, [bool self = true]) async { Future _deleteRecursive(FileSystemEntity entity, [bool self = true]) async {
if (entity is Directory) { if (entity is Directory) {
await for (var entity in entity.list(recursive: true)) { await for (var entity in entity.list(recursive: true)) {
try { try {
await _deleteRecursive(entity); await _deleteRecursive(entity);
} catch (e) {} } catch (e) {
print(e);
}
} }
try { try {
if (self != false) await entity.delete(recursive: true); if (self != false) await entity.delete(recursive: true);
} catch (e) {} } catch (e) {
print(e);
}
} else if (entity is File) { } else if (entity is File) {
try { try {
await entity.delete(recursive: true); await entity.delete(recursive: true);
} catch (e) {} } catch (e) {
print(e);
}
} else if (entity is Link) { } else if (entity is Link) {
var path = await entity.resolveSymbolicLinks(); var path = await entity.resolveSymbolicLinks();
var stat = await FileStat.stat(path); var stat = await FileStat.stat(path);
@ -117,42 +128,49 @@ class InitCommand extends Command {
} }
} }
_cloneRepo(Directory projectDir) async { Future _cloneRepo(Directory projectDir) async {
Directory boilerplateDir; Directory boilerplateDir = Directory("./empty");
try { try {
if (await projectDir.exists()) { if (await projectDir.exists()) {
var shouldDelete = prompts.getBool( var shouldDelete = prompts.getBool(
"Directory '${projectDir.absolute.path}' already exists. Overwrite it?"); "Directory '${projectDir.absolute.path}' already exists. Overwrite it?");
if (!shouldDelete) if (!shouldDelete) {
throw "Chose not to overwrite existing directory."; throw 'Chose not to overwrite existing directory.';
else if (projectDir.absolute.uri.normalizePath().toFilePath() != } else if (projectDir.absolute.uri.normalizePath().toFilePath() !=
Directory.current.absolute.uri.normalizePath().toFilePath()) Directory.current.absolute.uri.normalizePath().toFilePath()) {
await projectDir.delete(recursive: true); await projectDir.delete(recursive: true);
else { } else {
await _deleteRecursive(projectDir, false); await _deleteRecursive(projectDir, false);
} }
} }
// var boilerplate = basicBoilerplate; // var boilerplate = basicBoilerplate;
print('Choose a project type before continuing:'); print('Choose a project type before continuing:');
var boilerplate = prompts.choose( var boilerplate = prompts.choose(
'Choose a project type before continuing', boilerplates); 'Choose a project type before continuing', boilerplates) ??
basicBoilerplate;
// Ultimately, we want a clone of every boilerplate locally on the system. // Ultimately, we want a clone of every boilerplate locally on the system.
var boilerplateRootDir = Directory(p.join(angelDir.path, 'boilerplates')); var boilerplateRootDir = Directory(p.join(angelDir.path, 'boilerplates'));
var boilerplateBasename = p.basenameWithoutExtension(boilerplate.url); var boilerplateBasename = p.basenameWithoutExtension(boilerplate.url);
if (boilerplate.ref != null) boilerplateBasename += '.${boilerplate.ref}'; if (boilerplate.ref != '') {
boilerplateBasename += '.${boilerplate.ref}';
}
boilerplateDir = boilerplateDir =
Directory(p.join(boilerplateRootDir.path, boilerplateBasename)); Directory(p.join(boilerplateRootDir.path, boilerplateBasename));
await boilerplateRootDir.create(recursive: true); await boilerplateRootDir.create(recursive: true);
var branch = boilerplate.ref ?? 'master'; var branch = boilerplate.ref;
if (branch == '') {
branch = 'master';
}
// If there is no clone existing, clone it. // If there is no clone existing, clone it.
if (!await boilerplateDir.exists()) { if (!await boilerplateDir.exists()) {
if (argResults['offline'] as bool) { if (argResults!['offline'] as bool) {
throw Exception( throw Exception(
'--offline was selected, but the "${boilerplate.name}" boilerplate has not yet been downloaded.'); '--offline was selected, but the "${boilerplate.name}" boilerplate has not yet been downloaded.');
} }
@ -161,15 +179,15 @@ class InitCommand extends Command {
'Cloning "${boilerplate.name}" boilerplate from "${boilerplate.url}"...'); 'Cloning "${boilerplate.name}" boilerplate from "${boilerplate.url}"...');
Process git; Process git;
if (boilerplate.ref == null) { if (boilerplate.ref == '') {
print(darkGray.wrap( print(darkGray.wrap(
'\$ git clone --depth 1 ${boilerplate.url} ${boilerplateDir.absolute.path}')); '\$ git clone --depth 1 ${boilerplate.url} ${boilerplateDir.absolute.path}'));
git = await Process.start( git = await Process.start(
"git", 'git',
[ [
"clone", 'clone',
"--depth", '--depth',
"1", '1',
boilerplate.url, boilerplate.url,
boilerplateDir.absolute.path boilerplateDir.absolute.path
], ],
@ -180,13 +198,13 @@ class InitCommand extends Command {
print(darkGray.wrap( print(darkGray.wrap(
'\$ git clone --depth 1 --single-branch -b ${boilerplate.ref} ${boilerplate.url} ${boilerplateDir.absolute.path}')); '\$ git clone --depth 1 --single-branch -b ${boilerplate.ref} ${boilerplate.url} ${boilerplateDir.absolute.path}'));
git = await Process.start( git = await Process.start(
"git", 'git',
[ [
"clone", 'clone',
"--depth", '--depth',
"1", '1',
"--single-branch", '--single-branch',
"-b", '-b',
boilerplate.ref, boilerplate.ref,
boilerplate.url, boilerplate.url,
boilerplateDir.absolute.path boilerplateDir.absolute.path
@ -196,19 +214,19 @@ class InitCommand extends Command {
} }
if (await git.exitCode != 0) { if (await git.exitCode != 0) {
throw Exception("Could not clone repo."); throw Exception('Could not clone repo.');
} }
} }
// Otherwise, pull from git. // Otherwise, pull from git.
else if (!(argResults['offline'] as bool)) { else if (!(argResults!['offline'] as bool)) {
print(darkGray.wrap('\$ git pull origin $branch')); print(darkGray.wrap('\$ git pull origin $branch'));
var git = await Process.start("git", ['pull', 'origin', '$branch'], var git = await Process.start('git', ['pull', 'origin', branch],
mode: ProcessStartMode.inheritStdio, mode: ProcessStartMode.inheritStdio,
workingDirectory: boilerplateDir.absolute.path); workingDirectory: boilerplateDir.absolute.path);
if (await git.exitCode != 0) { if (await git.exitCode != 0) {
print(yellow.wrap( print(yellow.wrap(
"Update of $branch failed. Attempting to continue with existing contents.")); 'Update of $branch failed. Attempting to continue with existing contents.'));
} }
} else { } else {
print(darkGray.wrap( print(darkGray.wrap(
@ -222,37 +240,39 @@ class InitCommand extends Command {
await preBuild(projectDir).catchError((_) => null); await preBuild(projectDir).catchError((_) => null);
} }
var gitDir = Directory.fromUri(projectDir.uri.resolve(".git")); var gitDir = Directory.fromUri(projectDir.uri.resolve('.git'));
if (await gitDir.exists()) await gitDir.delete(recursive: true); if (await gitDir.exists()) await gitDir.delete(recursive: true);
} catch (e) { } catch (e) {
await boilerplateDir.delete(recursive: true).catchError((_) => null); await boilerplateDir.delete(recursive: true);
//await boilerplateDir.delete(recursive: true).catchError((e) {
// print('Got error: ${e.error}');
//});
if (e is! String) { if (e is! String) {
print(red.wrap("$ballot Could not initialize Angel project.")); print(red.wrap('$ballot Could not initialize Angel3 project.'));
} }
rethrow; rethrow;
} }
} }
_pubGet(Directory projectDir) async { Future _pubGet(Directory projectDir) async {
var pubPath = resolvePub(); var dartPath = "dart";
print(darkGray.wrap('Running pub at "$pubPath"...')); print(darkGray.wrap('Running "$dartPath"...'));
print(darkGray.wrap('\$ $pubPath get')); print(darkGray.wrap('\$ $dartPath pub get'));
var pub = await Process.start(pubPath, ["get"], var dart = await Process.start(dartPath, ['pub', 'get'],
workingDirectory: projectDir.absolute.path, workingDirectory: projectDir.absolute.path,
mode: ProcessStartMode.inheritStdio); mode: ProcessStartMode.inheritStdio);
var code = await pub.exitCode; var code = await dart.exitCode;
print("Pub process exited with code $code"); print('Dart process exited with code $code');
} }
} }
Future preBuild(Directory projectDir) async { Future preBuild(Directory projectDir) async {
// Run build // Run build
// print('Running `pub run build_runner build`...'); // print('Running `dart run build_runner build`...');
print(darkGray.wrap('\$ pub run build_runner build')); print(darkGray.wrap('\$ dart run build_runner build'));
var build = await Process.start( var build = await Process.start("dart", ['run', 'build_runner', 'build'],
resolvePub(), ['run', 'build_runner', 'build'],
workingDirectory: projectDir.absolute.path, workingDirectory: projectDir.absolute.path,
mode: ProcessStartMode.inheritStdio); mode: ProcessStartMode.inheritStdio);
@ -261,63 +281,63 @@ Future preBuild(Directory projectDir) async {
if (buildCode != 0) throw Exception('Failed to pre-build resources.'); if (buildCode != 0) throw Exception('Failed to pre-build resources.');
} }
const RepoArchiveLocation = "https://github.com/angel-dart"; const repoLocation = 'https://github.com/dart-backend';
const RepoLocation = "https://github.com/dukefirehawk";
const BoilerplateInfo graphQLBoilerplate = const BoilerplateInfo( const BoilerplateInfo graphQLBoilerplate = BoilerplateInfo(
'GraphQL', 'GraphQL',
"A starting point for GraphQL API servers.", 'A starter application with GraphQL support.',
'${RepoLocation}/boilerplates.git', '$repoLocation/boilerplates.git',
ref: 'graphql-sdk-2.12.x', ref: 'v7/angel3-graphql',
); );
const BoilerplateInfo ormBoilerplate = const BoilerplateInfo( const BoilerplateInfo ormBoilerplate = BoilerplateInfo(
'ORM', 'ORM for PostgreSQL',
"A starting point for applications that use Angel's ORM.", 'A starter application with ORM support for PostgreSQL.',
'${RepoLocation}/boilerplates.git', '$repoLocation/boilerplates.git',
ref: 'orm-sdk-2.12.x', ref: 'v7/angel3-orm',
); );
const BoilerplateInfo basicBoilerplate = const BoilerplateInfo( const BoilerplateInfo ormMySqlBoilerplate = BoilerplateInfo(
'ORM for MySQL/MariaDB',
'A starter application with ORM support for MySQL/MariaDB.',
'$repoLocation/boilerplates.git',
ref: 'v7/angel3-orm-mysql',
);
const BoilerplateInfo basicBoilerplate = BoilerplateInfo(
'Basic', 'Basic',
'Minimal starting point for Angel 2.x - A simple server with only a few additional packages.', 'A basic starter application with minimal packages.',
'${RepoLocation}/boilerplates.git', '$repoLocation/boilerplates.git',
ref: 'basic-sdk-2.12.x'); ref: 'v7/angel3-basic');
const BoilerplateInfo legacyBoilerplate = const BoilerplateInfo( const BoilerplateInfo sharedBoilerplate = BoilerplateInfo(
'Legacy',
'Minimal starting point for applications running Angel 1.1.x.',
'${RepoArchiveLocation}/angel.git',
ref: '1.1.x',
);
const BoilerplateInfo sharedBoilerplate = const BoilerplateInfo(
'Shared', 'Shared',
'Holds common models and files shared across multiple Dart projects.', 'Holds common models and files shared across multiple Dart projects.',
'${RepoLocation}/boilerplate_shared.git'); '$repoLocation/boilerplate_shared.git');
const BoilerplateInfo sharedOrmBoilerplate = const BoilerplateInfo( const BoilerplateInfo sharedOrmBoilerplate = BoilerplateInfo(
'Shared (ORM)', 'Shared (ORM)',
'Holds common models and files shared across multiple Dart projects.', 'Holds common models and files shared across multiple Dart projects.',
'${RepoLocation}/boilerplate_shared.git', '$repoLocation/boilerplate_shared.git',
ref: 'orm', ref: 'orm',
); );
const List<BoilerplateInfo> boilerplates = const [ const List<BoilerplateInfo> boilerplates = [
basicBoilerplate, basicBoilerplate,
//legacyBoilerplate,
ormBoilerplate, ormBoilerplate,
ormMySqlBoilerplate,
graphQLBoilerplate, graphQLBoilerplate,
//sharedBoilerplate, //sharedBoilerplate,
//sharedOrmBoilerplate, //sharedOrmBoilerplate,
]; ];
class BoilerplateInfo { class BoilerplateInfo {
final String name, description, url, ref; final String name, description, url;
final String ref;
final bool needsPrebuild; final bool needsPrebuild;
const BoilerplateInfo(this.name, this.description, this.url, const BoilerplateInfo(this.name, this.description, this.url,
{this.ref, this.needsPrebuild: false}); {this.ref = '', this.needsPrebuild = false});
@override @override
String toString() => '$name ($description)'; String toString() => '$name ($description)';

View file

@ -3,7 +3,8 @@ import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:glob/glob.dart'; import 'package:glob/glob.dart';
import 'package:io/ansi.dart'; import 'package:io/ansi.dart';
import 'package:mustache4dart2/mustache4dart2.dart' as mustache; //import 'package:mustache4dart2/mustache4dart2.dart' as mustache;
import 'package:mustache_template/mustache_template.dart' as mustache;
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:prompts/prompts.dart' as prompts; import 'package:prompts/prompts.dart' as prompts;
import 'package:pubspec_parse/pubspec_parse.dart'; import 'package:pubspec_parse/pubspec_parse.dart';
@ -11,6 +12,7 @@ import 'package:yaml/yaml.dart' as yaml;
import '../util.dart'; import '../util.dart';
import 'make/maker.dart'; import 'make/maker.dart';
@Deprecated("No longer needed")
class InstallCommand extends Command { class InstallCommand extends Command {
static const String repo = 'https://github.com/angel-dart/install.git'; static const String repo = 'https://github.com/angel-dart/install.git';
static final Directory installRepo = static final Directory installRepo =
@ -46,62 +48,66 @@ class InstallCommand extends Command {
} }
@override @override
run() async { Future run() async {
print(yellow.wrap( print(yellow.wrap(
'WARNING: The `install` command is no longer considered necessary, and has been deprecated.\n' 'WARNING: The `install` command is no longer considered necessary, and has been deprecated.\n'
'Expect it to be removed in an upcoming release.\n\n' 'Expect it to be removed in an upcoming release.\n\n'
'See here: https://github.com/angel-dart/install.git\n\n' 'See here: https://github.com/angel-dart/install.git\n\n'
'To stop seeing this, downgrade to `package:angel_cli@<=2.0.0`.')); 'To stop seeing this, downgrade to `package:angel_cli@<=2.0.0`.'));
if (argResults['wipe'] as bool) { if (argResults?['wipe'] as bool) {
if (await installRepo.exists()) await installRepo.delete(recursive: true); if (await installRepo.exists()) await installRepo.delete(recursive: true);
} else if (argResults['list'] as bool) { } else if (argResults?['list'] as bool) {
var addons = await list(); var addons = await list();
print('${addons.length} add-on(s) installed:'); print('${addons.length} add-on(s) installed:');
for (var addon in addons) { for (var addon in addons) {
print(' * ${addon.name}@${addon.version}: ${addon.description}'); print(' * ${addon.name}@${addon.version}: ${addon.description}');
} }
} else if (argResults['update'] as bool) { } else if (argResults?['update'] as bool) {
await update(); await update();
} else if (argResults.rest.isNotEmpty) { } else if (argResults!.rest.isNotEmpty) {
if (!await installRepo.exists()) if (!await installRepo.exists()) {
throw 'No local add-on database exists. Run `angel install --update` first.'; throw 'No local add-on database exists. Run `angel3 install --update` first.';
}
var pubspec = await loadPubspec(); var pubspec = await loadPubspec();
for (var packageName in argResults.rest) { for (var packageName in argResults?.rest ?? <String>[]) {
var packageDir = var packageDir =
Directory.fromUri(installRepo.uri.resolve(packageName)); Directory.fromUri(installRepo.uri.resolve(packageName));
if (!await packageDir.exists()) if (!await packageDir.exists()) {
throw 'No add-on named "$packageName" is installed. You might need to run `angel install --update`.'; throw 'No add-on named "$packageName" is installed. You might need to run `angel3 install --update`.';
}
print('Installing $packageName...'); print('Installing $packageName...');
Map values = { var values = {
'project_name': pubspec.name, 'project_name': pubspec.name,
'pubspec': pubspec, 'pubspec': pubspec,
}; };
List<Glob> globs = []; var globs = <Glob>[];
var projectPubspec = await loadPubspec(packageDir); var projectPubspec = await loadPubspec(packageDir);
var deps = projectPubspec.dependencies.keys var deps = projectPubspec.dependencies.keys
.map((k) { .map((k) {
var dep = projectPubspec.dependencies[k]; var dep = projectPubspec.dependencies[k];
if (dep is HostedDependency) if (dep is HostedDependency) {
return MakerDependency(k, dep.version.toString()); return MakerDependency(k, dep.version.toString());
}
return null; return null;
}) })
.where((d) => d != null) .whereType<MakerDependency>()
.toList(); .toList();
deps.addAll(projectPubspec.devDependencies.keys.map((k) { deps.addAll(projectPubspec.devDependencies.keys.map((k) {
var dep = projectPubspec.devDependencies[k]; var dep = projectPubspec.devDependencies[k];
if (dep is HostedDependency) if (dep is HostedDependency) {
return MakerDependency(k, dep.version.toString(), dev: true); return MakerDependency(k, dep.version.toString(), dev: true);
}
return null; return null;
}).where((d) => d != null)); }).whereType<MakerDependency>());
await depend(deps); await depend(deps);
@ -125,11 +131,11 @@ class InstallCommand extends Command {
var desc = val[key]['description'] ?? key; var desc = val[key]['description'] ?? key;
if (val[key]['type'] == 'prompt') { if (val[key]['type'] == 'prompt') {
values[key] = prompts.get(desc.toString(), values[key as String] = prompts.get(desc.toString(),
defaultsTo: val[key]['default']?.toString()); defaultsTo: val[key]['default']?.toString());
} else if (val[key]['type'] == 'choice') { } else if (val[key]['type'] == 'choice') {
values[key] = prompts.choose( values[key as String] = prompts.choose(desc.toString(),
desc.toString(), val[key]['choices'] as Iterable); (val[key]['choices'] as Iterable) as Iterable<Object>)!;
} }
} }
} }
@ -151,7 +157,7 @@ class InstallCommand extends Command {
var name = p.basename(entity.path); var name = p.basename(entity.path);
var target = dst.uri.resolve(name); var target = dst.uri.resolve(name);
var targetFile = File.fromUri(target); var targetFile = File.fromUri(target);
bool allClear = !await targetFile.exists(); var allClear = !await targetFile.exists();
if (!allClear) { if (!allClear) {
print('The file ${entity.absolute.path} already exists.'); print('The file ${entity.absolute.path} already exists.');
@ -167,8 +173,10 @@ class InstallCommand extends Command {
print( print(
'Rendering Mustache template from ${entity.absolute.path} to ${targetFile.absolute.path}...'); 'Rendering Mustache template from ${entity.absolute.path} to ${targetFile.absolute.path}...');
var contents = await entity.readAsString(); var contents = await entity.readAsString();
var renderer = mustache.compile(contents); //var renderer = mustache.compile(contents);
var generated = renderer(values); //var generated = renderer(values);
var template = mustache.Template(contents);
var generated = template.renderString(values);
await targetFile.writeAsString(generated.toString()); await targetFile.writeAsString(generated.toString());
} else { } else {
print( print(
@ -197,9 +205,9 @@ class InstallCommand extends Command {
Future<List<Pubspec>> list() async { Future<List<Pubspec>> list() async {
if (!await installRepo.exists()) { if (!await installRepo.exists()) {
throw 'No local add-on database exists. Run `angel install --update` first.'; throw 'No local add-on database exists. Run `angel3 install --update` first.';
} else { } else {
List<Pubspec> repos = []; var repos = <Pubspec>[];
await for (var entity in installRepo.list()) { await for (var entity in installRepo.list()) {
if (entity is Directory) { if (entity is Directory) {
@ -236,7 +244,9 @@ class InstallCommand extends Command {
); );
} }
git..stdout.listen(stdout.add)..stderr.listen(stderr.add); git
..stdout.listen(stdout.add)
..stderr.listen(stderr.add);
var code = await git.exitCode; var code = await git.exitCode;

View file

@ -7,10 +7,10 @@ class KeyCommand extends Command {
String get name => 'key'; String get name => 'key';
@override @override
String get description => 'Generates a new `angel_auth` key.'; String get description => 'Generates a new `angel3_auth` key.';
@override @override
run() async { Future run() async {
var secret = rs.randomAlphaNumeric(32); var secret = rs.randomAlphaNumeric(32);
print('Generated new development JWT secret: $secret'); print('Generated new development JWT secret: $secret');
await changeSecret(File('config/default.yaml'), secret); await changeSecret(File('config/default.yaml'), secret);
@ -20,11 +20,11 @@ class KeyCommand extends Command {
await changeSecret(File('config/production.yaml'), secret); await changeSecret(File('config/production.yaml'), secret);
} }
changeSecret(File file, String secret) async { Future changeSecret(File file, String secret) async {
if (await file.exists()) { if (await file.exists()) {
var contents = await file.readAsString(); var contents = await file.readAsString();
contents = contents.replaceAll(RegExp(r'jwt_secret:[^\n]+\n?'), ''); contents = contents.replaceAll(RegExp(r'jwt_secret:[^\n]+\n?'), '');
await file.writeAsString(contents.trim() + '\njwt_secret: "$secret"'); await file.writeAsString('${contents.trim()}\njwt_secret: "$secret"');
} }
} }
} }

View file

@ -30,59 +30,60 @@ class ControllerCommand extends Command {
} }
@override @override
run() async { Future run() async {
var pubspec = await loadPubspec(); String? name;
String name; if (argResults?.wasParsed('name') == true) {
if (argResults.wasParsed('name')) name = argResults['name'] as String; name = argResults!['name'] as String?;
}
if (name?.isNotEmpty != true) { if (name?.isNotEmpty != true) {
name = prompts.get('Name of controller class'); name = prompts.get('Name of controller class');
} }
List<MakerDependency> deps = [ var deps = <MakerDependency>[
const MakerDependency('angel_framework', '^2.0.0') const MakerDependency('angel3_framework', '^7.0.0')
]; ];
//${pubspec.name}.src.models.${rc.snakeCase} //${pubspec.name}.src.models.${rc.snakeCase}
var rc = new ReCase(name); var rc = ReCase(name!);
var controllerLib = new Library((controllerLib) { var controllerLib = Library((controllerLib) {
if (argResults['websocket'] as bool) { if (argResults?['websocket'] as bool) {
deps.add(const MakerDependency('angel_websocket', '^2.0.0')); deps.add(const MakerDependency('angel3_websocket', '^7.0.0'));
controllerLib.directives controllerLib.directives
.add(new Directive.import('package:angel_websocket/server.dart')); .add(Directive.import('package:angel3_websocket/server.dart'));
} else { } else {
controllerLib.directives.add(new Directive.import( controllerLib.directives.add(
'package:angel_framework/angel_framework.dart')); Directive.import('package:angel3_framework/angel3_framework.dart'));
} }
controllerLib.body.add(new Class((clazz) { controllerLib.body.add(Class((clazz) {
clazz clazz
..name = '${rc.pascalCase}Controller' ..name = '${rc.pascalCase}Controller'
..extend = refer(argResults['websocket'] as bool ..extend = refer(argResults?['websocket'] as bool
? 'WebSocketController' ? 'WebSocketController'
: 'Controller'); : 'Controller');
if (argResults['websocket'] as bool) { if (argResults!['websocket'] as bool) {
// XController(AngelWebSocket ws) : super(ws); // XController(AngelWebSocket ws) : super(ws);
clazz.constructors.add(new Constructor((b) { clazz.constructors.add(Constructor((b) {
b b
..requiredParameters.add(new Parameter((b) => b ..requiredParameters.add(Parameter((b) => b
..name = 'ws' ..name = 'ws'
..type = refer('AngelWebSocket'))) ..type = refer('AngelWebSocket')))
..initializers.add(new Code('super(ws)')); ..initializers.add(Code('super(ws)'));
})); }));
clazz.methods.add(new Method((meth) { clazz.methods.add(Method((meth) {
meth meth
..name = 'hello' ..name = 'hello'
..returns = refer('void') ..returns = refer('void')
..annotations ..annotations
.add(refer('ExposeWs').call([literal('get_${rc.snakeCase}')])) .add(refer('ExposeWs').call([literal('get_${rc.snakeCase}')]))
..requiredParameters.add(new Parameter((b) => b ..requiredParameters.add(Parameter((b) => b
..name = 'socket' ..name = 'socket'
..type = refer('WebSocketContext'))) ..type = refer('WebSocketContext')))
..body = new Block((block) { ..body = Block((block) {
block.addExpression(refer('socket').property('send').call([ block.addExpression(refer('socket').property('send').call([
literal('got_${rc.snakeCase}'), literal('got_${rc.snakeCase}'),
literalMap({'message': literal('Hello, world!')}), literalMap({'message': literal('Hello, world!')}),
@ -93,7 +94,7 @@ class ControllerCommand extends Command {
clazz clazz
..annotations ..annotations
.add(refer('Expose').call([literal('/${rc.snakeCase}')])) .add(refer('Expose').call([literal('/${rc.snakeCase}')]))
..methods.add(new Method((meth) { ..methods.add(Method((meth) {
meth meth
..name = 'hello' ..name = 'hello'
..returns = refer('String') ..returns = refer('String')
@ -106,14 +107,15 @@ class ControllerCommand extends Command {
})); }));
}); });
var outputDir = new Directory.fromUri( var outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String)); Directory.current.uri.resolve(argResults?['output-dir'] as String));
var controllerFile = var controllerFile =
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart')); File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await controllerFile.exists()) if (!await controllerFile.exists()) {
await controllerFile.create(recursive: true); await controllerFile.create(recursive: true);
await controllerFile.writeAsString(new DartFormatter() }
.format(controllerLib.accept(new DartEmitter()).toString())); await controllerFile.writeAsString(
DartFormatter().format(controllerLib.accept(DartEmitter()).toString()));
print(green.wrap( print(green.wrap(
'$checkmark Created controller file "${controllerFile.absolute.path}"')); '$checkmark Created controller file "${controllerFile.absolute.path}"'));

View file

@ -6,7 +6,7 @@ class MakerDependency implements Comparable<MakerDependency> {
final String name, version; final String name, version;
final bool dev; final bool dev;
const MakerDependency(this.name, this.version, {this.dev: false}); const MakerDependency(this.name, this.version, {this.dev = false});
@override @override
int compareTo(MakerDependency other) => name.compareTo(other.name); int compareTo(MakerDependency other) => name.compareTo(other.name);
@ -18,10 +18,11 @@ Future depend(Iterable<MakerDependency> deps) async {
for (var dep in deps) { for (var dep in deps) {
var isPresent = false; var isPresent = false;
if (dep.dev) if (dep.dev) {
isPresent = pubspec.devDependencies.containsKey(dep.name); isPresent = pubspec.devDependencies.containsKey(dep.name);
else } else {
isPresent = pubspec.dependencies.containsKey(dep.name); isPresent = pubspec.dependencies.containsKey(dep.name);
}
if (!isPresent) { if (!isPresent) {
missing.add(dep); missing.add(dep);
@ -51,11 +52,11 @@ Future depend(Iterable<MakerDependency> deps) async {
print(yellow.wrap( print(yellow.wrap(
'Update your `pubspec.yaml` to add the following dependencies:\n')); 'Update your `pubspec.yaml` to add the following dependencies:\n'));
void printMissing(String type, Iterable<MakerDependency> deps) { void printMissing(String type, Iterable<MakerDependency?> deps) {
if (deps.isNotEmpty) { if (deps.isNotEmpty) {
print(yellow.wrap(' $type:')); print(yellow.wrap(' $type:'));
for (var dep in deps) { for (var dep in deps) {
print(yellow.wrap(' ${dep.name}: ${dep.version}')); print(yellow.wrap(' ${dep!.name}: ${dep.version}'));
} }
} }
} }

View file

@ -3,7 +3,7 @@ import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
import 'package:inflection2/inflection2.dart'; import 'package:inflection3/inflection3.dart';
import 'package:io/ansi.dart'; import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts; import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
@ -28,21 +28,23 @@ class MigrationCommand extends Command {
@override @override
FutureOr run() async { FutureOr run() async {
String name; String? name;
if (argResults.wasParsed('name')) name = argResults['name'] as String; if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) { if (name?.isNotEmpty != true) {
name = prompts.get('Name of model class'); name = prompts.get('Name of model class');
} }
var deps = [const MakerDependency('angel_migration', '^2.0.0')]; var deps = [const MakerDependency('angel3_migration', '^7.0.0')];
var rc = new ReCase(name); var rc = ReCase(name!);
var migrationLib = new Library((migrationLib) { var migrationLib = Library((migrationLib) {
migrationLib migrationLib
..directives.add(new Directive.import( ..directives.add(Directive.import(
'package:angel_migration.dart/angel_migration.dart')) 'package:angel3_migration.dart/angel3_migration.dart'))
..body.add(new Class((migrationClazz) { ..body.add(Class((migrationClazz) {
migrationClazz migrationClazz
..name = '${rc.pascalCase}Migration' ..name = '${rc.pascalCase}Migration'
..extend = refer('Migration'); ..extend = refer('Migration');
@ -50,21 +52,21 @@ class MigrationCommand extends Command {
var tableName = pluralize(rc.snakeCase); var tableName = pluralize(rc.snakeCase);
// up() // up()
migrationClazz.methods.add(new Method((up) { migrationClazz.methods.add(Method((up) {
up up
..name = 'up' ..name = 'up'
..returns = refer('void') ..returns = refer('void')
..annotations.add(refer('override')) ..annotations.add(refer('override'))
..requiredParameters.add(new Parameter((b) => b ..requiredParameters.add(Parameter((b) => b
..name = 'schema' ..name = 'schema'
..type = refer('Schema'))) ..type = refer('Schema')))
..body = new Block((block) { ..body = Block((block) {
// (table) { ... } // (table) { ... }
var callback = new Method((callback) { var callback = Method((callback) {
callback callback
..requiredParameters ..requiredParameters
.add(new Parameter((b) => b..name = 'table')) .add(Parameter((b) => b..name = 'table'))
..body = new Block((block) { ..body = Block((block) {
var table = refer('table'); var table = refer('table');
block.addExpression( block.addExpression(
@ -95,15 +97,15 @@ class MigrationCommand extends Command {
})); }));
// down() // down()
migrationClazz.methods.add(new Method((down) { migrationClazz.methods.add(Method((down) {
down down
..name = 'down' ..name = 'down'
..returns = refer('void') ..returns = refer('void')
..annotations.add(refer('override')) ..annotations.add(refer('override'))
..requiredParameters.add(new Parameter((b) => b ..requiredParameters.add(Parameter((b) => b
..name = 'schema' ..name = 'schema'
..type = refer('Schema'))) ..type = refer('Schema')))
..body = new Block((block) { ..body = Block((block) {
block.addExpression( block.addExpression(
refer('schema').property('drop').call([ refer('schema').property('drop').call([
literal(tableName), literal(tableName),
@ -115,15 +117,16 @@ class MigrationCommand extends Command {
}); });
// Save migration file // Save migration file
var migrationDir = new Directory.fromUri( var migrationDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String)); Directory.current.uri.resolve(argResults!['output-dir'] as String));
var migrationFile = var migrationFile =
new File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart')); File.fromUri(migrationDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await migrationFile.exists()) if (!await migrationFile.exists()) {
await migrationFile.create(recursive: true); await migrationFile.create(recursive: true);
}
await migrationFile.writeAsString(new DartFormatter() await migrationFile.writeAsString(
.format(migrationLib.accept(new DartEmitter()).toString())); DartFormatter().format(migrationLib.accept(DartEmitter()).toString()));
print(green.wrap( print(green.wrap(
'$checkmark Created migration file "${migrationFile.absolute.path}".')); '$checkmark Created migration file "${migrationFile.absolute.path}".'));

View file

@ -32,37 +32,39 @@ class ModelCommand extends Command {
} }
@override @override
run() async { Future run() async {
String name; String? name;
if (argResults.wasParsed('name')) name = argResults['name'] as String; if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) { if (name?.isNotEmpty != true) {
name = prompts.get('Name of model class'); name = prompts.get('Name of model class');
} }
List<MakerDependency> deps = [ var deps = <MakerDependency>[
const MakerDependency('angel_model', '^1.0.0'), const MakerDependency('angel3_model', '^3.0.0'),
]; ];
var rc = new ReCase(name); var rc = ReCase(name!);
var modelLib = new Library((modelLib) { var modelLib = Library((modelLib) {
if (argResults['orm'] as bool && argResults['migration'] as bool) { if (argResults?['orm'] as bool && argResults?['migration'] as bool) {
modelLib.directives.addAll([ modelLib.directives.addAll([
new Directive.import('package:angel_migration/angel_migration.dart'), Directive.import('package:angel3_migration/angel3_migration.dart'),
]); ]);
} }
var needsSerialize = var needsSerialize =
argResults['serializable'] as bool || argResults['orm'] as bool; argResults?['serializable'] as bool || argResults?['orm'] as bool;
// argResults['migration'] as bool; // argResults['migration'] as bool;
if (needsSerialize) { if (needsSerialize) {
modelLib.directives.add(new Directive.import( modelLib.directives.add(
'package:angel_serialize/angel_serialize.dart')); Directive.import('package:angel3_serialize/angel3_serialize.dart'));
deps.add(const MakerDependency('angel_serialize', '^2.0.0')); deps.add(const MakerDependency('angel3_serialize', '^7.0.0'));
deps.add(const MakerDependency('angel_serialize_generator', '^2.0.0')); deps.add(const MakerDependency('angel3_serialize_generator', '^7.0.0'));
deps.add(const MakerDependency('build_runner', '^1.0.0')); deps.add(const MakerDependency('build_runner', '^2.2.0'));
} }
// else { // else {
@ -71,18 +73,18 @@ class ModelCommand extends Command {
// deps.add(const MakerDependency('angel_model', '^1.0.0')); // deps.add(const MakerDependency('angel_model', '^1.0.0'));
// } // }
if (argResults['orm'] as bool) { if (argResults?['orm'] as bool) {
modelLib.directives.addAll([ modelLib.directives.addAll([
new Directive.import('package:angel_orm/angel_orm.dart'), Directive.import('package:angel3_orm/angel3_orm.dart'),
]); ]);
deps.add(const MakerDependency('angel_orm', '^2.0.0')); deps.add(const MakerDependency('angel3_orm', '^7.0.0'));
} }
modelLib.body.addAll([ modelLib.body.addAll([
new Code("part '${rc.snakeCase}.g.dart';"), Code("part '${rc.snakeCase}.g.dart';"),
]); ]);
modelLib.body.add(new Class((modelClazz) { modelLib.body.add(Class((modelClazz) {
modelClazz modelClazz
..abstract = true ..abstract = true
..name = needsSerialize ? '_${rc.pascalCase}' : rc.pascalCase ..name = needsSerialize ? '_${rc.pascalCase}' : rc.pascalCase
@ -93,8 +95,8 @@ class ModelCommand extends Command {
modelClazz.annotations.add(refer('serializable')); modelClazz.annotations.add(refer('serializable'));
} }
if (argResults['orm'] as bool) { if (argResults?['orm'] as bool) {
if (argResults['migration'] as bool) { if (argResults?['migration'] as bool) {
modelClazz.annotations.add(refer('orm')); modelClazz.annotations.add(refer('orm'));
} else { } else {
modelClazz.annotations.add( modelClazz.annotations.add(
@ -105,14 +107,13 @@ class ModelCommand extends Command {
}); });
// Save model file // Save model file
var outputDir = new Directory.fromUri( var outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String)); Directory.current.uri.resolve(argResults?['output-dir'] as String));
var modelFile = var modelFile = File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
new File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await modelFile.exists()) await modelFile.create(recursive: true); if (!await modelFile.exists()) await modelFile.create(recursive: true);
await modelFile.writeAsString(new DartFormatter() await modelFile.writeAsString(
.format(modelLib.accept(new DartEmitter()).toString())); DartFormatter().format(modelLib.accept(DartEmitter()).toString()));
print(green print(green
.wrap('$checkmark Created model file "${modelFile.absolute.path}".')); .wrap('$checkmark Created model file "${modelFile.absolute.path}".'));

View file

@ -10,10 +10,10 @@ import 'maker.dart';
class PluginCommand extends Command { class PluginCommand extends Command {
@override @override
String get name => "plugin"; String get name => 'plugin';
@override @override
String get description => "Creates a new plug-in within the given project."; String get description => 'Creates a new plug-in within the given project.';
PluginCommand() { PluginCommand() {
argParser argParser
@ -25,27 +25,29 @@ class PluginCommand extends Command {
} }
@override @override
run() async { Future run() async {
var pubspec = await loadPubspec(); var pubspec = await loadPubspec();
String name; String? name;
if (argResults.wasParsed('name')) name = argResults['name'] as String; if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) { if (name?.isNotEmpty != true) {
name = prompts.get('Name of plug-in class'); name = prompts.get('Name of plug-in class');
} }
List<MakerDependency> deps = [ var deps = <MakerDependency>[
const MakerDependency('angel_framework', '^2.0.0') const MakerDependency('angel3_framework', '^7.0.0')
]; ];
var rc = new ReCase(name); var rc = ReCase(name!);
final pluginDir = new Directory.fromUri( final pluginDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String)); Directory.current.uri.resolve(argResults!['output-dir'] as String));
final pluginFile = final pluginFile =
new File.fromUri(pluginDir.uri.resolve("${rc.snakeCase}.dart")); File.fromUri(pluginDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await pluginFile.exists()) await pluginFile.create(recursive: true); if (!await pluginFile.exists()) await pluginFile.create(recursive: true);
await pluginFile.writeAsString( await pluginFile
new DartFormatter().format(_generatePlugin(pubspec, rc))); .writeAsString(DartFormatter().format(_generatePlugin(pubspec, rc)));
if (deps.isNotEmpty) await depend(deps); if (deps.isNotEmpty) await depend(deps);
@ -57,7 +59,7 @@ class PluginCommand extends Command {
return ''' return '''
library ${pubspec.name}.src.config.plugins.${rc.snakeCase}; library ${pubspec.name}.src.config.plugins.${rc.snakeCase};
import 'package:angel_framework/angel_framework.dart'; import 'package:angel3_framework/angel3_framework.dart';
AngelConfigurer ${rc.camelCase}() { AngelConfigurer ${rc.camelCase}() {
return (Angel app) async { return (Angel app) async {

View file

@ -2,10 +2,9 @@ import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
import 'package:inflection2/inflection2.dart'; import 'package:inflection3/inflection3.dart';
import 'package:io/ansi.dart'; import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts; import 'package:prompts/prompts.dart' as prompts;
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import '../service_generators/service_generators.dart'; import '../service_generators/service_generators.dart';
import '../../util.dart'; import '../../util.dart';
@ -32,24 +31,26 @@ class ServiceCommand extends Command {
} }
@override @override
run() async { void run() async {
var pubspec = await loadPubspec(); await loadPubspec();
String name; String? name;
if (argResults.wasParsed('name')) name = argResults['name'] as String; if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) { if (name?.isNotEmpty != true) {
name = prompts.get('Name of service'); name = prompts.get('Name of service');
} }
List<MakerDependency> deps = [ var deps = <MakerDependency>[
const MakerDependency('angel_framework', '^2.0.0') const MakerDependency('angel3_framework', '^7.0.0')
]; ];
// '${pubspec.name}.src.services.${rc.snakeCase}' // '${pubspec.name}.src.services.${rc.snakeCase}'
var rc = new ReCase(name); var rc = ReCase(name!);
var serviceLib = new Library((serviceLib) { var serviceLib = Library((serviceLib) {
var generator = prompts.choose( var generator = prompts.choose(
'Choose which type of service to create', serviceGenerators); 'Choose which type of service to create', serviceGenerators)!;
// if (generator == null) { // if (generator == null) {
// _pen.red(); // _pen.red();
@ -62,56 +63,61 @@ class ServiceCommand extends Command {
if (!deps.any((d) => d.name == dep.name)) deps.add(dep); if (!deps.any((d) => d.name == dep.name)) deps.add(dep);
} }
if (generator.goesFirst) { if (name != null && generator.goesFirst) {
generator.applyToLibrary(serviceLib, name, rc.snakeCase); generator.applyToLibrary(serviceLib, name, rc.snakeCase);
serviceLib.directives.add(new Directive.import( serviceLib.directives.add(
'package:angel_framework/angel_framework.dart')); Directive.import('package:angel3_framework/angel3_framework.dart'));
} else { } else if (name != null) {
serviceLib.directives.add(new Directive.import( serviceLib.directives.add(
'package:angel_framework/angel_framework.dart')); Directive.import('package:angel3_framework/angel3_framework.dart'));
generator.applyToLibrary(serviceLib, name, rc.snakeCase); generator.applyToLibrary(serviceLib, name, rc.snakeCase);
} }
if (argResults['typed'] as bool) { if (argResults!['typed'] as bool) {
serviceLib.directives serviceLib.directives
.add(new Directive.import('../models/${rc.snakeCase}.dart')); .add(Directive.import('../models/${rc.snakeCase}.dart'));
} }
// configureServer() {} // configureServer() {}
serviceLib.body.add(new Method((configureServer) { serviceLib.body.add(Method((configureServer) {
configureServer configureServer
..name = 'configureServer' ..name = 'configureServer'
..returns = refer('AngelConfigurer'); ..returns = refer('AngelConfigurer');
configureServer.body = new Block((block) { configureServer.body = Block((block) {
generator.applyToConfigureServer( if (name != null) {
serviceLib, configureServer, block, name, rc.snakeCase); generator.applyToConfigureServer(
serviceLib, configureServer, block, name, rc.snakeCase);
}
// return (Angel app) async {} // return (Angel app) async {}
var closure = new Method((closure) { var closure = Method((closure) {
closure closure
..modifier = MethodModifier.async ..modifier = MethodModifier.async
..requiredParameters.add(new Parameter((b) => b ..requiredParameters.add(Parameter((b) => b
..name = 'app' ..name = 'app'
..type = refer('Angel'))); ..type = refer('Angel')));
closure.body = new Block((block) {
generator.beforeService(serviceLib, block, name, rc.snakeCase);
// app.use('/api/todos', new MapService()); closure.body = Block((block) {
var service = generator.createInstance( if (name != null) {
serviceLib, closure, name, rc.snakeCase); generator.beforeService(serviceLib, block, name, rc.snakeCase);
if (argResults['typed'] as bool) { // app.use('/api/todos', new MapService());
var tb = new TypeReference((b) => b var service = generator.createInstance(
..symbol = 'TypedService' serviceLib, closure, name, rc.snakeCase);
..types.add(refer(rc.pascalCase)));
service = tb.newInstance([service]); if (argResults!['typed'] as bool) {
var tb = TypeReference((b) => b
..symbol = 'TypedService'
..types.add(refer(rc.pascalCase)));
service = tb.newInstance([service]);
}
block.addExpression(refer('app').property('use').call([
literal('/api/${pluralize(rc.snakeCase)}'),
service,
]));
} }
block.addExpression(refer('app').property('use').call([
literal('/api/${pluralize(rc.snakeCase)}'),
service,
]));
}); });
}); });
@ -120,13 +126,13 @@ class ServiceCommand extends Command {
})); }));
}); });
final outputDir = new Directory.fromUri( final outputDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String)); Directory.current.uri.resolve(argResults!['output-dir'] as String));
final serviceFile = final serviceFile =
new File.fromUri(outputDir.uri.resolve("${rc.snakeCase}.dart")); File.fromUri(outputDir.uri.resolve('${rc.snakeCase}.dart'));
if (!await serviceFile.exists()) await serviceFile.create(recursive: true); if (!await serviceFile.exists()) await serviceFile.create(recursive: true);
await serviceFile.writeAsString(new DartFormatter() await serviceFile.writeAsString(
.format(serviceLib.accept(new DartEmitter()).toString())); DartFormatter().format(serviceLib.accept(DartEmitter()).toString()));
print(green.wrap( print(green.wrap(
'$checkmark Successfully generated service file "${serviceFile.absolute.path}".')); '$checkmark Successfully generated service file "${serviceFile.absolute.path}".'));

View file

@ -10,10 +10,10 @@ import 'maker.dart';
class TestCommand extends Command { class TestCommand extends Command {
@override @override
String get name => "test"; String get name => 'test';
@override @override
String get description => "Creates a new test within the given project."; String get description => 'Creates a new test within the given project.';
TestCommand() { TestCommand() {
argParser argParser
@ -28,37 +28,39 @@ class TestCommand extends Command {
} }
@override @override
run() async { Future run() async {
var pubspec = await loadPubspec(); var pubspec = await loadPubspec();
String name; String? name;
if (argResults.wasParsed('name')) name = argResults['name'] as String; if (argResults?.wasParsed('name') == true) {
name = argResults?['name'] as String?;
}
if (name?.isNotEmpty != true) { if (name?.isNotEmpty != true) {
name = prompter.get('Name of test'); name = prompter.get('Name of test');
} }
List<MakerDependency> deps = [ var deps = <MakerDependency>[
const MakerDependency('angel_framework', '^2.0.0'), const MakerDependency('angel3_framework', '^7.0.0'),
const MakerDependency('angel_test', '^2.0.0', dev: true), const MakerDependency('angel3_test', '^7.0.0', dev: true),
const MakerDependency('test', '^1.0.0', dev: true), const MakerDependency('test', '^1.21.0', dev: true),
]; ];
var rc = new ReCase(name); var rc = ReCase(name!);
final testDir = new Directory.fromUri( final testDir = Directory.fromUri(
Directory.current.uri.resolve(argResults['output-dir'] as String)); Directory.current.uri.resolve(argResults?['output-dir'] as String));
final testFile = final testFile =
new File.fromUri(testDir.uri.resolve("${rc.snakeCase}_test.dart")); File.fromUri(testDir.uri.resolve('${rc.snakeCase}_test.dart'));
if (!await testFile.exists()) await testFile.create(recursive: true); if (!await testFile.exists()) await testFile.create(recursive: true);
await testFile await testFile
.writeAsString(new DartFormatter().format(_generateTest(pubspec, rc))); .writeAsString(DartFormatter().format(_generateTest(pubspec, rc)));
if (deps.isNotEmpty) await depend(deps); if (deps.isNotEmpty) await depend(deps);
print(green.wrap( print(green.wrap(
'$checkmark Successfully generated test file "${testFile.absolute.path}".')); '$checkmark Successfully generated test file "${testFile.absolute.path}".'));
if (argResults['run-configuration'] as bool) { if (argResults!['run-configuration'] as bool) {
final runConfig = new File.fromUri(Directory.current.uri final runConfig = File.fromUri(Directory.current.uri
.resolve('.idea/runConfigurations/${name}_Tests.xml')); .resolve('.idea/runConfigurations/${name}_Tests.xml'));
if (!await runConfig.exists()) await runConfig.create(recursive: true); if (!await runConfig.exists()) await runConfig.create(recursive: true);
@ -85,15 +87,15 @@ class TestCommand extends Command {
return ''' return '''
import 'dart:io'; import 'dart:io';
import 'package:${pubspec.name}/${pubspec.name}.dart' as ${pubspec.name}; import 'package:${pubspec.name}/${pubspec.name}.dart' as ${pubspec.name};
import 'package:angel_framework/angel_framework.dart'; import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel_test/angel_test.dart'; import 'package:angel3_test/angel3_test.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
main() async { main() async {
TestClient client; TestClient client;
setUp(() async { setUp(() async {
var app = new Angel(); var app = Angel();
await app.configure(${pubspec.name}.configureServer); await app.configure(${pubspec.name}.configureServer);
client = await connectTo(app); client = await connectTo(app);
}); });

View file

@ -2,11 +2,13 @@ import 'dart:io';
final RegExp _leadingSlashes = RegExp(r'^/+'); final RegExp _leadingSlashes = RegExp(r'^/+');
@Deprecated("Replaced by dart pub")
String resolvePub() { String resolvePub() {
var exec = File(Platform.resolvedExecutable); var exec = File(Platform.resolvedExecutable);
var pubPath = exec.parent.uri.resolve('pub').path; var pubPath = exec.parent.uri.resolve('pub').path;
if (Platform.isWindows) if (Platform.isWindows) {
pubPath = pubPath.replaceAll(_leadingSlashes, '') + '.bat'; pubPath = '${pubPath.replaceAll(_leadingSlashes, '')}.bat';
}
pubPath = Uri.decodeFull(pubPath); pubPath = Uri.decodeFull(pubPath);
return pubPath; return pubPath;
} }

View file

@ -8,8 +8,6 @@ import 'package:glob/list_local_fs.dart';
import 'package:io/ansi.dart'; import 'package:io/ansi.dart';
import 'package:prompts/prompts.dart' as prompts; import 'package:prompts/prompts.dart' as prompts;
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import '../util.dart';
import 'pub.dart';
class RenameCommand extends Command { class RenameCommand extends Command {
@override @override
@ -22,16 +20,16 @@ class RenameCommand extends Command {
String get invocation => '$name <new name>'; String get invocation => '$name <new name>';
@override @override
run() async { Future run() async {
String newName; String? newName;
if (argResults.rest.isNotEmpty) if (argResults?.rest.isNotEmpty == true) {
newName = argResults.rest.first; newName = argResults?.rest.first;
else { } else {
newName = prompts.get('Rename project to'); newName = prompts.get('Rename project to');
} }
newName = ReCase(newName).snakeCase; newName = ReCase(newName!).snakeCase;
var choice = prompts.getBool('Rename the project to `$newName`?'); var choice = prompts.getBool('Rename the project to `$newName`?');
@ -63,7 +61,7 @@ class RenameCommand extends Command {
} }
} }
renamePubspec(Directory dir, String oldName, String newName) async { Future renamePubspec(Directory dir, String oldName, String newName) async {
// var pubspec = await loadPubspec(dir); // var pubspec = await loadPubspec(dir);
print(cyan.wrap('Renaming your project to `$newName.`')); print(cyan.wrap('Renaming your project to `$newName.`'));
@ -86,13 +84,13 @@ renamePubspec(Directory dir, String oldName, String newName) async {
// await newPubspec.save(dir); // await newPubspec.save(dir);
} }
renameDartFiles(Directory dir, String oldName, String newName) async { Future renameDartFiles(Directory dir, String oldName, String newName) async {
if (!await dir.exists()) return; if (!await dir.exists()) return;
// Try to replace MongoDB URL // Try to replace MongoDB URL
var configGlob = Glob('config/**/*.yaml'); // Replace name in config directory
try { try {
var configGlob = Glob('config/**/*.yaml');
await for (var yamlFile in configGlob.list(root: dir.absolute.path)) { await for (var yamlFile in configGlob.list(root: dir.absolute.path)) {
if (yamlFile is File) { if (yamlFile is File) {
print( print(
@ -113,12 +111,58 @@ renameDartFiles(Directory dir, String oldName, String newName) async {
print('Renaming library file `${entry.absolute.path}`...'); print('Renaming library file `${entry.absolute.path}`...');
} }
// Replace package:oldName/oldName.dart with package:newName/newName.dart
// Replace package:oldName/ with package:newName/
String updateImport(String content, String oldName, String newName) {
if (!content.startsWith('import')) {
return content;
}
if (content.contains('package:$oldName/$oldName.dart')) {
return content.replaceFirst(
'package:$oldName/$oldName.dart', 'package:$newName/$newName.dart');
}
if (content.contains('package:$oldName/')) {
return content.replaceFirst('package:$oldName/', 'package:$newName/');
}
return content;
}
// Replace mustache {{oldName}} with newName
String updateMustacheBinding(String content, String oldName, String newName) {
if (content.contains('{{$oldName}}')) {
return content.replaceAll('{{$oldName}}', newName);
}
return content;
}
var fmt = DartFormatter();
await for (FileSystemEntity file in dir.list(recursive: true)) {
if (file is File && file.path.endsWith('.dart')) {
var lineList = await file.readAsLines();
if (oldName.isNotEmpty && newName.isNotEmpty) {
var contents = lineList.fold<String>('', (prev, cur) {
var updatedCur = updateImport(cur, oldName, newName);
updatedCur = updateMustacheBinding(updatedCur, oldName, newName);
return '$prev\n$updatedCur';
});
await file.writeAsString(fmt.format(contents));
print('Updated file `${file.absolute.path}`.');
}
}
}
/* Deprecated, Not working
var fmt = DartFormatter(); var fmt = DartFormatter();
await for (FileSystemEntity file in dir.list(recursive: true)) { await for (FileSystemEntity file in dir.list(recursive: true)) {
if (file is File && file.path.endsWith('.dart')) { if (file is File && file.path.endsWith('.dart')) {
var contents = await file.readAsString(); var contents = await file.readAsString();
// TODO: Issue to be fixed: parseCompilationUnit uses Hubbub library which uses discontinued Google front_end library
// front_end package. Temporarily commeted out // front_end package. Temporarily commeted out
//var ast = parseCompilationUnit(contents); //var ast = parseCompilationUnit(contents);
var visitor = RenamingVisitor(oldName, newName); var visitor = RenamingVisitor(oldName, newName);
@ -128,7 +172,7 @@ renameDartFiles(Directory dir, String oldName, String newName) async {
visitor.replace.forEach((range, replacement) { visitor.replace.forEach((range, replacement) {
if (range.first is int) { if (range.first is int) {
contents = contents.replaceRange( contents = contents.replaceRange(
range.first as int, range.last as int, replacement); range.first as int, range.last as int?, replacement);
} else if (range.first is String) { } else if (range.first is String) {
contents = contents.replaceAll(range.first as String, replacement); contents = contents.replaceAll(range.first as String, replacement);
} }
@ -139,6 +183,7 @@ renameDartFiles(Directory dir, String oldName, String newName) async {
} }
} }
} }
*/
} }
class RenamingVisitor extends RecursiveAstVisitor { class RenamingVisitor extends RecursiveAstVisitor {
@ -153,41 +198,49 @@ class RenamingVisitor extends RecursiveAstVisitor {
if (uri == 'package:$oldName/$oldName.dart') { if (uri == 'package:$oldName/$oldName.dart') {
return 'package:$newName/$newName.dart'; return 'package:$newName/$newName.dart';
} else if (uri.startsWith('package:$oldName/')) { } else if (uri.startsWith('package:$oldName/')) {
return 'package:$newName/' + uri.replaceFirst('package:$oldName/', ''); return 'package:$newName/${uri.replaceFirst('package:$oldName/', '')}';
} else } else {
return uri; return uri;
}
@override
visitExportDirective(ExportDirective ctx) {
var uri = ctx.uri.stringValue, updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
@override
visitImportDirective(ImportDirective ctx) {
var uri = ctx.uri.stringValue, updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
@override
visitLibraryDirective(LibraryDirective ctx) {
var name = ctx.name.name;
if (name.startsWith(oldName)) {
replace[[ctx.offset, ctx.end]] =
'library ' + name.replaceFirst(oldName, newName) + ';';
} }
} }
@override @override
visitPartOfDirective(PartOfDirective ctx) { void visitExportDirective(ExportDirective node) {
if (ctx.libraryName != null) { var uri = node.uri.stringValue;
var name = ctx.libraryName.name; if (uri != null) {
var updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
}
@override
void visitImportDirective(ImportDirective node) {
var uri = node.uri.stringValue;
if (uri != null) {
var updated = updateUri(uri);
if (uri != updated) replace[[uri]] = updated;
}
}
@override
void visitLibraryDirective(LibraryDirective node) {
var name = node.name2?.name ?? '';
if (name.startsWith(oldName)) {
replace[[node.offset, node.end]] =
'library ${name.replaceFirst(oldName, newName)};';
}
}
@override
void visitPartOfDirective(PartOfDirective node) {
if (node.libraryName != null) {
var name = node.libraryName!.name;
if (name.startsWith(oldName)) { if (name.startsWith(oldName)) {
replace[[ctx.offset, ctx.end]] = replace[[node.offset, node.end]] =
'part of ' + name.replaceFirst(oldName, newName) + ';'; 'part of ${name.replaceFirst(oldName, newName)};';
} }
} }
} }

View file

@ -2,10 +2,8 @@ import 'package:code_builder/code_builder.dart';
import 'generator.dart'; import 'generator.dart';
class CustomServiceGenerator extends ServiceGenerator { class CustomServiceGenerator extends ServiceGenerator {
@override
bool get createsModel => false; bool get createsModel => false;
@override
bool get createsValidator => false; bool get createsValidator => false;
const CustomServiceGenerator() : super('Custom'); const CustomServiceGenerator() : super('Custom');

View file

@ -1,6 +1,6 @@
import 'generator.dart'; import 'generator.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:inflection2/inflection2.dart'; import 'package:inflection3/inflection3.dart';
import '../make/maker.dart'; import '../make/maker.dart';
class FileServiceGenerator extends ServiceGenerator { class FileServiceGenerator extends ServiceGenerator {
@ -8,7 +8,7 @@ class FileServiceGenerator extends ServiceGenerator {
@override @override
List<MakerDependency> get dependencies => List<MakerDependency> get dependencies =>
const [const MakerDependency('angel_file_service', '^2.0.0')]; const [MakerDependency('angel3_file_service', '^7.0.0')];
@override @override
bool get goesFirst => true; bool get goesFirst => true;
@ -18,9 +18,9 @@ class FileServiceGenerator extends ServiceGenerator {
LibraryBuilder library, LibraryBuilder library,
MethodBuilder configureServer, MethodBuilder configureServer,
BlockBuilder block, BlockBuilder block,
String name, String? name,
String lower) { String lower) {
configureServer.requiredParameters.add(new Parameter((b) => b configureServer.requiredParameters.add(Parameter((b) => b
..name = 'dbDirectory' ..name = 'dbDirectory'
..type = refer('Directory'))); ..type = refer('Directory')));
} }
@ -28,8 +28,7 @@ class FileServiceGenerator extends ServiceGenerator {
@override @override
void applyToLibrary(LibraryBuilder library, String name, String lower) { void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([ library.directives.addAll([
new Directive.import( Directive.import('package:angel3_file_service/angel3_file_service.dart'),
'package:angel_file_service/angel_file_service.dart'),
]); ]);
} }
@ -37,12 +36,12 @@ class FileServiceGenerator extends ServiceGenerator {
Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder, Expression createInstance(LibraryBuilder library, MethodBuilder methodBuilder,
String name, String lower) { String name, String lower) {
library.directives.addAll([ library.directives.addAll([
new Directive.import('package:file/file.dart'), Directive.import('package:file/file.dart'),
]); ]);
return refer('JsonFileService').newInstance([ return refer('JsonFileService').newInstance([
refer('dbDirectory') refer('dbDirectory')
.property('childFile') .property('childFile')
.call([literal(pluralize(lower) + '_db.json')]) .call([literal('${pluralize(lower)}_db.json')])
]); ]);
} }
} }

View file

@ -8,21 +8,6 @@ class ServiceGenerator {
List<MakerDependency> get dependencies => []; List<MakerDependency> get dependencies => [];
@deprecated
bool get createsModel => true;
@deprecated
bool get createsValidator => true;
@deprecated
bool get exportedInServiceLibrary => true;
@deprecated
bool get injectsSingleton => false;
@deprecated
bool get shouldRunBuild => false;
bool get goesFirst => false; bool get goesFirst => false;
void applyToLibrary(LibraryBuilder library, String name, String lower) {} void applyToLibrary(LibraryBuilder library, String name, String lower) {}

View file

@ -4,7 +4,6 @@ import 'package:code_builder/code_builder.dart';
class MapServiceGenerator extends ServiceGenerator { class MapServiceGenerator extends ServiceGenerator {
const MapServiceGenerator() : super('In-Memory'); const MapServiceGenerator() : super('In-Memory');
@override
bool get createsModel => false; bool get createsModel => false;
@override @override

View file

@ -1,6 +1,6 @@
import 'generator.dart'; import 'generator.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:inflection2/inflection2.dart'; import 'package:inflection3/inflection3.dart';
import '../make/maker.dart'; import '../make/maker.dart';
class MongoServiceGenerator extends ServiceGenerator { class MongoServiceGenerator extends ServiceGenerator {
@ -8,9 +8,8 @@ class MongoServiceGenerator extends ServiceGenerator {
@override @override
List<MakerDependency> get dependencies => List<MakerDependency> get dependencies =>
const [const MakerDependency('angel_mongo', '^2.0.0')]; const [MakerDependency('angel3_mongo', '^4.0.0')];
@override
bool get createsModel => false; bool get createsModel => false;
@override @override
@ -18,9 +17,9 @@ class MongoServiceGenerator extends ServiceGenerator {
LibraryBuilder library, LibraryBuilder library,
MethodBuilder configureServer, MethodBuilder configureServer,
BlockBuilder block, BlockBuilder block,
String name, String? name,
String lower) { String lower) {
configureServer.requiredParameters.add(new Parameter((b) => b configureServer.requiredParameters.add(Parameter((b) => b
..name = 'db' ..name = 'db'
..type = refer('Db'))); ..type = refer('Db')));
} }
@ -28,8 +27,8 @@ class MongoServiceGenerator extends ServiceGenerator {
@override @override
void applyToLibrary(LibraryBuilder library, String name, String lower) { void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([ library.directives.addAll([
new Directive.import('package:angel_mongo/angel_mongo.dart'), Directive.import('package:angel3_mongo/angel3_mongo.dart'),
new Directive.import('package:mongo_dart/mongo_dart.dart'), Directive.import('package:mongo_dart/mongo_dart.dart'),
]); ]);
} }

View file

@ -1,6 +1,6 @@
import 'generator.dart'; import 'generator.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:inflection2/inflection2.dart'; import 'package:inflection3/inflection3.dart';
import '../make/maker.dart'; import '../make/maker.dart';
class RethinkServiceGenerator extends ServiceGenerator { class RethinkServiceGenerator extends ServiceGenerator {
@ -8,9 +8,8 @@ class RethinkServiceGenerator extends ServiceGenerator {
@override @override
List<MakerDependency> get dependencies => List<MakerDependency> get dependencies =>
const [const MakerDependency('angel_rethink', '^2.0.0')]; const [MakerDependency('angel3_rethink', '^4.0.0')];
@override
bool get createsModel => false; bool get createsModel => false;
@override @override
@ -18,13 +17,13 @@ class RethinkServiceGenerator extends ServiceGenerator {
LibraryBuilder library, LibraryBuilder library,
MethodBuilder configureServer, MethodBuilder configureServer,
BlockBuilder block, BlockBuilder block,
String name, String? name,
String lower) { String lower) {
configureServer.requiredParameters.addAll([ configureServer.requiredParameters.addAll([
new Parameter((b) => b Parameter((b) => b
..name = 'connection' ..name = 'connection'
..type = refer('Connection')), ..type = refer('Connection')),
new Parameter((b) => b Parameter((b) => b
..name = 'r' ..name = 'r'
..type = refer('Rethinkdb')), ..type = refer('Rethinkdb')),
]); ]);
@ -33,9 +32,9 @@ class RethinkServiceGenerator extends ServiceGenerator {
@override @override
void applyToLibrary(LibraryBuilder library, String name, String lower) { void applyToLibrary(LibraryBuilder library, String name, String lower) {
library.directives.addAll([ library.directives.addAll([
'package:angel_rethink/angel_rethink.dart', 'package:angel3_rethink/angel3_rethink.dart',
'package:rethinkdb_dart/rethinkdb_dart.dart' 'package:rethinkdb_dart/rethinkdb_dart.dart'
].map((str) => new Directive.import(str))); ].map((str) => Directive.import(str)));
} }
@override @override

View file

@ -6,10 +6,10 @@ import 'mongo.dart';
import 'rethink.dart'; import 'rethink.dart';
export 'generator.dart'; export 'generator.dart';
const List<ServiceGenerator> serviceGenerators = const [ const List<ServiceGenerator> serviceGenerators = [
const MapServiceGenerator(), MapServiceGenerator(),
const FileServiceGenerator(), FileServiceGenerator(),
const MongoServiceGenerator(), MongoServiceGenerator(),
const RethinkServiceGenerator(), RethinkServiceGenerator(),
const CustomServiceGenerator() CustomServiceGenerator()
]; ];

View file

@ -7,7 +7,7 @@ final Random _rnd = Random.secure();
String randomAlphaNumeric(int length) { String randomAlphaNumeric(int length) {
var b = StringBuffer(); var b = StringBuffer();
for (int i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
b.writeCharCode(_valid.codeUnitAt(_rnd.nextInt(_valid.length))); b.writeCharCode(_valid.codeUnitAt(_rnd.nextInt(_valid.length)));
} }

View file

@ -10,18 +10,18 @@ final String checkmark = ansiOutputEnabled ? '\u2714' : '[Success]';
final String ballot = ansiOutputEnabled ? '\u2717' : '[Failure]'; final String ballot = ansiOutputEnabled ? '\u2717' : '[Failure]';
String get homeDirPath => String get homeDirPath =>
Platform.environment['HOME'] ?? Platform.environment['USERPROFILE']; Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'] ?? '.';
Directory get homeDir => new Directory(homeDirPath); Directory get homeDir => Directory(homeDirPath);
Directory get angelDir => Directory(p.join(homeDir.path, '.angel')); Directory get angelDir => Directory(p.join(homeDir.path, '.angel'));
Future<Pubspec> loadPubspec([Directory directory]) { Future<Pubspec> loadPubspec([Directory? directory]) {
directory ??= Directory.current; directory ??= Directory.current;
var file = new File.fromUri(directory.uri.resolve('pubspec.yaml')); var file = File.fromUri(directory.uri.resolve('pubspec.yaml'));
return file return file
.readAsString() .readAsString()
.then((yaml) => new Pubspec.parse(yaml, sourceUrl: file.uri)); .then((yaml) => Pubspec.parse(yaml, sourceUrl: file.uri));
} }
// From: https://gist.github.com/tobischw/98dcd2563eec9a2a87bda8299055358a // From: https://gist.github.com/tobischw/98dcd2563eec9a2a87bda8299055358a

View file

@ -1,27 +1,29 @@
#author: Tobe O <thosakwe@gmail.com> name: angel3_cli
description: Command-line tools for the Angel framework, including scaffolding. version: 8.2.0
homepage: https://github.com/dukefirehawk/angel/packages/angel_cli description: The command line interface for building dart backend in Angel3 framework.
name: angel_cli homepage: https://angel3-framework.web.app/
version: 3.0.0 repository: https://github.com/dart-backend/angel3-cli
environment: environment:
sdk: ">=2.10.0 <3.0.0" sdk: '>=3.0.0 <4.0.0'
dependencies: dependencies:
analyzer: ^1.1.0 analyzer: ^6.3.0
args: ^2.0.0 args: ^2.4.0
code_builder: ^3.0.0 code_builder: ^4.5.0
dart_style: ^1.0.0 dart_style: ^2.3.0
glob: ^2.0.0 glob: ^2.1.0
http: ^0.13.0 http: ^1.0.0
io: ^0.3.5 io: ^1.0.0
inflection2: ^0.4.2 inflection3: ^0.5.3+2
mustache4dart2: ^0.1.0 mustache_template: ^2.0.0
path: ^1.0.0 path: ^1.9.0
prompts: ^1.3.1 prompts: ^2.0.0
pubspec_parse: ^1.0.0 pubspec_parse: ^1.2.0
quiver: ^3.0.0 quiver: ^3.2.0
recase: ^3.0.1 recase: ^4.1.0
shutdown: ^0.4.0 shutdown: ^0.4.3
watcher: ^1.0.0 watcher: ^1.1.0
yaml: ^3.0.0 yaml: ^3.1.0
dev_dependencies:
lints: ^3.0.0
executables: executables:
angel: angel angel3: angel3

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

53
test/replace_name.dart Normal file
View file

@ -0,0 +1,53 @@
import 'dart:io';
import 'package:dart_style/dart_style.dart';
void main() async {
String updateImport(String content, String oldName, String newName) {
if (!content.startsWith('import')) {
return content;
}
if (content.contains('package:$oldName/$oldName.dart')) {
return content.replaceFirst(
'package:$oldName/$oldName.dart', 'package:$newName/$newName.dart');
}
if (content.contains('package:$oldName/')) {
return content.replaceFirst('package:$oldName/', 'package:$newName/');
}
return content;
}
String updateMustacheBinding(String content, String oldName, String newName) {
if (content.contains('{{$oldName}}')) {
return content.replaceAll('{{$oldName}}', newName);
}
return content;
}
var fmt = DartFormatter();
var dir = Directory('graph');
await for (FileSystemEntity file in dir.list(recursive: true)) {
if (file is File && file.path.endsWith('.dart')) {
var lineList = await file.readAsLines();
var oldName = 'angel';
var newName = 'graph';
var replace = {oldName: newName};
if (replace.isNotEmpty) {
var contents = lineList.fold<String>('', (prev, cur) {
var updatedCur = updateImport(cur, oldName, newName);
updatedCur = updateMustacheBinding(updatedCur, oldName, newName);
return '$prev\n$updatedCur';
});
await file.writeAsString(fmt.format(contents));
print('Updated file `${file.absolute.path}`.');
}
}
}
}