hglib-python commit test case - mercurial

I am writing hglib-erlang for converting hglib-python to erlang language module. In the file of "test-push.py", there is one test case as follows.
I think the second commit('second') will have nothing to commit and give error message. There is only one log item ('first'). Is it right?
class test_push(common.basetest):
def test_basic(self):
self.append('a', 'a')
self.client.commit('first', addremove=True)
self.client.clone(dest='other')
other = hglib.open('other')
# broken in hg, doesn't return 1 if nothing to push
#self.assertFalse(self.client.push('other'))
self.append('a', 'a')
self.client.commit('second')
self.assertTrue(self.client.push('other'))
self.assertEquals(self.client.log(), other.log())

From a cursory reading of this test code, it would seem like self.append('a', 'a') makes changes to the virtual copy, so that self.client.commit('second') will just work as normal.

Related

HG command line input receives unwanted default input automatically in THG

I've written an Hg hook (in Python) to check the validity of the committed files according to out team rules. One of these rules prohibits files larger than XX kB, unless agreed with the ream. In case a large file is committed, I would like the hook to ask the user to allow the file.
I implemented it like this:
import re, os, sys, mercurial
MAX_SIZE_KB = 500
def check_committed_files(ui, repo, **kwargs):
changelog = repo.changelog._cache
lines = changelog[2].splitlines()
ui.status("Checking files...\n")
for line in lines[3:-2]:
fn = line
ui.status(" " + fn)
# check file size
file_size_kb = float(os.stat(line).st_size) / 1024
if file_size_kb > MAX_SIZE_KB:
if ui.prompt(" Allow file [%s] of %g kB?" % (fn, file_size_kb)).lower() not in ['y', 'yes']:
ui.warn(" Not allowed by user\n")
return 1
ui.flush()
return 0
It all works well if I use Hg CLI. But when I use TortoiseHg, the prompt is automatically yes-ed, so I get this in console:
Allow file [test.txt] of 2573.49 kB? y
and the hook goes on. I would like TortoiseHg to show a dialogue with Yes/No buttons. Is it possible? I'd like to have the solution as portable as possible, so e.g. no external Python modules that users need to install.
Since this is my first attempt with Hg hooks, any other comments on my implementation are also much appreciated.

printing the output of shell command from python subprocess

I am running a shell script which emits lots of line while executing...they are just status output rather than the actual output....
I want them to be displayed on a JTextArea. I am working on jython. The piece of my code looks like:
self.console=JTextArea(20,80)
cmd = "/Users/name/galaxy-dist/run.sh"
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
self.console.append(p.stdout.read())
This will wait until the command finishes and prints the output. But I want to show the realtime out put to mimic the console. Anybody have the idea ?
You're making things more complicated than they need to be. The Popen docs state the following about the stream arguments:
With the default settings of None, no redirection will occur; the child’s file handles will be inherited from the parent. [my emphasis]
Therefore, if you want the subprocess' output to go to your stdout, simply leave those arguments blank:
subprocess.Popen(cmd, shell=True)
In fact, you aren't using any of the more advanced features of the Popen constructor, and this particular example doesn't need any parsing by the shell, so you can simplify it further with the subprocess.call() function:
subprocess.call(cmd)
If you still want the return code, simply set a variable equal to this call:
return_code = subprocess.call(cmd)

My function cannot create text file

I am a beginner in Python and i am reading Wrox's "Beginning Python Using Python 2.6 and Python 3.1"... There is one certain example in chapter 8 about using files and directories that has troubled me a lot... The following function is supposed to create (if it doesn't exist) and write in a text file:
def write_to_file():
f=open("C:/Python33/test.txt","w")
f.write("TEST TEST TEST TEST")
f.close()
When i run the function nothing happens, no text file is created and no error message is returned...
When i run the code in IDLE, command by command, it works perfectly...
What is wrong with the function???
Python's picky about indentation, from what I remember of it:
def write_to_file():
f = open("C:/Python33/test.txt", "w")
f.write("TEST TEST TEST TEST")
f.close()
# On top of that, you need to actually run the function.
write_to_file()
I think this is because of indentation, do it like this:
def write_to_file():
f=open("C:/Python33/test.txt","w")
f.write("TEST TEST TEST TEST")
f.close()

Perl - getlogin, getpwuid, and $<

Wanted to understand the example line of code given # perldoc.perl.org for getlogin
$login = getlogin || getpwuid($<) || "Kilroy";
It seems like it tries to get the user name from getlogin or getpwuid, but if either fails, use Kilroy instead. I might be wrong, so please correct me. Also, I've been using getlogin() in previous scripts - is there any difference between getlogin() and getlogin?
What is this code safeguarding against? Also, what purpose does $< serve? I'm not exactly sure what to search for when looking up what $< is and what it does.
EDIT
found this in the special variables section - still don't know why it is needed or what is does in the example above
$<
The real uid of this process.
(Mnemonic: it's the uid you came from,
if you're running setuid.) You can
change both the real uid and the
effective uid at the same time by
using POSIX::setuid(). Since changes
to $< require a system call, check $!
after a change attempt to detect any
possible errors.
EDIT x2
Is this line comparable to the above example? (it is currently what I use to avoid any potential problems with "cron" executing a script - i've never run into this problem, but i am trying to avoid any theoretical problem)
my $username = getlogin(); if(!($username)){$username = 'jsmith';}
You're exactly right. If getlogin returns false it will test getpwuid($<) if that returns false it will set $login to "Kilroy"
$< is the real uid of the process. Even if you're running in a setuid environment it will return the original uid the process was started from.
Edit to match your edit :)
getpwuid returns the user's name by the UID (in scalar context, which would be the case here). You would want $< as an argumnent in case the program switched UID at some point ($< is the original one it was started with)
The only thing it's guarding against is the fact that on some systems, in some circumstances, getlogin can fail to return anything useful. In particular, getlogin only does anything useful when the process it's in has a "controlling terminal", which non-interactive processes may not. See, e.g., http://www.perlmonks.org/?node_id=663562.
I think the fallback of "Kilroy" is just for fun, though in principle getpwuid can fail to return anything useful too. (You can have a user ID that doesn't have an entry in the password database.)

Case-insensitive diffs in Mercurial

I'm using Mercurial (specifically TortoiseHg on Windows) to do version control of VBA code. Anybody who's tried this knows that VBA changes the case of every variable throughout a project whenever any declaration of that variable is changed anywhere in the project (regardless of scope). It makes version control a nightmare.
I would like to ignore case changes in my source code when performing diffs. What is the easiest way to do this? (some option for diff that I'm missing, an external diff utility, something else?)
NOTE: I am not talking about dealing with 'case-insensitive filenames' (yes, I'm talking to you Google...)
You can do that when diffing for your on-screen consumption using the ExtDiff Extension.
[extensions]
hgext.extdiff =
[extdiff]
# add new command that runs GNU diff(1) in case-insensitive mode
cmd.mydiff = diff
opts.mydiff = -i
Then you'd run hg mydiff from the command line. That, of course, requires you have a diff binary installed be it gnu's or other.
However, that's not going to be as helpful as you might like because internally, of course, Mercurial can't ignore case -- it's taking the cryptographic hash of the file contents, and those don't allow for wiggle room. So if you get this set up you'll do hg mydiff, and see no changes, and then do hg commit and see changes all over the place.
So you can make this work on-screen, but not fundamentally.
One option would be to find a visual basic code-cleaner, similar to indent for C-like languages, that normalizes variable case and run that in a mercurial commit hook. Then at least all the code going into source control will be consistent and you can diff across revisions accurately.
If you are okay with having your code in all lower-case, say, then you could employ the encode/decode hooks for this. It would work like this:
[encode]
*.vba = tr A-Z a-z
This will encode the file content in lower-case whenever you do a commit. The diffs are also computed based on the encoded (repository) version of the files.
Consider a file that contains
hello
Changing it in your working copy to
Hello World
will give a diff of
% hg diff
diff --git a/a.txt b/a.txt
--- a/a.txt
+++ b/a.txt
## -1,1 +1,1 ##
-hello
+hello world
Notice how the capital "H" and "W" has been ignored.
I don't really know anything about VBA code, so I'm not 100% sure this solution works for you. But I hope it can be a starting point.
One drawback is that you'll need to set this encode rule for all your repositories. The reposettings extension can help you here.
Here's the solution I have settled on. It is far from ideal, but better than the other alternatives I've considered.
I created an Autohotkey script that does the following:
reverts MS Access files in a repository with detected changes (to .orig files)
reads in the .orig file (the one with the changes)
reads in the existing file (the one already in the repository)
converts the text of both files to lower case
compares the lower case contents of the files
if the files still differ, the .orig file is restored so it may be committed to the repository
if the files are the same (i.e., they differ only in case, the .orig file is deleted because we don't care about those changes)
For files that have actual changes that we care about, I still see the case changes that were made as well. If that results in a lot of noise, I open the file in a comparison tool that allows case-insensitive compares (e.g., kdiff).
It's not a perfect solution, but it removes about 90% of the frustration for me.
Here's my script. Note that the script includes another Autohotkey script, ConsoleApp.ahk, which provides a function named, ConsoleApp_RunWait(). This is a 3rd party script that no longer works very well with 64-bit AHK, so I'm not including it as part of my answer. Any AHK function that executes a command line and returns the output as a string will suffice.
; This script checks an MS Access source directory and reverts all files whose only modifications are to the
; case of the characters within the file.
#Include %A_ScriptDir%\ConsoleApp.ahk
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; Allow for custom path to hg (support for moving to TortoiseHg 2.0)
IniRead hg, %A_ScriptDir%\LocalSettings\Settings.cfg, TortoiseHg, hg_path, hg
if 0 < 1 ; The left side of a non-expression if-statement is always the name of a variable.
{
MsgBox Usage:`n`HgIgnoreCase DirectoryWithFilesToScrub
ExitApp
}
SrcDir = %1%
StringReplace SrcDir, SrcDir, ", , All
StringRight test, SrcDir, 1 ; add trailing slash if necessary
ifnotequal test, \
SrcDir = %SrcDir%\
RestoreOriginals(SrcDir)
RevertCaseChangeModifiedFiles(SrcDir)
RevertCaseChangeModifiedFiles(SrcDir) {
global hg
includes = -I "*.form" -I "*.bas" -I "*.report" -I "*.table"
cmdline = %hg% revert --all %includes%
;Don't revert items that have been removed completely
Loop 3
{
Result := ConsoleApp_RunWait(hg . " status -nrd " . includes, SrcDir)
If (Result)
Break
}
Loop parse, Result, `n, `r
{
if (A_LoopField)
cmdline = %cmdline% -X "%A_LoopField%"
}
Result =
;msgbox %cmdline%
;revert all modified forms, reports, and code modules
Loop 3
{
Result := ConsoleApp_RunWait(cmdline, SrcDir)
If (Result)
Break
}
;MsgBox %Result%
Loop parse, Result, `n, `r
{
StringLeft FileStatus, A_LoopField, 9
If (FileStatus = "reverting")
{
StringMid FName, A_LoopField, 11
FullPath = %SrcDir%%FName%
ToolTip Checking %FullPath%
RestoreIfNotEqual(FullPath, FullPath . ".orig")
}
}
ToolTip
}
RestoreIfNotEqual(FName, FNameOrig) {
FileRead File1, %FName%
FileRead File2, %FNameOrig%
StringLower File1, File1
StringLower File2, File2
;MsgBox %FName%`n%FNameOrig%
If (File1 = File2)
FileDelete %FNameOrig%
Else
FileMove %FNameOrig%, %FName%, 1
}
RestoreOriginals(SrcDir) {
Loop %SrcDir%*.orig
{
;MsgBox %A_LoopFileLongPath%`n%NewName%
NewName := SubStr(A_LoopFileLongPath, 1, -5)
FileMove %A_LoopFileLongPath%, %NewName%, 1
}
while FileExist(SrcDir . "*.orig")
Sleep 10
}