Rename a newly-created directory using Yeoman (mem-fs-editor) - yeoman

I'm trying to rename a folder in the destination directory. The directory structure inside my templates folder looks like this:
root/
├── generators
│ └── app
│ ├── templates
│ │ └── app
│ │ └── widget
│ │ ├── widget.controller.ts
│ │ ├── widget.service.ts
│ │ └── widget.module.ts
│ └── index.js
└── .yo-rc.json
I'm trying to rename the widget directory (in destinationPath) to a name that the user enters during the prompting stage. Here's how I'm attempting this:
module.exports = generators.Base.extend({
copyAppTemplate: function () {
this.fs.copyTpl(this.templatePath('**/*'), this.destinationPath('.'), this.props);
this.fs.move(
this.destinationPath('app/widget'),
this.destinationPath('app/' + this.props.widgetName)
);
}
})
The call to copyTpl is correctly scaffolding and templating the app from the templatePath to the destinationPath. However, when the fs.move operation is called, I get the following error message:
PS C:\Users\username\code\generator-dashboard-widget-test> yo dashboard-widget
? Your widget's name: (generator-dashboard-widget-test)
? Your widget's name: generator-dashboard-widget-test
events.js:154
throw er; // Unhandled 'error' event
^
AssertionError: Trying to copy from a source that does not exist: C:\Users\username\code\generator-dashboard-widget-test\app\widget
at EditionInterface.exports._copySingle (C:\Users\username\code\generator-dashboard-widget\node_modules\mem-fs-editor\lib\actions\copy.js:45:3)
at EditionInterface.exports.copy (C:\Users\username\code\generator-dashboard-widget\node_modules\mem-fs-editor\lib\actions\copy.js:23:17)
at EditionInterface.module.exports [as move] (C:\Users\username\code\generator-dashboard-widget\node_modules\mem-fs-editor\lib\actions\move.js:4:8)
at module.exports.generators.Base.extend.copyAppTemplate (C:\Users\username\code\generator-dashboard-widget\generators\app\index.js:54:17)
at Object.<anonymous> (C:\Users\username\code\generator-dashboard-widget\node_modules\yeoman-generator\lib\base.js:431:23)
at C:\Users\username\code\generator-dashboard-widget\node_modules\run-async\index.js:26:25
at C:\Users\username\code\generator-dashboard-widget\node_modules\run-async\index.js:25:19
at C:\Users\username\code\generator-dashboard-widget\node_modules\yeoman-generator\lib\base.js:432:9
at processImmediate [as _immediateCallback] (timers.js:383:17)
From what I understand from the Yeoman file system documenation, all actions on the virtual file system are synchronous, so the app/widget directory should exist before the mem-fs-editor instance attempts to move it.
Is there a different way I should be renaming the directory?
I'm using Yeoman 1.8.4 on Windows 8.1 with node 5.6.0.

I didn't figure out this specific issue, but I was able to accomplish what I was after by using the gulp-rename plugin as a transform stream:
copyAppTemplate: function () {
var _this = this;
// move a file like "app/widget/widget.controller.ts" to
// "app/my-widget-name/my-widget-name.controller.ts"
this.registerTransformStream(rename(function (path) {
path.dirname = path.dirname.replace('widget', _this.props.widgetName);
path.basename = path.basename.replace('widget', _this.props.widgetName);
return path;
}));
this.fs.copyTpl(this.templatePath('**/*'), this.destinationPath('.'), this.props);
},
I've also opened up a GitHub issue to follow up with this behavior here: https://github.com/yeoman/yo/issues/455

Related

Terraform.tf parameterize or template for different environment

This is the terraform.tf file. I want to give different values based on the environment for 'name' field. How can I do it?
provider "azurerm" {
version = "=2.46.0"
features {}
}
terraform {
backend "azurerm" {
resource_group_name = "rgtstate"
storage_account_name = "adststorage"
container_name = "terraform.tfstate"
# access_key = ""
}
}
data "azurerm_client_config" "current" {}
resource "azurerm_resource_group" "resourcegroup" {
name = "sk-terraform-rg"
location = "west europe"
}
resource "azurerm_data_factory" "example" {
name = "adfSB"
location = azurerm_resource_group.resourcegroup.location
resource_group_name = azurerm_resource_group.resourcegroup.name
}
resource "azurerm_data_factory_integration_runtime_self_hosted" "example" {
name = "VMSHIRSB"
data_factory_name = azurerm_data_factory.example.name
resource_group_name = azurerm_resource_group.resourcegroup.name
}
To give different values based on the environment for the 'name' field, if you want the same configuration main.tf file for defining multiple environments, you can declare the environment variable "env" {} then use the var.env prefix on the name filed in each resource in different environments. You can create each resource dynamically by passing a different environment variable.
resource "azurerm_resource_group" "resourcegroup" {
name = "${var.env}-terraform-rg"
location = "west europe"
}
resource "azurerm_data_factory" "example" {
name = "${var.env}-adfSB"
location = azurerm_resource_group.resourcegroup.location
resource_group_name = azurerm_resource_group.resourcegroup.name
}
resource "azurerm_data_factory_integration_runtime_self_hosted" "example" {
name = "${var.env}-VMSHIRSB"
data_factory_name = azurerm_data_factory.example.name
resource_group_name = azurerm_resource_group.resourcegroup.name
}
If you want to create separate configurations file for different environments, you can create directories. When you are finished separating these environments into directories, your file structure should look like the one below.
.
├── assets
│ ├── index.html
├── prod
│ ├── main.tf
│ ├── variables.tf
│ ├── terraform.tfstate
│ └── terraform.tfvars
└── dev
├── main.tf
├── variables.tf
├── terraform.tfstate
└── terraform.tfvars
In this scenario, you will have duplicate Terraform code in each directory.
If you want to use the same Terraform code but have different state files, you can use workspace-separated environments. You could define variable "dev_prefix" {} or variable "prod_prefix" {}
Your directory will look similar to the one below.
.
├── README.md
├── assets
│ └── index.html
├── dev.tfvars
├── main.tf
├── outputs.tf
├── prod.tfvars
├── terraform.tfstate.d
│ ├── dev
│ │ └── terraform.tfstate
│ ├── prod
│ │ └── terraform.tfstate
├── terraform.tfvars
└── variables.tf
In this scenario, if you want to be able to declare variables that give us selection control, you can refer to this. Read here for more details about workspace and modules.

Luacheck include files from exclude directory

I have a project like this (in fact, there are more files and dirs):
.
├── src
│ ├── main.lua
│ └── smth.lua
└── tests
├── others
│ ├── others_1.lua
│ ├── others_2.lua
│ └── others_3.lua
├── speed_tests
│ ├── test1.lua
│ └── test2.lua
└── sql
├── join.lua
└── select.lua
and I have such .luacheckrc:
include_files = {
"**/*.lua"
}
exclude_files = {
"tests/**/*.lua",
}
I want luacheck utility to check files in tests/sql directory, but not to touch other directories in tests/. Of course, I can explicitly write:
exclude_files = {
"tests/others/*.lua",
"tests/speed_tests/*.lua"
}
, but in real project there're 15+ dirs and it doesn't look good to do that.
How can I reach a goal elegantly?
Don't use exclude then, only include dirs you wish to traverse.
include_files = {
"src/*.lua",
"tests/sql/*.lua"
}

Error while loading modules in test-kitchen

I am new to test kitchen and i am trying to use the existing vpc modules i have created earlier using terraform. I am having problems on loading the modules to test kitchen.
My folder structure looks like
tf_aws_cluster
├── .kitchen.yml
├── Gemfile
├── Gemfile.lock
├── README.md
│ ├── modules
| |── vpc
│ ├── main.tf
│ └── variables.tf
├── main.tf
|── variables.tf
the ~/tf_aws_cluster/.kitchen.yml file
---
driver:
name: terraform
provisioner:
name: terraform
directory: ~/tf_aws_cluster/modules/vpc
variable_files:
- variables.tf
my ~/tf_aws_cluster/main.tf file looks like
module "vpc" {
source = "../modules/vpc"
env = "prod"
aws_account_id = "************"
}
when i try to run
bundle exec kitchen verify
i am getting an error in loading modules.
-----> Creating <default-ubuntu>...
Copying configuration from "/home/ubuntu/tf_aws_cluster"...
Upgrading modules...
Error downloading modules: Error loading modules: module vpc: failed to get download URL for "../module/vpc": 200 OK resp:<!DOCTYPE html>
what is the values i should pass under provisioner for the module ?
I have tried by giving the full path for the source parameter ~/tf_aws_cluster/main.tf
source = "~/tf_aws_cluster/modules/vpc/"
this gives me an error as
Error downloading modules: Error loading modules: module vpc: invalid source string: ~/tf_aws_cluster/modules/vpc/
The directory should be a relative path in your directory attribute. Like this:
directory: modules/vpc
Also in the newly released kitchen-terraform v3.0.0 you should be using root_module_directory instead of directory
On a related topic, I would recommend going through the getting started guide to help understand how to do test fixtures as that is what I think you are trying to accomplish with main.tf and modules directory.
I would organize the code as such:
tf_aws_cluster
├── .kitchen.yml
├── Gemfile
├── Gemfile.lock
├── README.md
│ ├── test
| |── fixtures
| |── my_module
│ ├── main.tf
│ └── variables.tf
├── main.tf
|── variables.tf
.kitchen.yml
---
driver:
name: terraform
directory: test/fixtures/my_module
variable_files:
- variables.tf
provisioner:
name: terraform
the root main.tf:
# this should have your actual Terraform code
resource ... {
...
}
the test fixture main.tf (test/fixtures/my_module/main.tf)
# this should have a module reference to your root's main.tf such as:
module "vpc" {
source = "source = "../../.."
env = "prod"
aws_account_id = "************"
}

What globbing pattern will exclude a subdirectory except for two other subdirectories inside it?

I am copying over the jQueryUI library from bower. I only want to copy over two themes from their "themes" directory. The theme folders I want to keep are "base" and "ui-lightness".
How can I accomplish this with a globbing pattern?
I've tried this...
gulp.src([
'./bower_components/jqueryui/**',
'!./bower_components/jqueryui/themes/**(!base/**)'
])
Here is the directory structure:
├── themes
│   ├── base
│   ├── black-tie
│   ├── blitzer
│   ├── cupertino
│   ├── dark-hive
│   ├── dot-luv
│   ├── eggplant
│   ├── excite-bike
│   ├── flick
│   ├── hot-sneaks
│   ├── humanity
│   ├── le-frog
│   ├── mint-choc
│   ├── overcast
│   ├── pepper-grinder
│   ├── redmond
│   ├── smoothness
│   ├── south-street
│   ├── start
│   ├── sunny
│   ├── swanky-purse
│   ├── trontastic
│   ├── ui-darkness
│   ├── ui-lightness
│   └── vader
└── ui
├── i18n
└── minified
Gulp v4.x
The current gulp docs include an example glob pattern which can be customized to meet your requirement. Try the following:
gulp.task('copyfoobar', function() {
gulp.src([
'bower_components/jqueryui/**', // [1]
'!bower_components/jqueryui/themes/**', // [2]
'bower_components/jqueryui/themes/{base,ui-lightness}/**' // [3]
], { base: './' } )
.pipe(gulp.dest('./dist'));
});
The Array of globs shown above does the following:
[1] Matches everything under the bower_components/jqueryui/ directory.
[2] Negates the bower_components/jqueryui/themes directory, (and everything in it), from the list created via the previous glob pattern.
[3] Adds the bower_components/jqueryui/themes/base and bower_components/jqueryui/themes/ui-lightness directories, (and everything in them), back to the list.
Note: The solution above assumes that the bower_components directory resides in the same directory as your gulpfile.js, and the target directory is dist.
Resultant directory tree:
If you don't want the bower_components directory added to your target/destination directory, (i.e. dist), then set the base option to:
{ base: './bower_components/' }
This will result in something like this:
.
└── dist
└── jqueryui
├── themes
│ ├── base
│ │ └── ...
│ └── ui-lightness
│ └── ...
└── ...
Where as setting the base option to:
{ base: './' }
results in something like this:
.
└── dist
└── bower_components
└── jqueryui
├── themes
│ ├── base
│ │ └── ...
│ └── ui-lightness
│ └── ...
└── ...
Gulp v3.x
Unfortunately, the example shown above does not work in Gulp version 3.x because Negations (!) were handled differently - they were always done last regardless of the order they were specified in the glob Array. More info of that discussed in issue 837.
The workaround, (for v.3.x), is to utilize gulp-src-ordered-globs which will allow you to use the same Array of globs as the previous example.
The code for this will be:
var gulpSrc = require('gulp-src-ordered-globs'); // require the gulp.src() wrapper.
gulp.task('copyfoobar', function() {
gulpSrc([ // <-- gulpSrc() used instead of gulp.src()
'bower_components/jqueryui/**',
'!bower_components/jqueryui/themes/**',
'bower_components/jqueryui/themes/{base,ui-lightness}/**'
], { base: './' } )
.pipe(gulp.dest('./dist'));
});
I just did this instead. I think it was a little too difficult to figure it out in one task.
var task1 = gulp.src(base + 'jqueryui/*.*').pipe(gulp.dest(target));
var task2 = gulp.src(base + 'jqueryui/ui/**').pipe(gulp.dest(target + '/ui/'));
var task3 = gulp.src(base + 'jqueryui/themes/base/**').pipe(gulp.dest(target + '/themes/base/'));
var task4 = gulp.src(base + 'jqueryui/themes/ui-lightness/**').pipe(gulp.dest(target + '/themes/ui-lightness/'));
return [task1, task2, task3, task4];
Try this one
gulp.task('copy_flolder',function(){
gulp.src(['./bower_components/jqueryui/**', '!./bower_components/jqueryui/themes/**'])
.pipe(gulp.dest('your dist folder'))
});
gulp.task('copy_only_Themes',['copy_flolder'], function() {
gulp.src(['./bower_components/jqueryui/themes/base/**', './bower_components/jqueryui/themes/ui-lightness/**'])
.pipe(gulp.dest('your dist folder'))
});

Icon not showing on context menu item with Firefox Add-on SDK

This is the structure of the files:
├── data
│   ├── icon.png
│   ├── upload.js
│   └── upload.js~
├── doc
│   └── main.md
├── icon.png
├── lib
│   ├── icon.png
│   ├── main.js
│   └── main.js~
├── package.json
├── package.json.backup
├── README.md
├── share2.xpi
└── test
└── test-main.js
This is the code in main.js:
const contextMenu = require("context-menu");
const data = require("self").data;
exports.main = function(options,callbacks){
var cm = require("context-menu").Item({
label:"share it",
contentScriptFile:data.url("upload.js"),
image:data.url("icon.png")
});
}
"share it" is displayed in the context menu, and the contentScriptFile is be excuted, but the image doesn't display. How can I solve this problem?
Make sure you're using a sufficient version of the Add-on SDK; the 'image' property was only added in version 1.1. If you're using 1.0, you'll need to update. Otherwise, it should be working.
I could be wrong but from the comments on Chris' answer, it seems like the issue is not with the icon but with your upload script.
It could be that the run process never reaches the image property to add it.
Do you get the same error if you remove the image property altogether?
Try this, it has worked for me:
var self = require("sdk/self");
require("sdk/context-menu").Item({
label: "Buscar lugar geográfico...",
contentScript: 'self.on("click", self.postMessage);',
onMessage: function () {
doSearch();
},
image:self.data.url("logo.png")
});

Resources