Posts de May, 2011

[Francisco Souza] Testing jQuery plugins with Jasmine

Saturday, May 28th, 2011

Since I started working at Globo.com, I developed some jQuery plugins (for internal use) with my team, and we are starting to test these plugins using Jasmine, “a behavior-driven development framework for testing your JavaScript code”. In this post, I will show how to develop a very simple jQuery plugin (based on an example that I learned with Ricard D. Worth): zebrafy. This plugin “zebrafies” a table, applying different classes to odd and even lines. Let’s start setting up a Jasmine environment…

First step is download the standalone version of Jasmine, then extract it and edit the runner. The runner is a simple HTML file, that loads Jasmine and all JavaScript files you want to test. But, wait… why not test using node.js or something like this? Do I really need the browser on this test? You don’t need, but I think it is important to test a plugin that works with the DOM using a real browser. Let’s delete some files and lines from SpecRunner.html file, so we adapt it for our plugin. This is how the structure is going to look like:

.├── SpecRunner.html├── lib│   ├── jasmine-1.0.2│   │   ├── MIT.LICENSE│   │   ├── jasmine-html.js│   │   ├── jasmine.css│   │   └── jasmine.js│   └── jquery-1.6.1.min.js├── spec│   └── ZebrafySpec.js└── src    └── jquery.zebrafy.js

You can create the files jquery.zebrafy.js and ZebrafySpec.js, but remember: it is BDD, we need to describe the behavior first, then write the code. So let’s start writing the specs in ZebrafySpec.js file using Jasmine. If you are familiar with RSpec syntax, it’s easy to understand how to write spec withs Jasmine, if you aren’t, here is the clue: Jasmine is a lib with some functions used for writing tests in an easier way. I’m going to explain each function “on demmand”, when we need something, we learn how to use it! ;)

First of all, we need to start a new test suite. Jasmine provides the describe function for that, this function receives a string and another function (a callback). The string describes the test suite and the function is a callback that delimites the scope of the test suite. Here is the Zebrafy suite:

describe('Zebrafy', function () {

});

Let’s start describing the behavior we want to get from the plugin. The most basic is: we want different CSS classes for odd an even lines in a table. Jasmine provides the it function for writing the tests. It also receives a string and a callback: the string is a description for the test and the callback is the function executed as test. Here is the very first test:

it('should apply classes zebrafy-odd and zebrafy-even to each other table lines', function () {    var table = $("#zebra-table");    table.zebrafy();    expect(table).toBeZebrafyied();});

Okay, here we go: in the first line of the callback, we are using jQuery to select a table using the #zebra-table selector, which will look up for a table with the ID attribute equals to “zebra-table”, but we don’t have this table in the DOM. What about add a new table to the DOM in a hook executed before the test run and remove the table in another hook that runs after the test? Jasmine provide two functions: beforeEach and afterEach. Both functions receive a callback function to be executed and, as the names suggest, the beforeEach callback is called before each test run, and the afterEach callback is called after the test run. Here are the hooks:

beforeEach(function () {    $('<table id="zebra-table"></table>').appendTo('body');    for (var i=0; i < 10; i++) {        $('<tr></tr>').append('<td></td>').append('<td></td>').append('<td></td>').appendTo('#zebra-table');    };});

afterEach(function () {    $("#zebra-table").remove();});

The beforeEach callback uses jQuery to create a table with 10 rows and 3 columns and add it to the DOM. In afterEach callback, we just remove that table using jQuery again. Okay, now the table exists, let’s go back to the test:

it('should apply classes zebrafy-odd and zebrafy-even to each other table lines', function () {    var table = $("#zebra-table");    table.zebrafy();    expect(table).toBeZebrafyied();});

In the second line, we call our plugin, that is not ready yet, so let’s forward to the next line, where we used the expect function. Jasmine provides this function, that receives an object and executes a matcher against it, there is a lot of built-in matchers on Jasmine, but toBeZebrafyied is not a built-in matcher. Here is where we know another Jasmine feature: the capability to write custom matchers, but how to do this? You can call the beforeEach again, and use the addMatcher method of Jasmine object:

beforeEach(function () {    this.addMatchers({        toBeZebrafyied: function() {            var isZebrafyied = true;

            this.actual.find("tr:even").each(function (index, tr) {                isZebrafyied = $(tr).hasClass('zebrafy-odd') === false && $(tr).hasClass('zebrafy-even');                if (!isZebrafyied) {                    return;                };            });

            this.actual.find("tr:odd").each(function (index, tr) {                isZebrafyied = $(tr).hasClass('zebrafy-odd') && $(tr).hasClass('zebrafy-even') === false;                if (!isZebrafyied) {                    return;                };            });

            return isZebrafyied;        }    });});

The method addMatchers receives an object where each property is a matcher. Your matcher can receive arguments if you want. The object being matched can be accessed using this.actual, so here is what the method above does: it takes all odd <tr> elements of the table (this.actual) and check if them have the CSS class zebrafy-odd and don’t have the CSS class zebrafy-even, then do the same checking with even <tr> lines.

Now that we have wrote the test, it’s time to write the plugin. Here some jQuery code:

(function ($) {    $.fn.zebrafy = function () {        this.find("tr:even").addClass("zebrafy-even");        this.find("tr:odd").addClass("zebrafy-odd");    };})(jQuery);

I’m not going to explain how to implement a jQuery plugin neither what are those brackets on function, this post aims to show how to use Jasmine to test jQuery plugins.

By convention, jQuery plugins are “chainable”, so let’s make sure the zebrafy plugin is chainable using a spec:

it('zebrafy should be chainable', function() {    var table = $("#zebra-table");    table.zebrafy().addClass('black-bg');    expect(table.hasClass('black-bg')).toBeTruthy();});

As you can see, we used the built-in matcher toBeTruthy, which asserts that an object or expression is true. All we need to do is return the jQuery object in the plugin and the test will pass:

(function ($) {    $.fn.zebrafy = function () {        return this.each(function (index, table) {            $(table).find("tr:even").addClass("zebrafy-even");            $(table).find("tr:odd").addClass("zebrafy-odd");        });    };})(jQuery);

So, the plugin is tested and ready to release! :) You can check the entire code and test with more spec in a Github repository.

[Francisco Souza] Testing jQuery plugins with Jasmine

Saturday, May 28th, 2011

Since I started working at Globo.com, I developed some jQuery plugins (for internal use) with my team, and we are starting to test these plugins using Jasmine, “a behavior-driven development framework for testing your JavaScript code”. In this post, I will show how to develop a very simple jQuery plugin (based on an example that I learned with Ricard D. Worth): zebrafy. This plugin “zebrafies” a table, applying different classes to odd and even lines. Let’s start setting up a Jasmine environment…

First step is download the standalone version of Jasmine, then extract it and edit the runner. The runner is a simple HTML file, that loads Jasmine and all JavaScript files you want to test. But, wait… why not test using node.js or something like this? Do I really need the browser on this test? You don’t need, but I think it is important to test a plugin that works with the DOM using a real browser. Let’s delete some files and lines from SpecRunner.html file, so we adapt it for our plugin. This is how the structure is going to look like:

.├── SpecRunner.html├── lib│   ├── jasmine-1.0.2│   │   ├── MIT.LICENSE│   │   ├── jasmine-html.js│   │   ├── jasmine.css│   │   └── jasmine.js│   └── jquery-1.6.1.min.js├── spec│   └── ZebrafySpec.js└── src    └── jquery.zebrafy.js

You can create the files jquery.zebrafy.js and ZebrafySpec.js, but remember: it is BDD, we need to describe the behavior first, then write the code. So let’s start writing the specs in ZebrafySpec.js file using Jasmine. If you are familiar with RSpec syntax, it’s easy to understand how to write spec withs Jasmine, if you aren’t, here is the clue: Jasmine is a lib with some functions used for writing tests in an easier way. I’m going to explain each function “on demmand”, when we need something, we learn how to use it! ;)

First of all, we need to start a new test suite. Jasmine provides the describe function for that, this function receives a string and another function (a callback). The string describes the test suite and the function is a callback that delimites the scope of the test suite. Here is the Zebrafy suite:

describe('Zebrafy', function () {

});

Let’s start describing the behavior we want to get from the plugin. The most basic is: we want different CSS classes for odd an even lines in a table. Jasmine provides the it function for writing the tests. It also receives a string and a callback: the string is a description for the test and the callback is the function executed as test. Here is the very first test:

it('should apply classes zebrafy-odd and zebrafy-even to each other table lines', function () {    var table = $("#zebra-table");    table.zebrafy();    expect(table).toBeZebrafyied();});

Okay, here we go: in the first line of the callback, we are using jQuery to select a table using the #zebra-table selector, which will look up for a table with the ID attribute equals to “zebra-table”, but we don’t have this table in the DOM. What about add a new table to the DOM in a hook executed before the test run and remove the table in another hook that runs after the test? Jasmine provide two functions: beforeEach and afterEach. Both functions receive a callback function to be executed and, as the names suggest, the beforeEach callback is called before each test run, and the afterEach callback is called after the test run. Here are the hooks:

beforeEach(function () {    $('<table id="zebra-table"></table>').appendTo('body');    for (var i=0; i < 10; i++) {        $('<tr></tr>').append('<td></td>').append('<td></td>').append('<td></td>').appendTo('#zebra-table');    };});

afterEach(function () {    $("#zebra-table").remove();});

The beforeEach callback uses jQuery to create a table with 10 rows and 3 columns and add it to the DOM. In afterEach callback, we just remove that table using jQuery again. Okay, now the table exists, let’s go back to the test:

it('should apply classes zebrafy-odd and zebrafy-even to each other table lines', function () {    var table = $("#zebra-table");    table.zebrafy();    expect(table).toBeZebrafyied();});

In the second line, we call our plugin, that is not ready yet, so let’s forward to the next line, where we used the expect function. Jasmine provides this function, that receives an object and executes a matcher against it, there is a lot of built-in matchers on Jasmine, but toBeZebrafyied is not a built-in matcher. Here is where we know another Jasmine feature: the capability to write custom matchers, but how to do this? You can call the beforeEach again, and use the addMatcher method of Jasmine object:

beforeEach(function () {    this.addMatchers({        toBeZebrafyied: function() {            var isZebrafyied = true;

            this.actual.find("tr:even").each(function (index, tr) {                isZebrafyied = $(tr).hasClass('zebrafy-odd') === false && $(tr).hasClass('zebrafy-even');                if (!isZebrafyied) {                    return;                };            });

            this.actual.find("tr:odd").each(function (index, tr) {                isZebrafyied = $(tr).hasClass('zebrafy-odd') && $(tr).hasClass('zebrafy-even') === false;                if (!isZebrafyied) {                    return;                };            });

            return isZebrafyied;        }    });});

The method addMatchers receives an object where each property is a matcher. Your matcher can receive arguments if you want. The object being matched can be accessed using this.actual, so here is what the method above does: it takes all odd <tr> elements of the table (this.actual) and check if them have the CSS class zebrafy-odd and don’t have the CSS class zebrafy-even, then do the same checking with even <tr> lines.

Now that we have wrote the test, it’s time to write the plugin. Here some jQuery code:

(function ($) {    $.fn.zebrafy = function () {        this.find("tr:even").addClass("zebrafy-even");        this.find("tr:odd").addClass("zebrafy-odd");    };})(jQuery);

I’m not going to explain how to implement a jQuery plugin neither what are those brackets on function, this post aims to show how to use Jasmine to test jQuery plugins.

By convention, jQuery plugins are “chainable”, so let’s make sure the zebrafy plugin is chainable using a spec:

it('zebrafy should be chainable', function() {    var table = $("#zebra-table");    table.zebrafy().addClass('black-bg');    expect(table.hasClass('black-bg')).toBeTruthy();});

As you can see, we used the built-in matcher toBeTruthy, which asserts that an object or expression is true. All we need to do is return the jQuery object in the plugin and the test will pass:

(function ($) {    $.fn.zebrafy = function () {        return this.each(function (index, table) {            $(table).find("tr:even").addClass("zebrafy-even");            $(table).find("tr:odd").addClass("zebrafy-odd");        });    };})(jQuery);

So, the plugin is tested and ready to release! :) You can check the entire code and test with more spec in a Github repository.

[Emerson Macedo] Conhecendo o NPM 1.0

Wednesday, May 25th, 2011

No dia primeiro deste mês, foi lançado a versão 1.0 do NPM (Node Package Manager). Pra quem não sabe, o NPM é o gerenciador de pacotes oficial do Node.JS. É com ele que criamos e baixamos bibliotecas para desenvolver nossas aplicações em Node.JS.

Não vou explicar aqui como funcionava até a versão 0.3.18 (a última antes das pré 1.0) para não ficar um artigo grande (já vai ficar), mas a explicação sobre o funcionamento da versão 1.0 deve ser suficiente para você conseguir migrar.

Instalando

Existem algumas instruções de instalação, mas basicamente a melhor forma é instalar limpando as coisas velhas. Digo isso porque agora que chegou na 1.0 e quase todas as libs já atualizaram para essa versão e novo modelo, não faz sentido manter libs, a não ser que você tenha alguma lib muito específica. Execute o seguinte:

$ curl http://npmjs.org/install.sh | clean=yes sh

Certifique que você tem permissão para escrever no diretório /usr/local.

Isso vai instalar o NPM 1.0.6 (versão do momento que escrevo o artigo) e limpar suas libs antigas). Se preferir, desinstale antes seu NPM antigo (npm uninstall npm) e apague o diretório ~/.npm. Novidades da instalação:

/usr/local/bin/npm #executável
/usr/local/lib/node_modules/ #pacotes globais

Desde a versão 0.4.x do Node.JS, o diretório node_modules passa a ser o diretório de armazenamento de pacotes, sempre contextualmente ao diretório do projeto que você está trabalhando. Tanto isso é verdade que as bibliotecas instaladas em /usr/local/lib/node_modules/ não ficam automaticamente visíveis para você dar require nelas. Falarei mais sobre isso adiante.

Sendo assim, a nova forma de trabalhar com o NPM é a seguinte:

  • Pacotes que contém executáveis (nodeunit, express, etc) instale com npm install pacote -g
  • Pacotes sem executáveis instale com npm install pacote

Qual a diferença?

A diferença é que a instalação utilizando -g deve ser utilizada primariamente para pacotes que contém executáveis, pois os executáveis já ficam visíveis no path. Outro uso é quando você quer compartilhar algum pacote com diversos projetos. Isso é feito criando um link, que falaei adiante. A instalação local limita o pacote ao escopo do projeto/diretório que foi instalado, ou seja, somente dentro desse diretório e seus subdiretórios esse pacote estará disponível para require.

Para listar os pacotes instalados localmente, basta executar o seguinte comando:

$ npm list
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Esse comando lista apenas os pacotes instalados no diretório node_modules dentro do diretório que aparece logo abaixo do comando npm list (ou npm ls)

Para listar os pacotes globais basta executar:

$ npm ls -g
/usr/local/lib
├─┬ connect@1.4.1
│ ├── mime@1.2.2
│ └── qs@0.1.0
├── nodeunit@0.5.1
└─┬ npm@1.0.6
  ├── abbrev@1.0.3
  ├── node-uuid@1.1.0
  ├── nopt@1.0.4
  └── semver@1.0.5

Repare que a lista é bem diferente. Nenhum desses pacotes podem ser utilizados sem que sejam linkados. Vamos fazer isso agora para que eles fiquem disponíveis localmente.

$ npm link connect
./node_modules/connect -> /usr/local/lib/node_modules/connect

E agora veremos novamente nossos pacotes locais:

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ connect@1.4.1 -> /usr/local/lib/node_modules/connect extraneous
│ ├── mime@1.2.2
│ └── qs@0.1.0
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Repare que o pacote connect aponta para um diretório na instalação global. Com esse link, é possível utilizar o pacote no projeto/diretório atual.

Alguns desenvolvedores utilizam a variável de ambiente NODE_PATH apontando para /usr/local/lib/node_modules/ porque seus projetos não estão enxergando os pacotes globais. De fato isso funciona, mas não é a maneira adequada, pois se você instalar um pacote local e outro global utilizando essa configuração, o pacote global vai prevalecer sobre o local, o que não deveria ser o comportamento esperado.

É importante entender que o escopo local é definido tão somente pelo diretório que você está. Se você voltar um diretório e listar novamente os pacotes perceberá que não tem nada instalado ou a lista de pacotes instalados é diferente (no caso de você ter instalado algo nesse diretório). Vejamos:

$ cd ..
$ npm ls
/Users/emerson.leite/Pet
(empty)

Voltemos para o diretório anterior e vamos remover o link ao pacote connect.

$ cd -
/Users/emerson.leite/Pet/node-database-cleaner
$ npm unlink connect
$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Nesse momento não temos mais o link para o pacote connect e portanto não podemos mais fazer um require dele.

Utilizando o package.json para gerenciar suas dependências

O arquivo package.json é um arquivo que descreve um pacote NPM. Nesse arquivo também pode/deve ser utilizado para especificar os pacotes que seu projeto depende. Dessa forma, basta estar no diretório e executar npm install que o NPM já instalará as dependências necessárias. Vejamos um exemplo:

{
  "name" : "database-cleaner",
  "description" : "Database Cleaner for node.js",
  "keywords" : [ "database", "cleaner", "mongodb",
                 "redis", "couchdb", "tests", "package.json" ],
  "version" : "0.3.2",
  "author" : "Emerson Macedo ",
  "repository" : {
    "type" : "git",
    "url" : "git://github.com/emerleite/node-database-cleaner.git"
  },
  "dependencies" : {
    "mongoose" : "1.0.10",
    "redis" : ">=0.5.7",
    "cradle" : ">=0.5.x"
  },
  "main": "index",
  "engines" : { "node" : ">=0.2.5" }
}

Vamos limpar o diretório e instalar novamente as dependências para ver como funciona. Primeiro vou apagar o diretório node_modules, listar para mostrar que está vazio e instalar as dependências.

$ rm -fr node_modules/
$ npm ls
npm WARN cradle >=0.5.x Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN mongoose 1.0.10 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN redis >=0.5.7 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├── UNMET DEPENDENCY cradle >=0.5.x
├── UNMET DEPENDENCY mongoose 1.0.10
└── UNMET DEPENDENCY redis >=0.5.7

A resposta mostra que as dependências não estão instaladas, o que vamos resolver agora:

$ npm install
redis@0.6.0 ./node_modules/redis
mongoose@1.0.10 ./node_modules/mongoose
vargs@0.1.0 ./node_modules/cradle/node_modules/vargs
eyes@0.1.6 ./node_modules/cradle/node_modules/vows/node_modules/eyes
vows@0.5.8 ./node_modules/cradle/node_modules/vows
cradle@0.5.5 ./node_modules/cradle

Agora vamos listar apenas para conferir.

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
└── redis@0.6.0

Pra fechar

O NPM tem uma série de outros recursos que vou tentar destacar em outros artigos, mas vejo que muita gente não estava entendendo bem a forma mais adequada de usar a versão 1.0, inclusive apelando para o uso inadequado da variável de ambiente NODE_PATH. Espero que este artigo possa ajudar a explicar um pouco do NPM 1.0.

[Emerson Macedo] Conhecendo o NPM 1.0

Wednesday, May 25th, 2011

No dia primeiro deste mês, foi lançado a versão 1.0 do NPM (Node Package Manager). Pra quem não sabe, o NPM é o gerenciador de pacotes oficial do Node.JS. É com ele que criamos e baixamos bibliotecas para desenvolver nossas aplicações em Node.JS.

Não vou explicar aqui como funcionava até a versão 0.3.18 (a última antes das pré 1.0) para não ficar um artigo grande (já vai ficar), mas a explicação sobre o funcionamento da versão 1.0 deve ser suficiente para você conseguir migrar.

Instalando

Existem algumas instruções de instalação, mas basicamente a melhor forma é instalar limpando as coisas velhas. Digo isso porque agora que chegou na 1.0 e quase todas as libs já atualizaram para essa versão e novo modelo, não faz sentido manter libs, a não ser que você tenha alguma lib muito específica. Execute o seguinte:

$ curl http://npmjs.org/install.sh | clean=yes sh

Certifique que você tem permissão para escrever no diretório /usr/local.

Isso vai instalar o NPM 1.0.6 (versão do momento que escrevo o artigo) e limpar suas libs antigas). Se preferir, desinstale antes seu NPM antigo (npm uninstall npm) e apague o diretório ~/.npm. Novidades da instalação:

/usr/local/bin/npm #executável
/usr/local/lib/node_modules/ #pacotes globais

Desde a versão 0.4.x do Node.JS, o diretório node_modules passa a ser o diretório de armazenamento de pacotes, sempre contextualmente ao diretório do projeto que você está trabalhando. Tanto isso é verdade que as bibliotecas instaladas em /usr/local/lib/node_modules/ não ficam automaticamente visíveis para você dar require nelas. Falarei mais sobre isso adiante.

Sendo assim, a nova forma de trabalhar com o NPM é a seguinte:

  • Pacotes que contém executáveis (nodeunit, express, etc) instale com npm install pacote -g
  • Pacotes sem executáveis instale com npm install pacote

Qual a diferença?

A diferença é que a instalação utilizando -g deve ser utilizada primariamente para pacotes que contém executáveis, pois os executáveis já ficam visíveis no path. Outro uso é quando você quer compartilhar algum pacote com diversos projetos. Isso é feito criando um link, que falaei adiante. A instalação local limita o pacote ao escopo do projeto/diretório que foi instalado, ou seja, somente dentro desse diretório e seus subdiretórios esse pacote estará disponível para require.

Para listar os pacotes instalados localmente, basta executar o seguinte comando:

$ npm list
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Esse comando lista apenas os pacotes instalados no diretório node_modules dentro do diretório que aparece logo abaixo do comando npm list (ou npm ls)

Para listar os pacotes globais basta executar:

$ npm ls -g
/usr/local/lib
├─┬ connect@1.4.1
│ ├── mime@1.2.2
│ └── qs@0.1.0
├── nodeunit@0.5.1
└─┬ npm@1.0.6
  ├── abbrev@1.0.3
  ├── node-uuid@1.1.0
  ├── nopt@1.0.4
  └── semver@1.0.5

Repare que a lista é bem diferente. Nenhum desses pacotes podem ser utilizados sem que sejam linkados. Vamos fazer isso agora para que eles fiquem disponíveis localmente.

$ npm link connect
./node_modules/connect -> /usr/local/lib/node_modules/connect

E agora veremos novamente nossos pacotes locais:

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ connect@1.4.1 -> /usr/local/lib/node_modules/connect extraneous
│ ├── mime@1.2.2
│ └── qs@0.1.0
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Repare que o pacote connect aponta para um diretório na instalação global. Com esse link, é possível utilizar o pacote no projeto/diretório atual.

Alguns desenvolvedores utilizam a variável de ambiente NODE_PATH apontando para /usr/local/lib/node_modules/ porque seus projetos não estão enxergando os pacotes globais. De fato isso funciona, mas não é a maneira adequada, pois se você instalar um pacote local e outro global utilizando essa configuração, o pacote global vai prevalecer sobre o local, o que não deveria ser o comportamento esperado.

É importante entender que o escopo local é definido tão somente pelo diretório que você está. Se você voltar um diretório e listar novamente os pacotes perceberá que não tem nada instalado ou a lista de pacotes instalados é diferente (no caso de você ter instalado algo nesse diretório). Vejamos:

$ cd ..
$ npm ls
/Users/emerson.leite/Pet
(empty)

Voltemos para o diretório anterior e vamos remover o link ao pacote connect.

$ cd -
/Users/emerson.leite/Pet/node-database-cleaner
$ npm unlink connect
$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Nesse momento não temos mais o link para o pacote connect e portanto não podemos mais fazer um require dele.

Utilizando o package.json para gerenciar suas dependências

O arquivo package.json é um arquivo que descreve um pacote NPM. Nesse arquivo também pode/deve ser utilizado para especificar os pacotes que seu projeto depende. Dessa forma, basta estar no diretório e executar npm install que o NPM já instalará as dependências necessárias. Vejamos um exemplo:

{
  "name" : "database-cleaner",
  "description" : "Database Cleaner for node.js",
  "keywords" : [ "database", "cleaner", "mongodb",
                 "redis", "couchdb", "tests", "package.json" ],
  "version" : "0.3.2",
  "author" : "Emerson Macedo ",
  "repository" : {
    "type" : "git",
    "url" : "git://github.com/emerleite/node-database-cleaner.git"
  },
  "dependencies" : {
    "mongoose" : "1.0.10",
    "redis" : ">=0.5.7",
    "cradle" : ">=0.5.x"
  },
  "main": "index",
  "engines" : { "node" : ">=0.2.5" }
}

Vamos limpar o diretório e instalar novamente as dependências para ver como funciona. Primeiro vou apagar o diretório node_modules, listar para mostrar que está vazio e instalar as dependências.

$ rm -fr node_modules/
$ npm ls
npm WARN cradle >=0.5.x Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN mongoose 1.0.10 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN redis >=0.5.7 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├── UNMET DEPENDENCY cradle >=0.5.x
├── UNMET DEPENDENCY mongoose 1.0.10
└── UNMET DEPENDENCY redis >=0.5.7

A resposta mostra que as dependências não estão instaladas, o que vamos resolver agora:

$ npm install
redis@0.6.0 ./node_modules/redis
mongoose@1.0.10 ./node_modules/mongoose
vargs@0.1.0 ./node_modules/cradle/node_modules/vargs
eyes@0.1.6 ./node_modules/cradle/node_modules/vows/node_modules/eyes
vows@0.5.8 ./node_modules/cradle/node_modules/vows
cradle@0.5.5 ./node_modules/cradle

Agora vamos listar apenas para conferir.

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
└── redis@0.6.0

Pra fechar

O NPM tem uma série de outros recursos que vou tentar destacar em outros artigos, mas vejo que muita gente não estava entendendo bem a forma mais adequada de usar a versão 1.0, inclusive apelando para o uso inadequado da variável de ambiente NODE_PATH. Espero que este artigo possa ajudar a explicar um pouco do NPM 1.0.

[Emerson Macedo] Conhecendo o NPM 1.0

Wednesday, May 25th, 2011

No dia primeiro deste mês, foi lançado a versão 1.0 do NPM (Node Package Manager). Pra quem não sabe, o NPM é o gerenciador de pacotes oficial do Node.JS. É com ele que criamos e baixamos bibliotecas para desenvolver nossas aplicações em Node.JS.

Não vou explicar aqui como funcionava até a versão 0.3.18 (a última antes das pré 1.0) para não ficar um artigo grande (já vai ficar), mas a explicação sobre o funcionamento da versão 1.0 deve ser suficiente para você conseguir migrar.

Instalando

Existem algumas instruções de instalação, mas basicamente a melhor forma é instalar limpando as coisas velhas. Digo isso porque agora que chegou na 1.0 e quase todas as libs já atualizaram para essa versão e novo modelo, não faz sentido manter libs, a não ser que você tenha alguma lib muito específica. Execute o seguinte:

$ curl http://npmjs.org/install.sh | clean=yes sh

Certifique que você tem permissão para escrever no diretório /usr/local.

Isso vai instalar o NPM 1.0.6 (versão do momento que escrevo o artigo) e limpar suas libs antigas). Se preferir, desinstale antes seu NPM antigo (npm uninstall npm) e apague o diretório ~/.npm. Novidades da instalação:

/usr/local/bin/npm #executável
/usr/local/lib/node_modules/ #pacotes globais

Desde a versão 0.4.x do Node.JS, o diretório node_modules passa a ser o diretório de armazenamento de pacotes, sempre contextualmente ao diretório do projeto que você está trabalhando. Tanto isso é verdade que as bibliotecas instaladas em /usr/local/lib/node_modules/ não ficam automaticamente visíveis para você dar require nelas. Falarei mais sobre isso adiante.

Sendo assim, a nova forma de trabalhar com o NPM é a seguinte:

  • Pacotes que contém executáveis (nodeunit, express, etc) instale com npm install pacote -g
  • Pacotes sem executáveis instale com npm install pacote

Qual a diferença?

A diferença é que a instalação utilizando -g deve ser utilizada primariamente para pacotes que contém executáveis, pois os executáveis já ficam visíveis no path. Outro uso é quando você quer compartilhar algum pacote com diversos projetos. Isso é feito criando um link, que falaei adiante. A instalação local limita o pacote ao escopo do projeto/diretório que foi instalado, ou seja, somente dentro desse diretório e seus subdiretórios esse pacote estará disponível para require.

Para listar os pacotes instalados localmente, basta executar o seguinte comando:

$ npm list
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Esse comando lista apenas os pacotes instalados no diretório node_modules dentro do diretório que aparece logo abaixo do comando npm list (ou npm ls)

Para listar os pacotes globais basta executar:

$ npm ls -g
/usr/local/lib
├─┬ connect@1.4.1
│ ├── mime@1.2.2
│ └── qs@0.1.0
├── nodeunit@0.5.1
└─┬ npm@1.0.6
  ├── abbrev@1.0.3
  ├── node-uuid@1.1.0
  ├── nopt@1.0.4
  └── semver@1.0.5

Repare que a lista é bem diferente. Nenhum desses pacotes podem ser utilizados sem que sejam linkados. Vamos fazer isso agora para que eles fiquem disponíveis localmente.

$ npm link connect
./node_modules/connect -> /usr/local/lib/node_modules/connect

E agora veremos novamente nossos pacotes locais:

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ connect@1.4.1 -> /usr/local/lib/node_modules/connect extraneous
│ ├── mime@1.2.2
│ └── qs@0.1.0
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Repare que o pacote connect aponta para um diretório na instalação global. Com esse link, é possível utilizar o pacote no projeto/diretório atual.

Alguns desenvolvedores utilizam a variável de ambiente NODE_PATH apontando para /usr/local/lib/node_modules/ porque seus projetos não estão enxergando os pacotes globais. De fato isso funciona, mas não é a maneira adequada, pois se você instalar um pacote local e outro global utilizando essa configuração, o pacote global vai prevalecer sobre o local, o que não deveria ser o comportamento esperado.

É importante entender que o escopo local é definido tão somente pelo diretório que você está. Se você voltar um diretório e listar novamente os pacotes perceberá que não tem nada instalado ou a lista de pacotes instalados é diferente (no caso de você ter instalado algo nesse diretório). Vejamos:

$ cd ..
$ npm ls
/Users/emerson.leite/Pet
(empty)

Voltemos para o diretório anterior e vamos remover o link ao pacote connect.

$ cd -
/Users/emerson.leite/Pet/node-database-cleaner
$ npm unlink connect
$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Nesse momento não temos mais o link para o pacote connect e portanto não podemos mais fazer um require dele.

Utilizando o package.json para gerenciar suas dependências

O arquivo package.json é um arquivo que descreve um pacote NPM. Nesse arquivo também pode/deve ser utilizado para especificar os pacotes que seu projeto depende. Dessa forma, basta estar no diretório e executar npm install que o NPM já instalará as dependências necessárias. Vejamos um exemplo:

{
  "name" : "database-cleaner",
  "description" : "Database Cleaner for node.js",
  "keywords" : [ "database", "cleaner", "mongodb",
                 "redis", "couchdb", "tests", "package.json" ],
  "version" : "0.3.2",
  "author" : "Emerson Macedo ",
  "repository" : {
    "type" : "git",
    "url" : "git://github.com/emerleite/node-database-cleaner.git"
  },
  "dependencies" : {
    "mongoose" : "1.0.10",
    "redis" : ">=0.5.7",
    "cradle" : ">=0.5.x"
  },
  "main": "index",
  "engines" : { "node" : ">=0.2.5" }
}

Vamos limpar o diretório e instalar novamente as dependências para ver como funciona. Primeiro vou apagar o diretório node_modules, listar para mostrar que está vazio e instalar as dependências.

$ rm -fr node_modules/
$ npm ls
npm WARN cradle >=0.5.x Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN mongoose 1.0.10 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN redis >=0.5.7 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├── UNMET DEPENDENCY cradle >=0.5.x
├── UNMET DEPENDENCY mongoose 1.0.10
└── UNMET DEPENDENCY redis >=0.5.7

A resposta mostra que as dependências não estão instaladas, o que vamos resolver agora:

$ npm install
redis@0.6.0 ./node_modules/redis
mongoose@1.0.10 ./node_modules/mongoose
vargs@0.1.0 ./node_modules/cradle/node_modules/vargs
eyes@0.1.6 ./node_modules/cradle/node_modules/vows/node_modules/eyes
vows@0.5.8 ./node_modules/cradle/node_modules/vows
cradle@0.5.5 ./node_modules/cradle

Agora vamos listar apenas para conferir.

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
└── redis@0.6.0

Pra fechar

O NPM tem uma série de outros recursos que vou tentar destacar em outros artigos, mas vejo que muita gente não estava entendendo bem a forma mais adequada de usar a versão 1.0, inclusive apelando para o uso inadequado da variável de ambiente NODE_PATH. Espero que este artigo possa ajudar a explicar um pouco do NPM 1.0.

[Emerson Macedo] Conhecendo o NPM 1.0

Wednesday, May 25th, 2011

No dia primeiro deste mês, foi lançado a versão 1.0 do NPM (Node Package Manager). Pra quem não sabe, o NPM é o gerenciador de pacotes oficial do Node.JS. É com ele que criamos e baixamos bibliotecas para desenvolver nossas aplicações em Node.JS.

Não vou explicar aqui como funcionava até a versão 0.3.18 (a última antes das pré 1.0) para não ficar um artigo grande (já vai ficar), mas a explicação sobre o funcionamento da versão 1.0 deve ser suficiente para você conseguir migrar.

Instalando

Existem algumas instruções de instalação, mas basicamente a melhor forma é instalar limpando as coisas velhas. Digo isso porque agora que chegou na 1.0 e quase todas as libs já atualizaram para essa versão e novo modelo, não faz sentido manter libs, a não ser que você tenha alguma lib muito específica. Execute o seguinte:

$ curl http://npmjs.org/install.sh | clean=yes sh

Certifique que você tem permissão para escrever no diretório /usr/local.

Isso vai instalar o NPM 1.0.6 (versão do momento que escrevo o artigo) e limpar suas libs antigas). Se preferir, desinstale antes seu NPM antigo (npm uninstall npm) e apague o diretório ~/.npm. Novidades da instalação:

/usr/local/bin/npm #executável
/usr/local/lib/node_modules/ #pacotes globais

Desde a versão 0.4.x do Node.JS, o diretório node_modules passa a ser o diretório de armazenamento de pacotes, sempre contextualmente ao diretório do projeto que você está trabalhando. Tanto isso é verdade que as bibliotecas instaladas em /usr/local/lib/node_modules/ não ficam automaticamente visíveis para você dar require nelas. Falarei mais sobre isso adiante.

Sendo assim, a nova forma de trabalhar com o NPM é a seguinte:

  • Pacotes que contém executáveis (nodeunit, express, etc) instale com npm install pacote -g
  • Pacotes sem executáveis instale com npm install pacote

Qual a diferença?

A diferença é que a instalação utilizando -g deve ser utilizada primariamente para pacotes que contém executáveis, pois os executáveis já ficam visíveis no path. Outro uso é quando você quer compartilhar algum pacote com diversos projetos. Isso é feito criando um link, que falaei adiante. A instalação local limita o pacote ao escopo do projeto/diretório que foi instalado, ou seja, somente dentro desse diretório e seus subdiretórios esse pacote estará disponível para require.

Para listar os pacotes instalados localmente, basta executar o seguinte comando:

$ npm list
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Esse comando lista apenas os pacotes instalados no diretório node_modules dentro do diretório que aparece logo abaixo do comando npm list (ou npm ls)

Para listar os pacotes globais basta executar:

$ npm ls -g
/usr/local/lib
├─┬ connect@1.4.1
│ ├── mime@1.2.2
│ └── qs@0.1.0
├── nodeunit@0.5.1
└─┬ npm@1.0.6
  ├── abbrev@1.0.3
  ├── node-uuid@1.1.0
  ├── nopt@1.0.4
  └── semver@1.0.5

Repare que a lista é bem diferente. Nenhum desses pacotes podem ser utilizados sem que sejam linkados. Vamos fazer isso agora para que eles fiquem disponíveis localmente.

$ npm link connect
./node_modules/connect -> /usr/local/lib/node_modules/connect

E agora veremos novamente nossos pacotes locais:

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ connect@1.4.1 -> /usr/local/lib/node_modules/connect extraneous
│ ├── mime@1.2.2
│ └── qs@0.1.0
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Repare que o pacote connect aponta para um diretório na instalação global. Com esse link, é possível utilizar o pacote no projeto/diretório atual.

Alguns desenvolvedores utilizam a variável de ambiente NODE_PATH apontando para /usr/local/lib/node_modules/ porque seus projetos não estão enxergando os pacotes globais. De fato isso funciona, mas não é a maneira adequada, pois se você instalar um pacote local e outro global utilizando essa configuração, o pacote global vai prevalecer sobre o local, o que não deveria ser o comportamento esperado.

É importante entender que o escopo local é definido tão somente pelo diretório que você está. Se você voltar um diretório e listar novamente os pacotes perceberá que não tem nada instalado ou a lista de pacotes instalados é diferente (no caso de você ter instalado algo nesse diretório). Vejamos:

$ cd ..
$ npm ls
/Users/emerson.leite/Pet
(empty)

Voltemos para o diretório anterior e vamos remover o link ao pacote connect.

$ cd -
/Users/emerson.leite/Pet/node-database-cleaner
$ npm unlink connect
$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Nesse momento não temos mais o link para o pacote connect e portanto não podemos mais fazer um require dele.

Utilizando o package.json para gerenciar suas dependências

O arquivo package.json é um arquivo que descreve um pacote NPM. Nesse arquivo também pode/deve ser utilizado para especificar os pacotes que seu projeto depende. Dessa forma, basta estar no diretório e executar npm install que o NPM já instalará as dependências necessárias. Vejamos um exemplo:

{
  "name" : "database-cleaner",
  "description" : "Database Cleaner for node.js",
  "keywords" : [ "database", "cleaner", "mongodb",
                 "redis", "couchdb", "tests", "package.json" ],
  "version" : "0.3.2",
  "author" : "Emerson Macedo ",
  "repository" : {
    "type" : "git",
    "url" : "git://github.com/emerleite/node-database-cleaner.git"
  },
  "dependencies" : {
    "mongoose" : "1.0.10",
    "redis" : ">=0.5.7",
    "cradle" : ">=0.5.x"
  },
  "main": "index",
  "engines" : { "node" : ">=0.2.5" }
}

Vamos limpar o diretório e instalar novamente as dependências para ver como funciona. Primeiro vou apagar o diretório node_modules, listar para mostrar que está vazio e instalar as dependências.

$ rm -fr node_modules/
$ npm ls
npm WARN cradle >=0.5.x Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN mongoose 1.0.10 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN redis >=0.5.7 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├── UNMET DEPENDENCY cradle >=0.5.x
├── UNMET DEPENDENCY mongoose 1.0.10
└── UNMET DEPENDENCY redis >=0.5.7

A resposta mostra que as dependências não estão instaladas, o que vamos resolver agora:

$ npm install
redis@0.6.0 ./node_modules/redis
mongoose@1.0.10 ./node_modules/mongoose
vargs@0.1.0 ./node_modules/cradle/node_modules/vargs
eyes@0.1.6 ./node_modules/cradle/node_modules/vows/node_modules/eyes
vows@0.5.8 ./node_modules/cradle/node_modules/vows
cradle@0.5.5 ./node_modules/cradle

Agora vamos listar apenas para conferir.

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
└── redis@0.6.0

Pra fechar

O NPM tem uma série de outros recursos que vou tentar destacar em outros artigos, mas vejo que muita gente não estava entendendo bem a forma mais adequada de usar a versão 1.0, inclusive apelando para o uso inadequado da variável de ambiente NODE_PATH. Espero que este artigo possa ajudar a explicar um pouco do NPM 1.0.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

[Rafael Biriba] IST-Rio: Inscrições abertas – Vestibular 2011: 2º semestre

Wednesday, May 25th, 2011

 

http://www.faetec.rj.gov.br/ist-rio

http://www.faetec.rj.gov.br/ist-rio

Estão abertas as inscrições para o vestibular de acesso ao curso de Análise de Sistemas Informatizados do IST-Rio (Instituto Superior de Tecnologia em Ciência da Computação do Rio de Janeiro), para o segundo semestre de 2011.

São oferecidas 30 vagas para o turno da manhã e 30 vagas para o turno da noite. As inscrições podem ser feitas pelo site da FAETEC, ou pelo link: http://200.150.155.210/FAETEC_2011.2/ na opção Vestibular Faetec – IST.

O período para inscrições vai de 23/05/2011 até 17/06/2011, segundo as informações no site da organizadora do concurso.

De acordo com o INEP/MEC o curso (Análise de Sistemas Informatizados do IST-Rio) é o 2º melhor do Rio de Janeiro e o 8º melhor do Brasil…

Não perca essa oportunidade! Qualquer dúvida ligue para (21) 2332-4048. Boa Sorte a todos os candidatos… ;)

Links Úteis: ( vestibular 2º semestre / 2011 )
Site do instituto: http://www.faetec.rj.gov.br/ist-rio/
Link direto para inscrição no vestibular:
http://200.150.155.210/FAETEC_2011.2/Inscricao/Formulario.asp?opcao=4
Link direto para o edital:
http://200.150.155.210/FAETEC_2011.2/Divulgacao/Edital%20Vestibulas_2011_2_Final.doc
Link direto para o calendário: http://200.150.155.210/FAETEC_2011.2/Divulgacao/CALENDARIO_Vestibular_2011_2_Final.doc
Link direto para o anexo de vagas: http://200.150.155.210/FAETEC_2011.2/Divulgacao/Quadro%20de%20Vagas_Vestibular_2011_2_Final.doc
Link direto para referencia de estudo para a prova:
Não encontrei o link para a matriz de referência para base de estudo =/

Abaixo segue umas imagens do instituto:

istrio

Endereço:
Rua Clarimundo de Melo, 847, Quintino Bocaiúva, Rio de Janeiro, RJ – CEP: 21311-280

Leia também:


[Guilherme Garnier] Gerenciando múltiplas versões de Ruby no Windows

Thursday, May 19th, 2011

O RVM já se tornou a opção padrão para gerenciar múltiplas versões de Ruby. Ele permite instalar várias versões, alternar entre elas, instalar gems em cada versão independentemente… mas não funciona em ambiente Windows. Eu sei que este não é um ambiente muito popular para desenvolvimento Ruby, mas existem usuários de Windows (seja por opção ou por obrigação) programando em Ruby. Para estes, uma alternativa ao RVM é o Pik.

O Pik funciona de forma bastante semelhante ao RVM. Para instalá-lo, primeiro é necessário instalar o Ruby Installer, um pacote pré-configurado especialmente para instalar o Ruby no Windows. A documentação do Pik recomenda a versão 1.8.7. Em seguida, instale as gems rake, isolate e o próprio pik:

gem install rake isolate pik

Antes de instalar o isolate, talvez seja necessário atualizar o Rubygems com o comando abaixo:

gem update --system

O próximo passo é instalar o Pik no diretório de sua preferência. Um detalhe importante que já me custou um bom tempo é que o path completo não deve conter espaços. Execute o seguinte comando para instalar em C:\Ruby\pik, por exemplo:

pik_install C:\Ruby\pik

Concluída a instalação, o comando pik help commands exibe uma lista com os comandos disponíveis. Quem já usou o RVM não terá dificuldades, pois os comandos são bem semelhantes. Os comandos mais comuns são:

  • pik install ruby/jruby/ironruby [versão] -> instala a versão desejada do Ruby, JRuby ou IronRuby. A versão é opcional; se for omitida, será instalada a versão mais recente. Importante: antes de executar este comando, instale o 7zip e adicione-o ao path
  • pik list -> exibe as versões de Ruby atualmente instaladas
  • pik use [versão] -> seleciona uma versão instalada
  • pik gem [comando] -> executa um comando do Rubygems em todas as versões instaladas
  • pik ruby [parâmetros] -> executa Ruby em todas as versões instaladas

Inicialmente, o comando pik list exibe apenas a versão 1.8.7:

C:\Ruby\pik>pik list
* 187: ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]

Decidi instalar a última versão do Ruby e do JRuby. Após instalar estas duas versões, a saída do comando pik list ficou assim (o asterisco mostra a versão atualmente em uso):

C:\Ruby\pik>pik install ruby
...
C:\Ruby\pik>pik install jruby
...
C:\Ruby\pik>pik list
  161: jruby 1.6.1 (ruby-1.8.7-p330) (2011-04-12 85838f6) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows XP-x86-java]
* 187: ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]
  192: ruby 1.9.2dev (2010-05-31) [i386-mingw32]

Para selecionar o JRuby, por exemplo, use o comando pik use 161 (é importante lembrar que neste caso os comandos mudam de nome: irb vira jirb, ruby vira jruby):

C:\Ruby\pik>pik use 161

C:\Ruby\pik>ruby -v
'ruby' não é reconhecido como um comando interno
ou externo, um programa operável ou um arquivo em lotes.

C:\Ruby\pik>jruby -v
jruby 1.6.1 (ruby-1.8.7-p330) (2011-04-12 85838f6) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows XP-x86-java]

Para instalar gems, basta usar o comando gem install normalmente. A gem será instalada na versão atual do Ruby (ou seja, a que você selecionou com o comando pik use). O comando pik gem permite instalar uma gem em todas as versões:

C:\Ruby\pik>pik gem install mongo
jruby 1.6.1 (ruby-1.8.7-p330) (2011-04-12 85838f6) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows XP-x86-java]

Fetching: bson-1.3.1-jruby.gem (100%)
Fetching: mongo-1.3.1.gem (100%)
Successfully installed bson-1.3.1-java
Successfully installed mongo-1.3.1
2 gems installed

ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]

Fetching: bson-1.3.1.gem (100%)
Fetching: mongo-1.3.1.gem (100%)
Successfully installed bson-1.3.1
Successfully installed mongo-1.3.1
2 gems installed
Installing ri documentation for bson-1.3.1...
Installing ri documentation for mongo-1.3.1...
Installing RDoc documentation for bson-1.3.1...
Installing RDoc documentation for mongo-1.3.1...

ruby 1.9.2dev (2010-05-31) [i386-mingw32]

Successfully installed bson-1.3.1
Successfully installed mongo-1.3.1
2 gems installed
Installing ri documentation for bson-1.3.1...
Installing ri documentation for mongo-1.3.1...
Installing RDoc documentation for bson-1.3.1...
Installing RDoc documentation for mongo-1.3.1...

O comando pik ruby permite executar um código em todas as versões instaladas, útil para verificar incompatibilidades entre as versões, como por exemplo o construtor com parâmetros da classe Time:

C:\Ruby\pik>pik ruby -e "puts Time.new('2011-01-01')"
jruby 1.6.1 (ruby-1.8.7-p330) (2011-04-12 85838f6) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows XP-x86-java]

ArgumentError: wrong number of arguments (1 for 0)
  (root) at -e:1

ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]

-e:1:in `initialize': wrong number of arguments (1 for 0) (ArgumentError)
        from -e:1:in `new'
        from -e:1

ruby 1.9.2dev (2010-05-31) [i386-mingw32]

2011-01-01 00:00:00 -0200

Mais detalhes sobre o funcionamento do Pik podem ser encontrados no Github do projeto.

Posts relacionados:



[Tarsis Azevedo] Vagrant - Maquinas virtuais leves e rapidas

Monday, May 16th, 2011

Se voce é programador e precisa subir maquinas virtuais pra testar sites no IE 6/7/8/9, ou quer fazer deploy para ambientes iguais os de produção, e pra mais varias coisas que precisam ser rapidas e são mega chatas e demoradas, e voce usa VirtualBox – Voce esta fazendo isso errado.

Ok, entao eu uso o que?

O vagrant é uma ferramenta para a construção e distribuição de ambientes dedesenvolvimento virtualizados, escrita em ruby que usa o VirtualBox da Oracle como base, e prove funcionalidades que permitem criar, distribuir, reproduzir e configurar Maquinas Virtuais(VM) de forma rapida (fonte: github do projeto).

ComoFas


Como eu disse anterior mente é muito facil, basta ter o ruby, e a virtualbox instalada, uma internet boa ajuda tambem.

Tendo isso instalado vamos começar:

Execute esse comando:

$ gem install vagrant

Certifique-se que tudo está instalado corretamente.

Antes de criar sua maquina, crie uma pasta para abrigar os arquivos de configuraçao:

$ mkdir vagrant-machine

Agora vamos criar uma VM com ubuntu 10.04

$ cd vagrant-machine
$ vagrant box add lucid32 http://files.vagrantup.com/lucid32.box
$ vagrant init lucid32
$ vagrant up

Feito isso sua VM ja está pronta para ser acessada!

Mas é só isso mesmo?!

Claro que nao!!! Agora vamos configurar seu ambiente!
Primeiro, abra o arquivo Vagrantfile na pasta vagrant-machine e deixe ele assim:

Vagrant::Config.run do |config|
  # Setup the box
  config.vm.box = "lucid32"
end

Execute o comando de reload para carregar suas modificações

$ vagrant reload

Teste o acesso a sua VM para ver se está funcionando corretamente

$ vagrant ssh

OBS: Tudo que voce colocar na pasta onde está seu Vagrantfile, aparecerá na VM na pasta /vagrant. Para ter certeza, execute este comando na VM:

$ ls /vagrant

Agora acabou?

Bom agora voce tem que instalar os pacotes que voce precisa no seu ambiente.
Para isso eu escolhi usar o chef para gerenciar a instalação.
Esse processo depende muito do seu ambiente, entao deixarei referencias para montagem de ambientes usando o chef.

Para estudar o vagrant e o chef eu fiz uma VM configurada para ser um servidor de CI

Nela estao instalados os seguintes pacotes:
* Django 1.3
* Apache
* git
* MySql
* Jenkins (servidor de CI)

Download aqui

OBS: Execute a VM e acesse o servidor de CI pela url http://localhost:8080/

Referencias:

Bom, é isso, divirtam-se com suas novas VMs rapidas e praticas.

Duvidas e criticas, deixem nos comentarios.

Até a proxima

Permalink

| Leave a comment  »

[Tarsis Azevedo] Vagrant - Maquinas virtuais leves e rapidas

Monday, May 16th, 2011

Se voce é programador e precisa subir maquinas virtuais pra testar sites no IE 6/7/8/9, ou quer fazer deploy para ambientes iguais os de produção, e pra mais varias coisas que precisam ser rapidas e são mega chatas e demoradas, e voce usa VirtualBox – Voce esta fazendo isso errado.

Ok, entao eu uso o que?

O vagrant é uma ferramenta para a construção e distribuição de ambientes dedesenvolvimento virtualizados, escrita em ruby que usa o VirtualBox da Oracle como base, e prove funcionalidades que permitem criar, distribuir, reproduzir e configurar Maquinas Virtuais(VM) de forma rapida (fonte: github do projeto).

ComoFas


Como eu disse anterior mente é muito facil, basta ter o ruby, e a virtualbox instalada, uma internet boa ajuda tambem.

Tendo isso instalado vamos começar:

Execute esse comando:

$ gem install vagrant

Certifique-se que tudo está instalado corretamente.

Antes de criar sua maquina, crie uma pasta para abrigar os arquivos de configuraçao:

$ mkdir vagrant-machine

Agora vamos criar uma VM com ubuntu 10.04

$ cd vagrant-machine
$ vagrant box add lucid32 http://files.vagrantup.com/lucid32.box
$ vagrant init lucid32
$ vagrant up

Feito isso sua VM ja está pronta para ser acessada!

Mas é só isso mesmo?!

Claro que nao!!! Agora vamos configurar seu ambiente!
Primeiro, abra o arquivo Vagrantfile na pasta vagrant-machine e deixe ele assim:

Vagrant::Config.run do |config|
  # Setup the box
  config.vm.box = "lucid32"
end

Execute o comando de reload para carregar suas modificações

$ vagrant reload

Teste o acesso a sua VM para ver se está funcionando corretamente

$ vagrant ssh

OBS: Tudo que voce colocar na pasta onde está seu Vagrantfile, aparecerá na VM na pasta /vagrant. Para ter certeza, execute este comando na VM:

$ ls /vagrant

Agora acabou?

Bom agora voce tem que instalar os pacotes que voce precisa no seu ambiente.
Para isso eu escolhi usar o chef para gerenciar a instalação.
Esse processo depende muito do seu ambiente, entao deixarei referencias para montagem de ambientes usando o chef.

Para estudar o vagrant e o chef eu fiz uma VM configurada para ser um servidor de CI

Nela estao instalados os seguintes pacotes:
* Django 1.3
* Apache
* git
* MySql
* Jenkins (servidor de CI)

Download aqui

OBS: Execute a VM e acesse o servidor de CI pela url http://localhost:8080/

Referencias:

Bom, é isso, divirtam-se com suas novas VMs rapidas e praticas.

Duvidas e criticas, deixem nos comentarios.

Até a proxima

Permalink

| Leave a comment  »