alex's blog |
You could just delete your working copy and check out a fresh one. In my case, that takes hours. So I wanted to find a way to remove all local modifications. svn st | awk '{ if ( $1 == "?" ) print $2 }' | xargs rm -Rf svn st | awk '{ if ( $1 == "M" ) print $2 }' | xargs svn revert Remove all files whos' svn status is '?', meaning not part of version control. Then revert changes in any file which has an "M" (modified) status. svt st You should now have no local changes or unknown files. WARNING |
|||
Create a Demo ProjectI'll create a basic project to demonstrate how the merge-tracking features in Subversion 1.5 work. This isn't exactly new, but it's new to me since our company just upgraded our svn server. $ svnadmin create frobulator-repo $ mkdir skeleton $ mkdir skeleton/trunk $ touch skeleton/trunk/frob.rb $ mkdir skeleton/branches $ mkdir skeleton/branches/release-1.0.0 $ cp skeleton/trunk/frob.rb skeleton/branches/release-1.0.0/ $ svn import skeleton file:///Users/alex/tmp/frobulator-repo -m 'initial import' Adding skeleton/trunk Adding skeleton/trunk/frob.rb Adding skeleton/branches Adding skeleton/branches/release-1.0.0 Adding skeleton/branches/release-1.0.0/frob.rb Committed revision 1. $ svn co file:///Users/alex/tmp/frobulator-repo frobulator-wc A frobulator-wc/trunk A frobulator-wc/trunk/frob.rb A frobulator-wc/branches A frobulator-wc/branches/release-1.0.0 A frobulator-wc/branches/release-1.0.0/frob.rb Checked out revision 1. Make a ChangeSo far, I've created a new repository with a trunk and 1 branch. The trunk and branch have identical content right now, a single empty frob.rb file. I'll fix a 'bug' in the trunk now. $ cd frobulator-wc/trunk frobulator-wc/trunk$ echo 'puts "bug fixed!"' > frob.rb frobulator-wc/trunk$ svn commit -m 'fixed bug in frob.rb' Sending trunk/frob.rb Transmitting file data . Committed revision 2. Merge FixNow I want to merge my bug fix into my release branch. frobulator-wc/trunk$ cd ../branches/release-1.0.0/ frobulator-wc/branches/release-1.0.0$ svn merge -c 2 file:///Users/alex/tmp/frobulator-repo/trunk . --- Merging r2 into '.': U frob.rb frobulator-wc/branches/release-1.0.0$ svn commit -m 'merge bug fix from trunk' Sending release-1.0.0 Sending release-1.0.0/frob.rb Transmitting file data . Committed revision 3. View Basic LogUp to this point, there's nothing different from how I would have done things in subversion 1.4, except that my commit in the branch didn't mention where the merge came from. Formerly, I would have added a commit log like "merged trunk r2 into release-1.0.0". Otherwise we wouldn't have known what got merged and what didn't. Notice the log only shows changes which were made in this branch. This behavior is the same as in previous version of Subversion. frobulator-wc/branches/release-1.0.0$ svn log -v ------------------------------------------------------------------------ r3 | alex | 2010-07-27 09:08:43 -0500 (Tue, 27 Jul 2010) | 1 line Changed paths: M /branches/release-1.0.0 M /branches/release-1.0.0/frob.rb merge bug fix from trunk ------------------------------------------------------------------------ r1 | alex | 2010-07-27 09:04:51 -0500 (Tue, 27 Jul 2010) | 1 line Changed paths: A /branches A /branches/release-1.0.0 A /branches/release-1.0.0/frob.rb A /trunk A /trunk/frob.rb initial import ------------------------------------------------------------------------ View Merge Information in LogThis is where the new merge-tracking features in Subversion 1.5 show themselves. Adding the frobulator-wc/branches/release-1.0.0$ svn log -vg ------------------------------------------------------------------------ r3 | alex | 2010-07-27 09:08:43 -0500 (Tue, 27 Jul 2010) | 1 line Changed paths: M /branches/release-1.0.0 M /branches/release-1.0.0/frob.rb merge bug fix from trunk ------------------------------------------------------------------------ r2 | alex | 2010-07-27 09:07:15 -0500 (Tue, 27 Jul 2010) | 1 line Changed paths: M /trunk/frob.rb Merged via: r3 fixed bug in frob.rb ------------------------------------------------------------------------ r1 | alex | 2010-07-27 09:04:51 -0500 (Tue, 27 Jul 2010) | 1 line Changed paths: A /branches A /branches/release-1.0.0 A /branches/release-1.0.0/frob.rb A /trunk A /trunk/frob.rb initial import ------------------------------------------------------------------------ |
|||
class AnExampleWhichAnnoysMe < ActiveRecord::Migration def self.up create_table :test do |t| t.column :column_a, :integer end add_column :test, :column_b, :integer add_index :test, :column_b, :name=>'idx_on_test_col_b' end def self.down remove_index :test, :name=>'idx_on_test_col_b' remove_column :test, :column_b drop_table :test end end
I wish these were more consistent. The names seem to be based on common SQL commands, but for that to be a useful rule-of-thumb, columns and indexes should be manipulated through some 'alter' method, since ALTER is usually the command you use to change these kinds of objects in SQL. In the context of ActiveRecord, I can see that add & drop really make more sense, but I wish that logic would have been applied to tables as well. As it is, I often make the mistake of using create_table and drop_index. |
|||
Everybody talks about the importance of semantic markup on the web. I think Semitic markup isn't getting nearly enough attention.
|
|||
There have been many times that I've captured some machine-generated XML document for debugging purposes. Usually these documents omit all line breaks, indentation, and other niceties which make the text more readable. Of course no real XML parser cares about such things, but the very-incomplete XML parser in my head really appreciates them. I've spent plenty of time manually re-formatting various documents to get them into some state where I could understand the structure and makes some sense out of it. But, wow, that is tedious work. Click, enter, space, space, click, enter, space, space, etc, etc, etc... I went looking for a better solution, and found xmlformat. You can also use tidy, which is included on OSX by default. I prefer xmlformat because of the ease of configuration. alex@rutabaga:~$ xmlformat --show-config *DEFAULT format = block entry-break = 1 element-break = 1 exit-break = 1 subindent = 2 normalize = no wrap-length = 0 *DOCUMENT format = block entry-break = 0 element-break = 1 exit-break = 1 subindent = 0 normalize = no wrap-length = 0 This is pretty much the default configuration. I keep my configuration in Why is this good?With a single command: alex@rutabaga:~$ xmlformat wfs_getfeature.xml This mess: <wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><wfs:Query typeName="kodos:" srsName="EPSG:4326" xmlns:kodos="http://www.regionsproject.org/kodos"><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:And><ogc:PropertyIsLessThan><ogc:PropertyName>map_id</ogc:PropertyName><ogc:Literal>0</ogc:Literal></ogc:PropertyIsLessThan><ogc:BBOX><ogc:PropertyName>area</ogc:PropertyName><gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:lowerCorner>-227.08007812014 0.922841119201</gml:lowerCorner><gml:upperCorner>17.08007812012 68.341004876129</gml:upperCorner></gml:Envelope></ogc:BBOX></ogc:And></ogc:Filter></wfs:Query></wfs:GetFeature> is transformed into this: <wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <wfs:Query typeName="kodos:" srsName="EPSG:4326" xmlns:kodos="http://www.regionsproject.org/kodos"> <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"> <ogc:And> <ogc:PropertyIsLessThan> <ogc:PropertyName>map_id</ogc:PropertyName> <ogc:Literal>0</ogc:Literal> </ogc:PropertyIsLessThan> <ogc:BBOX> <ogc:PropertyName>area</ogc:PropertyName> <gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"> <gml:lowerCorner>-227.08007812014 0.922841119201</gml:lowerCorner> <gml:upperCorner>17.08007812012 68.341004876129</gml:upperCorner> </gml:Envelope> </ogc:BBOX> </ogc:And> </ogc:Filter> </wfs:Query> </wfs:GetFeature> It's now easy to see what elements are nested inside which other elements. This makes all kinds of debugging and troubleshooting tasks immensely easier. |
|||
A while ago I wanted to be able to upload a GeoTIFF to GeoServer via their REST interface. The default way to do this is to send the GeoTIFF image in an HTTP PUT. In my case, the image was already on the same filesystem as GeoServer's data directory, so sending it again in another HTTP transaction seemed like kind of a waste. I was hoping to find a way to just tell GeoServer to use the GeoTIFF in its current location, without the need to make a copy of the file. I poked around in the source code for GeoServer's REST extension and discovered that this behavior was indeed supported. It just wasn't documented. A while ago I submitted some documentation additions which should make this clearer. This is a common use case, judging by the number of people who ask about this kind of thing on the GeoServer user's mailing list. So, until my patch gets accepted and makes its way into the official GeoServer REST API docs, I thought I'd point it out for anyone searching for a way to get GeoServer to use GeoTIFFs which are outside the data directory. http://jira.codehaus.org/browse/GEOS-3966 Enjoy. |
|||
11 May 09:27:51 ERROR [geotools.rendering] - side location conflict [ (462.7099002767874, 220.80214145084886, NaN) ] com.vividsolutions.jts.geom.TopologyException: side location conflict [ (462.7099002767874, 220.80214145084886, NaN) ] This error occurs sometimes when you use a point-style SLD for a polygon layer. When adding new layers via the GeoServer web interface, the 'point' style is the default, so if you're just wanting a quick preview of your data you might forget to select an appropriate style and then encounter this error. I'm not sure why some polygon layers can actually be rendered as points, while others raise this exception. In any case, I didn't find much information when searching for this specific error message, so I thought others might find this helpful. |
|||
http://arrsync.sourceforge.net/ Brilliant! |
|||
We upgraded Sara's iMac to OSX 10.6. Mostly this is fine, but a few things are broken. Local DNS was one main problem. We have all our local machines in the '.dean' domain, and while I was able to correctly look up these names using dig, I wasn't able to actually use them in Firefox, ssh, or any other program. The problem seems to be that 10.6 does not respect a DNS response with a TTL (time to live) of 0, which is the default value used by DNSMasq, the DNS/DHCP server which we use as part of DD-WRT. The problem is described in this thread, in a posting by 'hphoto' dated '09-22-2009, 04:25 PM'. The advice seems to be right-on. Raising the TTL to some non-0 value for local DNS seems to solve the problem. I chose 5 seconds for mine. alex@schlitz:~$ dig grawp.dean ; <<>> DiG 9.4.3-P3 <<>> grawp.dean ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26685 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;grawp.dean. IN A ;; ANSWER SECTION: grawp.dean. 0 IN A 192.168.0.1 ;; Query time: 13 msec ;; SERVER: 192.168.0.100#53(192.168.1.2) ;; WHEN: Fri Apr 2 21:46:05 2010 ;; MSG SIZE rcvd: 44 Notice the '0' in the ANSWER SECTION. That's the TTL. Now go to the DD-WRT admin page for DNS options: And add a 'local-ttl' value. Then save your options. These pages were useful for reference. Notice that the options in the man page seem to be usable by just dropping the '--' from the long version of the option. So '--local-ttl=5' in the command-line version becomes just 'local-ttl=5' in the DD-WRT web interface. Now, you can re-try that dig query to see the changed value. alex@schlitz:~$ dig grawp.dean ; <<>> DiG 9.4.3-P3 <<>> grawp.dean ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26685 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;grawp.dean. IN A ;; ANSWER SECTION: grawp.dean. 5 IN A 192.168.0.1 ;; Query time: 13 msec ;; SERVER: 192.168.0.100#53(192.168.1.2) ;; WHEN: Fri Apr 2 21:46:05 2010 ;; MSG SIZE rcvd: 44 Hope that helps! |
|||
Postgres has a single character encoding per database. It can also silently translate from different client encodings to the one configured for the server. So Postgres is pretty flexible and can handle most text you throw at it. But, if you ever need or want to know, it's simple to discover what encoding is being used by the server. $ psql Welcome to psql 8.3.1, the PostgreSQL interactive terminal. Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit testdb=# show server_encoding; server_encoding ----------------- UTF8 (1 row) Seeing what encoding is in use by your client is just as easy. testdb=# show client_encoding; client_encoding ----------------- UTF8 (1 row) |
|||
In this example, I have a Red Hat 5 VM running in VMWare Fusion on a MacBook Pro. The '/' partition is on a single LVM logical volume. I want to increase its size from 20GB to 25GB. If you're not using LVM, try these instructions instead : http://www.howtoforge.com/linux_resizing_ext3_partitions_p2 Here's the problem: [root@rhel5-oracle ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/VolGroup00-LogVol00 19G 18G 6.2M 100% / /dev/sda1 99M 18M 77M 19% /boot tmpfs 506M 0 506M 0% /dev/shm First step is to shut down the VM and give it more disk space via the VMWare 'Settings' panel. In this example, I just added space to the existing single virtual disk, but you could just as well create a separate virtual disk. The instructions below work just as well if you've got a non-virtual OS which you want to add more real physical storage to. Then boot the VM again, and do the following in the guest OS. fdisk /dev/sda Create a new partition for the newly available space. ## Check what you're starting with. Command (m for help): p Disk /dev/sda: 26.8 GB, 26843545600 bytes 255 heads, 63 sectors/track, 3263 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 * 1 13 104391 83 Linux /dev/sda2 14 2610 20860402+ 8e Linux LVM ## Create the new partition Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 3 First cylinder (2611-3263, default 2611): Using default value 2611 Last cylinder or +size or +sizeM or +sizeK (2611-3263, default 3263): Using default value 3263 ## Make it LVM Command (m for help): t Partition number (1-4): 3 Hex code (type L to list codes): 8e Changed system type of partition 3 to 8e (Linux LVM) ## Double-check Command (m for help): p Disk /dev/sda: 26.8 GB, 26843545600 bytes 255 heads, 63 sectors/track, 3263 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 * 1 13 104391 83 Linux /dev/sda2 14 2610 20860402+ 8e Linux LVM /dev/sda3 2611 3263 5245222+ 8e Linux LVM ## Commit your changes Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. WARNING: Re-reading the partition table failed with error 16: Device or resource busy. The kernel still uses the old table. The new table will be used at the next reboot. Syncing disks. Now reboot the VM and proceed. Online resizing of ext3 is supported in 2.6 kernels, so you don't even need to use Knoppix or some other CD-based distro. [root@rhel5-oracle ~]# pvcreate /dev/sda3 Physical volume "/dev/sda3" successfully created [root@rhel5-oracle ~]# vgextend VolGroup00 /dev/sda3 Volume group "VolGroup00" successfully extended [root@rhel5-oracle ~]# lvextend -L+5G /dev/VolGroup00/LogVol00 Extending logical volume LogVol00 to 23.88 GB Logical volume LogVol00 successfully resized [root@rhel5-oracle ~]# resize2fs /dev/mapper/VolGroup00-LogVol00 And here's the final outcome... [root@rhel5-oracle ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/VolGroup00-LogVol00 24G 18G 4.6G 80% / /dev/sda1 99M 18M 77M 19% /boot tmpfs 506M 0 506M 0% /dev/shm |
|||
Note to self... [root@rhel5-oracle ~]$ lsof -i tcp:1521 -nP COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME tnslsnr 5640 oracle 10u IPv4 11104 TCP *:1521 (LISTEN) tnslsnr 5640 oracle 12u IPv4 11424 TCP 127.0.0.1:1521->127.0.0.1:10948 (ESTABLISHED) oracle 5742 oracle 16u IPv4 11423 TCP 127.0.0.1:10948->127.0.0.1:1521 (ESTABLISHED) |
|||
UPDATE : April 21, 2010http://www.jonmaddox.com/2008/03/13/show-your-git-branch-name-in-your-pr... Rails uses the environment variable $RAILS_ENV to control which set of configuration files should be loaded. This includes, among many other things, what database to connect to. I tend to have lots of terminal windows open, doing several things at once. There are lots of circumstances where it's useful to switch to a different Rails environment for some tasks. The danger here, though, is that plenty of things you might do in a personal local development environment aren't at all safe to do in a production environment. (Dropping and re-loading test data into the production database is a particular no-no.)
I used to frequently The solution I cooked up is to add some information about my export RAILS_ENV=development export PS1='`if [ "$RAILS_ENV" == "development" ]; then echo -n "\[\033[01;32m\]"; else echo -n "\[\033[01;31m\]"; fi;`$RAILS_ENV:\[\033[01;34m\]\w\[\033[00m\]\$ ' Here's what it looks like in action: I do most of my work in OSX 10.5, which uses GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0). I suspect this could be tweaked to work in more versions of bash.
|
|||
I wrote a Ruby port of a PHP class I found which will 'translate' English strings to Swedish Chef. I posted the Cheferizer code to GitHub a few days ago, so go crazy. Many thanks to Erik Bakker, the author of the include 'cheferize' class String include Cheferize end >> "This is a test!".to_chef => "Tees is e test, bork bork bork!" Here's a slightly longer example of the time you can waste paying tribute to a personal hero... First the original English.
And now, enter the Chef.
|
|||
Here's a simple method you can use in a console to determine the contents of an existing Rails session. All you need is the session id. def read_session( sess_id ) result = ActiveRecord::Base.connection.select_all( "SELECT * FROM sessions WHERE session_id = '#{sess_id}'" ) Marshal.restore( Base64.decode64( result[ 0 ][ 'data' ] ) ) if result[ 0 ] end The return value will be a Note this doesn't do any input-escaping, so it's open to SQL injection. Don't expose this code to users. (That's a good idea for lots of reasons, given what it does.) Suppose you want to just watch a particular session in your console... def report_session( sess_id ) i = 0 while true puts "#{i} : #{read_session( sess_id ).inspect}" i += 1 sleep 1 end end $ script/console Loading development environment (Rails 2.2.2) >> report_session 'a3fbc5de20723a242b54a73cad4221bb' 0 : {"flash"=>{}} 1 : {"flash"=>{}} 2 : {"flash"=>{}} 3 : {"flash"=>{}} ... It'll keep updating with session data until you kill it with Control-c. |
|||
This is a simple method I've been using to automatically include controller-specific stylesheets. If you have app/controllers/users_controller.rb, then public/stylesheets/users.css will be included automatically if it exists. I'm sure this has been done before, but here's my take on it. # app/helpers/application_helper.rb module ApplicationHelper def controller_stylesheet controller_name = controller.controller_name if File.exists?( "#{Rails.root}/public/stylesheets/#{controller_name}.css" ) stylesheet_link_tag( controller_name ) end end end <!-- app/layouts/application.html.erb --> <html> <head> <%= controller_stylesheet %> </head> <body> <%= yield %> </body> </html> |
|||
Back in my original 'calendarserver on Linux' posting, I wrote about how to set up Apple's Darwin Calendar Server (DCS) on Ubuntu Linux. At the time, I neglected to mention that was Ubuntu 8.10. This turns out to be important, because I have since built a new server using Ubuntu 9.10 and discovered some important differences in the new Ubuntu. |
|||
My wife is better at finding things than I am. I am better at not losing things than she is. It's an important difference. Being good at 'finding things' means she's more careful when she goes place to place looking for something. She notices details I don't. She thinks of places to look which don't occur to me. Being good at 'not losing' things means I tend to put stuff back in the same place every time. Sara is constantly losing her keys, purse, or cell phone because she tends to drop them wherever, then go looking for them later. I tend to put stuff back in one place. (Notice I say *tend to*. I'm definitely not claiming any perfection here. I need her help plenty of times finding stuff I've stupidly dropped in some random place...) I developed the habit because, as mentioned above, I'm not very good at looking for things. This is my way of working around my own lack of search skill. Whenever I have something in my hands which I no longer want to be holding, I tend to ask the question "where is the first place I'd look for this thing?" Whichever place first comes to mind is the place where I put the thing. Not perfect, but a lot better that before, when I combined the 'drop stuff anywhere' storage strategy and the 'carelessly and unproductively scan for things' search algorithm. Why does this matter in the context of a blog about coding? I think the same rules about 'where to put things' apply really well to software or database design. 'How do I want to search for this?' should play a large part in 'how should I store this data?'. Of course there are plenty of other concerns. For example, tailoring a database schema too closely to a single kind of search often reduces the ease with which you can perform other kinds of searches of that data. But 'how will I search for this stuff' should be *part* of the design process. And, if you can't answer that question at all, I think it's worth asking 'do I really need to store this data at all?' |
|||
Got weird error trying to access www.google.com. Co-worker helped me figure out this was Verizon's 'DNS Assistance' messing up. Tried their 'opt out' option. Visiting a non-existent domain brings up an incredibly lame error page. The page you see below is HTML copy/pasted from the standard Internet Explorer page (including image references to 'C:\...'), with some Verizon links slapped on the end of it. Wow. What the heck? I switched to 4.2.2.1 and 4.2.2.2, but there are plenty of other public DNS providers. This is kinda funny since 4.2.2.1 is also a Verizon server, but it doesn't have this annoying 'helpful' feature. http://www.tech-faq.com/public-dns-servers.shtml |
|||
Just read a story about the Obama administration using the Drupal CMS for whitehouse.gov. Maybe we can say they're learning from us here at Deanspot? http://techpresident.com/blog-entry/whitehousegov-goes-drupal |
|||
