First Day in GUADEC

As some of you may know Gnome Users and Developers Congress (a.k.a. GUADEC) is taking place in Istanbul, Turkey at Bahcesehir University. And on it’s 4th day, it was my first day!

I had not have too much time to join discussions but, I’m sure I’m gonna attend tomorrow in the morning too. I had signed up over the internet and, GUADEC had some great stuff to give me as an attendee. A messenger back, a GUADEC 2008 t-shirt, a notepad (moleskin copy but red and written Google on it), a lots of commercial stuff about Turkey, Fedora 9 Live DVD, Ubuntu 8.04 CD and a 4G Mandriva bootable flash disk!

I had the chance to attend only two presentations, one was about Telepathy, a network framework that can be used to create multi user chat applications and other things. While at first I was intrested, the guy who was talking was not as good as a spokesman as a geek. I did not understand much of things he talked about but It was a good thing I guess.

The second one was about Moonlight, a Linux emulation of Silverlight. It was better than the previous one. The presentator was talking better but he had experienced some issues with his laptop. Anyway, It was intresting to see a Microsoft presentation in a Linux related congress. As Novell had some contracts with Microsoft, I guess this Silverlight emulation was about this as there is a group, full time worker in Novell who only does this job. I guess it’s also about that Adobe is not yet implemented Flash in Linux too. And this gap will be filled with Moonlight. It was funny to watch animations by the way. With it’s power to use C++ API and XAML markup language, it’s intresting. You have to use Mono for easily developing it. But any editors goes. But Mono is the easiest and most powerful I guess, at least that was what the man told.

It was great too see people in the conference room using their laptops during the presentation. You can argue that this is a disrespect to the man who is talking, but It was not the case in here. We are all geeks!! I really felt that I was not alone in the world and there is a lots of people around the globe that was like me!

While listening, some light bulbs had come on my mind that, joining these kind of congress open your way and mind up. When I had gone there, I was hoping there was somethings about Online Desktops but I had mistaken and I encountered something completely differently there and I entered to the discussion which I liked it’s name and it was enlightening and enjoying to do that.

Tomorrow I will go there just for that!

Leave a Comment

Development Diaries in Weburunu

Weburunu, also named as SanalDoku (meaning virtual texture/pattern in turkish) is a good framework for creating web sites and also a simple content management system.

It has its dead ends too of course. Even it’s a powerful tool, it’s not too easy to develop with it. You have to get some practice on it. While you practice writing code with it, you enjoy using it and fascinate with ideas in it, at least I had. Even it started to get a little older it’s still powerful and flexible.

During trainings about Weburunu I mentioned some things that can be added, since we need them but don’t have too much time to write their code or design them. These are some of my thoughts and they may take Weburunu one step ahead or it can be needles as there are some different projects going on.

Well in passing days I worked on the search part of WBU and added a template search in it. Now you are able to search in display templates and it will show you the results. It can be a useful tool or just nothing. Anyone who wants to try can try it from my home directory from any wbu website’s admin panel. Just search something and below the content results there will be template results.

One more thing that can be added is, the editing of these templates from the web browser. Without the need to open an html editor or emacs or vi, we should be able to edit these display types from admin panel. This will give us more freedom and perhaps more control over our product. Or it will just create a security hole.

Another thing is to add a form generator script to content types. Which will really take Weburunu one step ahead, and it will be really more user friendly and perhaps developer friendly. By this way we can really create content types that are different than others. How these values can be defined is a different discussion anyway, but if someone must intend to write them down, then we can discuss it anyway.

Not many people tries to change or improve the Weburunu’s core as many people try to use it as tools and not to get involved deep in it. But this will help you more to understand it and also will give more insight on how to write a framework :)

Leave a Comment

Parkyeri Planet

Someone, one of the interns, started a “Planet”, in the Company and that’s a post to try it out. Even I’m not a good blog writer, interns are started to change something just as the last year. I guess internship is a good thing for both the company and the company.

Leave a Comment

Code Smells

In recent days I have read an article about “Code Smells”. I was not aware of such a thing since then. I mean I was aware that people was writing bad code but I had not known there was a name for it. Anyway after reading the 3 part of the article at metapundit.net, I was really surprised to see people like me who actually think like me when writing code.

I know that development is about functionality, most often also about scalability and maintainability. Well most of the time you write a class constructor like:


public function Foo($a, $b, $c) {
$this->a = $a;
$this->b = $b;
$this->c = $c;
}

In most of the time you write down this kind of things. The part itself is repeating! Yuu just do the same thing, copy and paste. It’s perfectly understandable to do this. Because we are in the creation of it. How about something like this:


public function($a, $b, $c) {
$args = array("a", "b", "c");
foreach ($args as $arg)
$this->$arg = $$arg;
}

Is it cool? I know that it looks like lame. But isn’t the previous one looked lame too. I have not even reduced the lines of code. But think of adding another parameter to the function, then you have to copy paste another line doing the same thing but you just add another item in the array and lines are decreased. Instead of defining the arguments on the place where you define functions, you may use “func_get_args()” to get them and use the $args array to set them as you know which param is coming. Same thing can be done for most of the set and get functions


public function get($arg) {
return $this->$arg;
}
public function set($arg, $value) {
$this->$arg = $value;
}

Is it lame? Kind of, as you have lost lots of methods about getting and setting. I know that gets and sets are not used by this way. You may add some validations to it or some protections on it. Maybe you want to set to a new date and check if the day is 32 or not or if the month is 13 or something else. But that’s not the point. What I try to mean is, by this way you write less and create a more maintainable code I guess. It’s about functionality I suppose.

As metapundit mentioned, first thing we learn about programming is “loops”. The basic loops and, in most of the cases we pass down this first lesson and keep hard coding. How many of you created a form like:


<table>
<tr>
<td>Field 1</td>
<td><input type="text" name="field1"></td>
</tr>
<tr>
<td>Field 2</td>
<td><input type="text" name="field2"></td>
</tr>
<tr>
<td>Field 3</td>
<td><input type="text" name="field3"></td>
</tr>
</table>

Have you though of:


<table>
<?php
$fields = array("field1" => "Field 1", "field2" => "Field 2", "field3" => "Field 3");
foreach ($fields as $key => $val) {
echo '<tr><td><?=$val?></td><td><input type="text" name="<?=$key?>"></td></tr>';
}
?>
</table>

Isn’t this doing the same thing while giving you an understandable and maintainable code? I know that logic and design must be separated. So in this case our sample will change into something like:


<?php
$fields = array("field1" => "Field 1", "field2" => "Field 2", "field3" => "Field 3");
foreach ($fields as $key => $val) {
$template->setBlock("TEMPLATE1");
$template->setVariable(array("KEY"=>$key, "VAL" => $val));
$template->parseBlock();
}
?>
<table>
<!-- BEGIN TEMPLATE1 -->
<tr><td>{VAL}</td><td><input type="text" name="{KEY}"</td></tr>
<!-- END TEMPLATE1 -->
</table>

Syntax may change but the idea remains. You can also improve the way you define your form field elements in a way that template’s variable setting method accept it as it is.


<?php
$fields = array(array("key" => "field1", "val" => "Field 1"), array("key" => "field2", "val" => "Field 2"),array( "key" => "field3", "val" =>"Field 3");
for( $i = 0 ; $i < count($fields) ; $i++ ) {
$template->setBlock("TEMPLATE1");
$template->setVariable($fields[$i]);
$template->parseBlock();
}
?>
<table>
<!– BEGIN TEMPLATE1 –>
<tr><td>{VAL}</td><td><input type=”text” name=”{KEY}”</td></tr>
<!– END TEMPLATE1 –>
</table>

Remarked something? I repeat the way I define my variables. So:


<?php
$old_fields = array("field1" => "Field 1", "field2" => "Field 2", "field3" => "Field 3");
foreach ( $old_fields as $key => $val) {
$fields[] array(”key” => $key, “val” => $val);
}
for( $i = 0 ; $i < count($fields) ; $i++ ) {
$template->setBlock(”TEMPLATE1″);
$template->setVariable($fields[$i]);
$template->parseBlock();
}
?>
<table>
<!– BEGIN TEMPLATE1 –>
<tr><td>{VAL}</td><td><input type=”text” name=”{KEY}”</td></tr>
<!– END TEMPLATE1 –>
</table>

You may not want to the last part, but I hope that I was able to explain what I meant.

Anyway I really try to write code like this. Whenever I copy paste a part of a code to somewhere else, I think of creating a function or a loop from it. But in most of the time as my time is limited, I note it down to do it in a later time which I don’t. Only in Boop I try to refactor the code I have written as I’m not pressed on releasing it in a mean time.

Anyway I have given some examples from metapundit and also created my owns too. I hope I was able to explain what I thought when I read about his article. I was really happy to find out someone who was thinking like me but still making that mistakes, just like me!

Leave a Comment

Some More Updates About Boop

Well as you may remember I was working on a cms named Boop for half a year now, at least that’s all I can remember, as I’m the only developer it takes time to get things going. I recently had time to spent with it and things are getting better and better.

Yesterday I have installed a local svn and created a repository named boop and things are getting better since then. I was really anxious about using it a version control system and as now boop had moved from a local directory to a local svn repository I will be able to follow it’s development more easily.

Recent Improvements are about refactoring and API improvements. Everybody can write down code but very few documentate that and I’m one of the few people who really cares that. Well I have documented most of the classes. There are still lots to do but at least it’s a start

I also keep try to create an easily maintainable code, so I delete and re-write some parts of it. I have decided to redesign an old legendary site of mine with it. I guess you will be informed with the beta part of it soon.

Well boop will come sooner I guess but a lot of things depend on my jobs at Parkyeri and my summer school.

Leave a Comment

When writing code…

I know that I’m not the best developer you will find around, but during years I have learned a thing or two. The best advice I can give to you is to write modular codes or use classes. Try to re-use everything you have written, but while re-using, please do not copy paste the samething twice or twenty times.

I’m gonna share with you some lines of code here…


public static string olayekle(anaform anaform,string yazi)
{
string eklendimi = "hayır";
string eklenen_olay_adi = "eklenmedi";
if (anaform.olay1 == "boş" && eklendimi=="hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay1_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay1_son_y;
anaform.uyari1.Text = yazi;
anaform.uyari1.Location = (new Point(13, anaform.olay1_son_y));
anaform.uyari1.Visible = true;
eklendimi = "evet";
anaform.olay1 = "dolu";
eklenen_olay_adi = "olay1";
}else if (anaform.olay2 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay2_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay2_son_y;
anaform.uyari2.Text = yazi;
anaform.uyari2.Location = (new Point(13, anaform.olay2_son_y));
anaform.uyari2.Visible = true;
eklendimi = "evet";
anaform.olay2 = "dolu";
eklenen_olay_adi = "olay2";
}
else if (anaform.olay3 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay3_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay3_son_y;
anaform.uyari3.Text = yazi;
anaform.uyari3.Location = (new Point(13, anaform.olay3_son_y));
anaform.uyari3.Visible = true;
eklendimi = "evet";
anaform.olay3 = "dolu";
eklenen_olay_adi = "olay3";
}
else if (anaform.olay4 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay4_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay4_son_y;
anaform.uyari4.Text = yazi;
anaform.uyari4.Location = (new Point(13, anaform.olay4_son_y));
anaform.uyari4.Visible = true;
eklendimi = "evet";
anaform.olay4 = "dolu";
eklenen_olay_adi = "olay4";
}
else if (anaform.olay5 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay5_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay5_son_y;
anaform.uyari5.Text = yazi;
anaform.uyari5.Location = (new Point(13, anaform.olay5_son_y));
anaform.uyari5.Visible = true;
eklendimi = "evet";
anaform.olay5 = "dolu";
eklenen_olay_adi = "olay5";
}
else if (anaform.olay6 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay6_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay6_son_y;
anaform.uyari6.Text = yazi;
anaform.uyari6.Location = (new Point(13, anaform.olay6_son_y));
anaform.uyari6.Visible = true;
eklendimi = "evet";
anaform.olay6 = "dolu";
eklenen_olay_adi = "olay6";
}
else if (anaform.olay7 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay7_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay7_son_y;
anaform.uyari7.Text = yazi;
anaform.uyari7.Location = (new Point(13, anaform.olay7_son_y));
anaform.uyari7.Visible = true;
eklendimi = "evet";
anaform.olay7 = "dolu";
eklenen_olay_adi = "olay7";
}
else if (anaform.olay8 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay8_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay8_son_y;
anaform.uyari8.Text = yazi;
anaform.uyari8.Location = (new Point(13, anaform.olay8_son_y));
anaform.uyari8.Visible = true;
eklendimi = "evet";
anaform.olay8 = "dolu";
eklenen_olay_adi = "olay8";
}
else if (anaform.olay9 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay9_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay9_son_y;
anaform.uyari9.Text = yazi;
anaform.uyari9.Location = (new Point(13, anaform.olay9_son_y));
anaform.uyari9.Visible = true;
eklendimi = "evet";
anaform.olay9 = "dolu";
eklenen_olay_adi = "olay9";
}
else if (anaform.olay10 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay10_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay10_son_y;
anaform.uyari10.Text = yazi;
anaform.uyari10.Location = (new Point(13, anaform.olay10_son_y));
anaform.uyari10.Visible = true;
eklendimi = "evet";
anaform.olay10 = "dolu";
eklenen_olay_adi = "olay10";
}
else if (anaform.olay11 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay11_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay11_son_y;
anaform.uyari11.Text = yazi;
anaform.uyari11.Location = (new Point(13, anaform.olay11_son_y));
anaform.uyari11.Visible = true;
eklendimi = "evet";
anaform.olay11 = "dolu";
eklenen_olay_adi = "olay11";
}
else if (anaform.olay12 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay12_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay12_son_y;
anaform.uyari12.Text = yazi;
anaform.uyari12.Location = (new Point(13, anaform.olay12_son_y));
anaform.uyari12.Visible = true;
eklendimi = "evet";
anaform.olay12 = "dolu";
eklenen_olay_adi = "olay12";
}
else if (anaform.olay13 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay13_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay13_son_y;
anaform.uyari13.Text = yazi;
anaform.uyari13.Location = (new Point(13, anaform.olay13_son_y));
anaform.uyari13.Visible = true;
eklendimi = "evet";
anaform.olay13 = "dolu";
eklenen_olay_adi = "olay13";
}
else if (anaform.olay14 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay14_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay14_son_y;
anaform.uyari14.Text = yazi;
anaform.uyari14.Location = (new Point(13, anaform.olay14_son_y));
anaform.uyari14.Visible = true;
eklendimi = "evet";
anaform.olay14 = "dolu";
eklenen_olay_adi = "olay14";
}
else if (anaform.olay15 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay15_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay15_son_y;
anaform.uyari15.Text = yazi;
anaform.uyari15.Location = (new Point(13, anaform.olay15_son_y));
anaform.uyari15.Visible = true;
eklendimi = "evet";
anaform.olay15 = "dolu";
eklenen_olay_adi = "olay14";
}
else if (anaform.olay16 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay16_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay16_son_y;
anaform.uyari16.Text = yazi;
anaform.uyari16.Location = (new Point(13, anaform.olay16_son_y));
anaform.uyari16.Visible = true;
eklendimi = "evet";
anaform.olay16 = "dolu";
eklenen_olay_adi = "olay16";
}
else if (anaform.olay17 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay17_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay17_son_y;
anaform.uyari17.Text = yazi;
anaform.uyari17.Location = (new Point(13, anaform.olay17_son_y));
anaform.uyari17.Visible = true;
eklendimi = "evet";
anaform.olay17 = "dolu";
eklenen_olay_adi = "olay17";
}
else if (anaform.olay18 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay18_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay18_son_y;
anaform.uyari18.Text = yazi;
anaform.uyari18.Location = (new Point(13, anaform.olay18_son_y));
anaform.uyari18.Visible = true;
eklendimi = "evet";
anaform.olay18 = "dolu";
eklenen_olay_adi = "olay18";
}
else if (anaform.olay19 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay19_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay19_son_y;
anaform.uyari19.Text = yazi;
anaform.uyari19.Location = (new Point(13, anaform.olay19_son_y));
anaform.uyari19.Visible = true;
eklendimi = "evet";
anaform.olay19 = "dolu";
eklenen_olay_adi = "olay19";
}
else if (anaform.olay20 == "boş" && eklendimi == "hayır")
{
anaform.uyarilar_yukseklik += anaform.uyarilar_arasi;
anaform.olay20_son_y = anaform.uyarilar_son_koor_y + anaform.uyarilar_arasi;
anaform.uyarilar_son_koor_y = anaform.olay20_son_y;
anaform.uyari20.Text = yazi;
anaform.uyari20.Location = (new Point(13, anaform.olay20_son_y));
anaform.uyari20.Visible = true;
eklendimi = "evet";
anaform.olay20 = "dolu";
eklenen_olay_adi = "olay20";
}
return eklenen_olay_adi;
}

Please, I beg you. If you are writing the samething twenty times, you should guess that something is wrong and you have done something wrong at somewhere…

And also, classes are generally singular. You do not create a “cats” class but a “cat” class…

Leave a Comment

Support Developers

There is an intresting movement from developers. They are saying “NO” to IE 6. Well, of course it’s sucks and I really support this action. So If you are visiting this site with an IE6 browser you shall notice a notification. JS engines, bah html rendering, unsecure, easy to crash, why are you still using it anyway?

Check out savethedevelopers.org for additional reasons to upgrade IE6

Leave a Comment

Some Updates About Boop

Well if there are some people who were watching my previous blog, they may know that I was working on a blog system name “boop”. While I was struggling with Wordpress, Drupal, joomla and others I had really bored and decided to write down my I own. Time has passed and I said to myself why to stop with just a “blog”! So Boop project has evolved a bit and become something more and more flexible.

Some key features of Boop is that:

  • Easy to use for everyone with complex features for experts to entertain themselves,
  • Flexible design to match your needs,
  • Create your own types,
  • Supports different language,
  • Support different themes,
  • Customize the look and feel of most things from admin panel, with basic html knowledge or use the power of FCKEditor,
  • Easily port it to any database only with changing few lines of code.

I guess these are the key points of the project. Well, I will try to create a release soon with a “blog bundle” (I’m gonna explain it later…). The only thing left is the API and a good theme which’s suitable for my “simple complex” project.

Leave a Comment

Another Linux and Open Source Seminar in GYTE

Well, as you may know me and my colleagues from Parkyeri, especially with Alper are travelling around universties in Istanbul and try to inform everyone that they can win money without being “evil” or without using Microsoft or .Net platform. And we were at Gebze Yüksek Teknoloji Enstitüsü. It’s was a really cool place anyway, but that’s kind of a commercial so I pass.

I guess this was the best of em because people knew what we were talking about and they were curious about it. In previous seminar we had the problem to tell everyone what was Linux and what was open source, why you had to “buy” a license Windows and not crack it. Anyway none of these happened there! They were really informed and well trained even there were mostly freshmen in the seminar. Everyone was intrested and everyone was curios about something and we tried to share everything we know about software, linux, money and companies.

Well I suppose this was the last of the season even that I hope, we will go some more universities because it’s really fun to be there and talking. I was looking forward to share some pictures and we have taken none! The GYTE IEEE student brach members shoot some and I hope they will share it with me. (I couldn’t find there web site so can’t put a link on it, but will find soon)

Leave a Comment

NetBeans 6 and antscripts

Well it’s really a pain in the ass to have an antscript java file and use it in the NetBeans. What the real problem is to show class paths and runs it. I really hated it and in the end I also failed.

As I knew that NetBeans was great and should be great I wasted nearly two hours to modify the current build.xml created by Netbeans to create a build.xml which fits my requirements. I tried to add things, remove, modify my ant script to work with NetBeans run command. Anyway I have failed.

After a day of trial I have decided that black screen VIM is better, faster, safer and easier then NetBeans. AND to write “ant deploy” is much better to click on Run!!

Leave a Comment