<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Here comes the Sun &#187; tools</title>
	<atom:link href="http://sunng.info/blog/tag/tools/feed/" rel="self" type="application/rss+xml" />
	<link>http://sunng.info/blog</link>
	<description>47% users on this site use *nix</description>
	<lastBuildDate>Sat, 04 Feb 2012 13:08:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>包管理与路径管理</title>
		<link>http://sunng.info/blog/2011/01/%e5%8c%85%e7%ae%a1%e7%90%86%e4%b8%8e%e8%b7%af%e5%be%84%e7%ae%a1%e7%90%86/</link>
		<comments>http://sunng.info/blog/2011/01/%e5%8c%85%e7%ae%a1%e7%90%86%e4%b8%8e%e8%b7%af%e5%be%84%e7%ae%a1%e7%90%86/#comments</comments>
		<pubDate>Sat, 22 Jan 2011 08:07:17 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/2011/01/%e5%8c%85%e7%ae%a1%e7%90%86%e4%b8%8e%e8%b7%af%e5%be%84%e7%ae%a1%e7%90%86/</guid>
		<description><![CDATA[现在几乎每一种语言都有一些依赖管理工具，或者是中央的包仓库。比如这些： Java: maven, ivy, gradle Ruby: gems Python: easy_install, pip Clojure: leinigen Groovy: maven, grape, gradle Hashkell: cabal PHP: pear Nodejs: npm 这些工具在管理包和路径时都会采用各不相同的策略，有的是通过自身实现，有的是借助语言平台本身的特点。 Java 其中最注明的Maven，它的方式是在POM文件中定义你的依赖，Maven会在本地仓库中维护这些依赖。Maven的本地仓库默认是在$HOME/.m2/repository目录下，是用户独立的，当然要下载一个依赖也不需要root权限。而在通过Maven运行Java项目时，Maven插件会自动管理classpath，你并不需要把这些依赖从本地仓库里拷贝出来而单独维护一个所谓lib目录（这样也不好管理）。这是Maven的方式，目前看来，这也是最经典的一种方式。除了maven本身的特性以外，这也和Java的classpath机制有关。 最近势头很猛的Java构建工具gradle，方式也与Maven类似，它会把下载的依赖存放在$HOME/.gradle/cache目录里，并自动管理classpath。 同样是Java，与maven相对应的是ant+ivy。ivy可以为你管理依赖，但是ivy不会帮你管理classpath。ivy的包管理，是以project为scope的，你需要维护一个lib目录来存放这些下载的包，再通过传统的ant的方式去管理classpath，从而使项目可以进行编译和运行。 在Java世界里，还有一个特别的工具叫做grape，它是专门用于groovy的轻量级的依赖解决方案。grape是以脚本为scope，在需要依赖的脚本中通过@Grab声明依赖，grape工具可以从maven仓库中下载依赖到$HOME/.groovy/grapes中，并把相关的依赖加入groovy的classpath。除此以外，grape还有一个命令行工具帮助你手动下载依赖到本地仓库。grape的内部是基于ivy的，不过它的方式比ant要自动化很多。 在Java世界里还有一个特例，是Clojure的依赖管理工具leiningen。leiningen本身也比较简单，它的方式与ivy相同，会解析project.clj文件中定义的依赖关系，并下载到当前的工程目录下的lib中。lein是鼓励通过uberjar的方式把依赖统统打包的，所以它并没有classpath的管理功能。 总体来说，Java世界的工具和Java是相似的，其最大特点就是System independent，安装包不需要root权限，每次的运行都需要管理classpath。作为开发人员，classpath中有哪些可以访问的类库是可以控制的，这也使Java程序的移植性得到良好的控制和管理。 Python 与Java不同，Python通常作为系统分发的一部分，他的包管理和PATH管理要相对混乱一些。通常我们有两种方式来安装一个Python的软件包： sudo apt-get install python-redis sudo easy_install redis &#8230; <a href="http://sunng.info/blog/2011/01/%e5%8c%85%e7%ae%a1%e7%90%86%e4%b8%8e%e8%b7%af%e5%be%84%e7%ae%a1%e7%90%86/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>现在几乎每一种语言都有一些依赖管理工具，或者是中央的包仓库。比如这些：</p>
<ul>
<li>Java: maven, ivy, gradle</li>
<li>Ruby: gems</li>
<li>Python: easy_install, pip</li>
<li>Clojure: leinigen</li>
<li>Groovy: maven, grape, gradle</li>
<li>Hashkell: cabal</li>
<li>PHP: pear</li>
<li>Nodejs: npm</li>
</ul>
<p>这些工具在管理包和路径时都会采用各不相同的策略，有的是通过自身实现，有的是借助语言平台本身的特点。</p>
<h3>Java</h3>
<p>其中最注明的Maven，它的方式是在POM文件中定义你的依赖，Maven会在本地仓库中维护这些依赖。Maven的本地仓库默认是在$HOME/.m2/repository目录下，是用户独立的，当然要下载一个依赖也不需要root权限。而在通过Maven运行Java项目时，Maven插件会自动管理classpath，你并不需要把这些依赖从本地仓库里拷贝出来而单独维护一个所谓lib目录（这样也不好管理）。这是Maven的方式，目前看来，这也是最经典的一种方式。除了maven本身的特性以外，这也和Java的classpath机制有关。</p>
<p>最近势头很猛的Java构建工具gradle，方式也与Maven类似，它会把下载的依赖存放在$HOME/.gradle/cache目录里，并自动管理classpath。</p>
<p>同样是Java，与maven相对应的是ant+ivy。ivy可以为你管理依赖，但是ivy不会帮你管理classpath。ivy的包管理，是以project为scope的，你需要维护一个lib目录来存放这些下载的包，再通过传统的ant的方式去管理classpath，从而使项目可以进行编译和运行。</p>
<p>在Java世界里，还有一个特别的工具叫做grape，它是专门用于groovy的轻量级的依赖解决方案。grape是以脚本为scope，在需要依赖的脚本中通过@Grab声明依赖，grape工具可以从maven仓库中下载依赖到$HOME/.groovy/grapes中，并把相关的依赖加入groovy的classpath。除此以外，grape还有一个命令行工具帮助你手动下载依赖到本地仓库。grape的内部是基于ivy的，不过它的方式比ant要自动化很多。</p>
<p>在Java世界里还有一个特例，是Clojure的依赖管理工具leiningen。leiningen本身也比较简单，它的方式与ivy相同，会解析project.clj文件中定义的依赖关系，并下载到当前的工程目录下的lib中。lein是鼓励通过uberjar的方式把依赖统统打包的，所以它并没有classpath的管理功能。</p>
<p>总体来说，Java世界的工具和Java是相似的，其最大特点就是System independent，安装包不需要root权限，每次的运行都需要管理classpath。作为开发人员，classpath中有哪些可以访问的类库是可以控制的，这也使Java程序的移植性得到良好的控制和管理。</p>
<h3>Python</h3>
<p>与Java不同，Python通常作为系统分发的一部分，他的包管理和PATH管理要相对混乱一些。通常我们有两种方式来安装一个Python的软件包：</p>
<ul>
<li>sudo apt-get install python-redis</li>
<li>sudo easy_install redis</li>
</ul>
<p>一种是通过系统的包管理工具（如apt-get）从系统的软件仓库里安装，一种是通过python自己的包管理工具（如easy_install / pip）从Python Cheese Shop中下载安装。这两种安装方式有什么不同呢。以Ubuntu为例，通过apt-get安装的python包通常会被放在 /usr/share/pyshared 或 /usr/lib/python2.6/dist-packages 中，相对应的，由easy_install安装的Python包，则存放在 /usr/local/lib/python2.6/dist-packages 中。Python启动后可以通过查看sys.path来了解当前的path情况。</p>
<p>除了安装到系统目录，easy_install可以通过 &#8211;user 选项来把软件包安装到用户目录 $HOME/.local/lib/python2.6/site-packages。不过无论是系统级别还是用户级别，python都很难在启动时管理Path，即任何时候python都可以访问安装在系统中的所有软件包。这导致了混乱的情况，导致编写的python软件难以进行依赖管理和移植（即使没有定义在setup.py中，很多依赖还是可以访问的）。</p>
<p>由此virtualenv营运而生，virtualenv帮助你创建一个独立的python运行环境。激活这个小环境之后，easy_install/pip仅仅安装软件到小环境，python仅能访问环境内部的site-packages，这样整个环境中的依赖关系就非常清楚，也保障了程序的移植性。这样，就将原本系统scope的python包管理级别改进为项目级别。我之前写的jip也是将依赖下载或拷贝到virtualenv的小环境中，并且修改jython的启动脚本修改PYTHONPATH的设置，保证Java依赖对Jython的透明可访问。</p>
<h3>Nodejs</h3>
<p>nodejs是一个新兴的生态系统，一个包管理工具对其也是必不可少。npm是目前整个社区都比较认可的工具。</p>
<p>不过目前npm并不好用。npm默认会把自己安装到 node安装前缀的目录，比如node安装时你选择了默认前缀/usr/local，那么npm会把自己安装到/usr/local/lib/node里。这个目录是系统级别的，所以需要root权限，而npm本身又不鼓励用户用root权限来安装软件包（安全问题）。所以作者说希望用户把/usr/local/lib/node权限授予用户，或者把node安装到用户目录里。这两种方式其实都不太优雅。</p>
<p>Ruby的gems在这方面最符合unix哲学，即用户知道自己在做什么。如果用户以root权限运行gem  install，gem会把软件包安装到系统目录中对所有用户可用，而如果以普通用户权限运行，则安装到用户目录 $HOME/.gem 中仅当前用户可见。</p>
<p>nodejs在加载软件包时，会在require.paths中的几个目录里查找，前两个都是用户目录，所以npm也并非一定要把包安装到系统目录里去。虽然现在可以用过修改.npmrc文件在修改npm的默认行为，不过在这个CoC的时代，显然太繁琐了。</p>
<h3>Best Pratice</h3>
<p>总结一下，包管理和路径管理的最佳实践应该是：语言平台有CoC的路径机制，包管理器有基于环境变量、用户权限的判断执行合适行为。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2011/01/%e5%8c%85%e7%ae%a1%e7%90%86%e4%b8%8e%e8%b7%af%e5%be%84%e7%ae%a1%e7%90%86/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SQuirrel SQL Client 3发布了</title>
		<link>http://sunng.info/blog/2009/02/squirrel-sql-client-3%e5%8f%91%e5%b8%83%e4%ba%86/</link>
		<comments>http://sunng.info/blog/2009/02/squirrel-sql-client-3%e5%8f%91%e5%b8%83%e4%ba%86/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 08:54:16 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[swing]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.classicning.com/blog/?p=21</guid>
		<description><![CDATA[SQuirrel SQL Client是一个用Java写的数据库客户端，用JDBC统一数据库访问接口以后，可以通过一个统一的用户界面来操作MySQL PostgreSQL MSSQL Oracle等等任何支持JDBC访问的数据库。使用起来非常方便。而且，SQuirrel SQL Client还是一个典型的Swing程序，也算是Swing的一个比较成功的应用了。 2.x版本的SQuirrel SQL Client一直是用JDesktopPane和JInternalFrame来组织界面。这次发布的3.0最大的变化就是改用现在更加流行的Dock方式组织窗口。 07年开始我一直用这个工具，后来在某处实习时，意外地发现组里以前也有人用这个工具（不过后来没有人再用了），一问，原来也是之前我们学校的同学。看来，一个学校的果然还是有一点相同，呵呵。]]></description>
			<content:encoded><![CDATA[<p>SQuirrel SQL Client是一个用Java写的数据库客户端，用JDBC统一数据库访问接口以后，可以通过一个统一的用户界面来操作MySQL PostgreSQL MSSQL Oracle等等任何支持JDBC访问的数据库。使用起来非常方便。而且，SQuirrel SQL Client还是一个典型的Swing程序，也算是Swing的一个比较成功的应用了。</p>
<p>2.x版本的SQuirrel SQL Client一直是用JDesktopPane和JInternalFrame来组织界面。这次发布的3.0最大的变化就是改用现在更加流行的Dock方式组织窗口。</p>
<p>07年开始我一直用这个工具，后来在某处实习时，意外地发现组里以前也有人用这个工具（不过后来没有人再用了），一问，原来也是之前我们学校的同学。看来，一个学校的果然还是有一点相同，呵呵。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2009/02/squirrel-sql-client-3%e5%8f%91%e5%b8%83%e4%ba%86/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

