Forum Archive

Working Copy integration sidebar

smath

I recently stumbled on an app called Working Copy, which is a github client (though it also works with other services). It's a very well put together app, and to make things better, the beta currently out for testing with testflight supports x-callback-url. Since I know little to nothing about writing my own git client with authentication and all that, this makes things a ton easier, for the most part (more about that in a minute). In order to push to a remote repository you do have to upgrade the app ($1 for three weeks or $10 for forever). Note that charges do not apply to beta testers.

I've made a repo with a sidebar client I made which can add files on working copy, update them, commit single files or whole repositories, push, and pull to working copy. I hope to roll this into my personal copy of edit-menu, so I can switch back and forth between edit-menu, editing tabs, and git functions. I also hope to combine steps so I can add, commit, and push in a single step if desired for example.

Now for my problem. When trying to copy text stored in working copy file and update the corresponding file, I open an x-callback-url which should read the contents of the file stored in local copy, and send the right file location and text back as arguments to a second script (Update.py), which can then update the script contents. For some reason I am not getting sent back to pythonista with this code.

I also need to say that the developer of Working Copy has been very helpful. In the latest beta he updated the x-callback-url functionality at my request so that it would even be possible to get file contents back into pythonista. I have successfully gotten it to work when using a premade test URL. It just fails when this code puts it together for some reason. I can't tell what part of the URL is broken.

JonB

Do you have a simple example of a uri you are using? Are you being sure to encodeURI the text file contents?

JonB

Sorry, I think it might be urllib.quote

smath

I figured it out, but I don't have time to finish the code right now. I'll post it when it's done.

JonB

By the by, Smath, you may want to pull the latest editmenu if you haven't in a while. I recently updated everything as classes, which fixed some namespace conflicts and other issues when changing folders....

smath

Okay. I just updated the repository, and while I still hope to make improvements, everything is working. Please read the updated instructions on the README before trying to use, or it won't work. Let me know if you still have any questions. Also feel free to improve or suggest how it could be better.

I understand this probably won't be the best thing for everyone, especially people who are used to using git via the command line. It's also not a great idea for large repositories, and in fact breaks down when there are sub-directories in the repository (something I need to fix). Hopefully once I get around to combining steps it will be better for that purpose. I just like the idea of having a git interface built into my pythonista workflow, and since I usually work in small repositories this should work just fine.

JonB - thanks for the suggestion. I'll make sure to get the most current version.

JonB

FYI, there is also gitview, which is a ui interface to git.
https://omz-forums.appspot.com/pythonista/post/5810965861892096
It still has a lot of work to go

I do like the idea of sidebar commands. I suspect working copy has the capability to handle merges, etc better.

smath

I've noticed a problem with how I'm doing this. When I get text returned from working copy, what I get is a list of words. which I join with spaces. This totally kills my indentation. Any ideas how to fix this without looping through the whole list of words or string? If not I'lll probably give up on this and find some other way to simplify working with git. I may still use this to send stuff to git, but pullling code from git through working copy is turning out to be more complicated than I originally thought.

JonB

In the pythonista manual, it says

If you want to pass arguments that contain spaces, you have to enclose them in double quotes (as you would in a classic shell). %22 is an encoded double quote:

For instance

pythonista://printargs?action=run&args=%22foo%20bar%22

produces

['/var/mobile/Applications/88D6E0F3-4BB7-4D36-8AD6-BAF532976A46/Documents/printargs.py', 'foo bar']

Your scripts would have to ensure that there are no "s in you code. Use single quotes for strings, then you can replace any double quotes inside of strings with \x22.

If you ever need to quote single quotes, you could use triple single quoted strings instead of double quotes.

If you are only using ios, and don't need to share elsewhere, your pythonista code could add double quotes to the file that you check in, which thus ensures that when you get it back from working copy, the quotes get stripped off automatically. Alternatively, you will need the workingcopy author to add the option to surround the encoded code with %22s.

The other options you've got, I think, are:
You could use git from stash, which has been functionalized compared to the pythonista versions. So you could call those from a sidebar.
You could also use gitview, which right now has some additional features, like the ability to checkout old sha's. Once you create the gitui object, you can set the repo programatically, then all the commands should be callable from the gitui object. I have a lot of cleanup and organization to do in that class, but I don't see any real barrier to sidebar integration. Do you have a use css for what git commands you want implemented via sidebars?

JonB

Correction: you want to use argv rather than args. Argv does not require quoting.

smath

Okay, I got this working, however, I have been rethinking how good of a path this is. I didn't realize that git had been included in stash. That might be a good route. Is there any reason that it wouldn't work with bitbucket? I know that I can use the same command line commands with bitbucket as github on desktop, but I'm having trouble cloning a bitbucket url with it.

JonB

Be sure to include the full extension. Do you have an example url you are cloning?

ok, I reproduced this problem. I suspect it has to do with the authentication method used. Technically I don't see a reason dulwich wouldn't support bitbucket..

ccc

The new release of Working Copy adds x-callback-url commands.

smath

Just so you know, PMB1999 on github submitted an update for that app on 2/28 that should improve functionality substantially from what I had, so make sure you have the current version. I had arranged with the working copy developer to allow sending encoded zip files back to pythonista to allow whole folders to be synced at once, and I believe PMB1999 implemented that along with other improvements. I haven't been able to use it much yet, so I'm not sure of all the changes.

The other option for dealing with the close button is that I could just have all of the buttons moved down. Then no work around will be needed. I'm not sure if that will impact any iPhone users.

Helgi

By the way, check out my pull request on Github. I think I improved the script a little by removing the need for the user to configure INSTALL_PATH.

ccc

v1.8 of Working Copy was released yesterday and it seems to have great new features. I use it to fiddle with GitHub repos but I do not really know how use it to do heavy work between Pythonista and Working Copy and a GitHub repo.

Could someone please document some best practices for how to use Pythonista and Working Copy together?

A walk-through of the following steps would be a huge help to me:

  1. Use Working Copy fork an existing repo from GitHub
  2. Move one (or all) of the Python files from that local copy into Pythonista
  3. Make a change in one of those Python files
  4. Move the modified file from Pythonista back into Working Copy
  5. Push the change into the GitHub repo
    5a. A repo to which I have commit rights
    5b. As a "pull request" to a repo to which I do NOT have commit rights

Steps 2, 4, and 5b are the ones that I have difficulty with and I am sure that my current approach is suboptimal ;-).

Utsira

I'm a big fan of Working Copy (but only just getting started with Pythonista), having a full-featured Git client on iOS is wonderful I think, so I was delighted to discover this script.

@ccc I'm still relatively new to Pythonista, but I've used Working Copy quite a bit for other projects, so I can answer some of these.

  1. Cloning from GitHub is very easy. The main URL of the GitHub repository you want to clone can act as an alias for the Git clone URL. Copy the URL from the safari address bar (the "copy" command in the action menu will do this), open Working Copy, navigate to the root if you aren't already there, hit "+" clone, it should detect that you have a GitHub URL in the clipboard, and a blue notification appears asking if you want to clone from that URL, tap the notification, then tap clone.

for 2-5, I would use the buttons in this script. You can save the script to the Pythonista action menu, so that it is always easily within reach.

Utsira

@smath I just submitted a pull request to your repo, just a couple of small changes. When I push/upload, the operation works, but when it switches back to Pythonista, a notification pops up saying that I have no such file in my library.

andymitchhank

I have forked the wc_sync repo and made some updates to it to work with the Pythonista 2.0 beta. The sidebar view has not worked in the beta for a while now and some other changes have been made that made the original code unusable.

PS @Utsira - Working copy sends back the name of the updated file in the x-callback-url, so in turn Pythonista tries to open said file, which it thinks is in the root directory, since WC does not send back the repo name. I have accounted for this in my updates below.

https://github.com/ahenry91/wc_sync

shaun-h

@ahenry91 slight issue with the UI it doesn't appear to be responsive on my iPhone it is cut off slightly still usable though.
If you are happy to accept a pull request I might try and fix it tonight if someone doesn't beat me to it.

andymitchhank

@shaun-h sorry, I beat you to the iPhone interface. If you would like to create a better interface, I'd be happy to accept the pull request.

ccc

Were the ideas in these two pull requests incorporated into the current code? https://github.com/pysmath/wc_sync/pulls

andymitchhank

@ccc it looks like the open in current repository pull request is incorporated in my fork, but not the other one (INSTALL PATH). I haven't made a pull request for my fork back to the original repo.

andymitchhank

So, I have made some changes to the Working Copy Integration project.

Changes:
* Rewrote the main script to use a class structure allowing easier extension of the project.
* Moved the URL Scheme code (rxZip.py and rxFile.py) into the class.
* Retrieve a list of available repos from Working Copy when copying a repo into Pythonista. You don't have to type the name of the repo anymore.
* Moved from the UI module to the Dialogs module for the interface. This makes it easier to be sure that the UI works across all devices.
* Integrated one of the Pull Requests for the original repo to determine the Install Path automatically.

I think that is all the changes for now. I am looking into a way to push all changed files in the repo to Working Copy, but haven't quite figured out how to approach it. If anyone wants to tackle it, be my guest.

Note: Sometimes Working Copy hangs for a few seconds when retrieving the list of available repos. Give it a few seconds and it will return to Pythonista.

ccc

hangs for a few seconds...

A console.hud_alert() can help the user experience a lot in these situations.

mrcoxall

When I try running Working_Copy_Sync.py, l am getting an error on line:

import dialogs

Are "dialogs" a beta 1.6 things only?

andymitchhank

@mrcoxall I think you're right that dialogs is a beta feature. Hadn't realized that when I did the rewrite. The release version is under review (again) for the App Store and will hopefully be out soon.

JonB

http://appreviewtimes.com/ current review time: 14 days!

mrcoxall

I have upgraded to Pythonista 2.0 to give the Working_Copy_Sync.py a try. I have pasted in the code into a script called Working_Copy_Sync.py, but I am getting acerror on line:

repo, path = fullPath.split('/', 1)
andymitchhank

@mrcoxall try moving the script to a sub directory such as wc_sync.

ccc

Or put print(fullPath) on the line before the problematic line and tell us what gets printed to the console. It is also very helpful to know exactly what the error message is.

andymitchhank

@ccc the error is caused by the script being in the root (home) directory. So the full path doesn't have a \, just the script name. When you split it (line 47), you only get one return value and the script tries to unpack it into repo, path.

The script uses the project directory as the repo name. I'm looking into a possible solution for this.

mrcoxall

Moving it to a subdirectory called wc_sync worked.
Thanks.

I get the dialog showing up.
The problem is when I try doing a "Push", I get an error in Working Copy. The error says:

No repository found where name or remote-URLs matches repo=wc_sync.

andymitchhank

@mrcoxall Sorry for the (really) delayed response here. You need to create a repo in Working Copy called wc_sync so that it will have somewhere to push the changes. For other repos, you need to add the Working_Copy_Sync.py script to the quick actions in Pythonista.

andymitchhank

I have updated the Working Copy Sync script again with a couple of changes.

Before updating to the latest version, push all of your changes from Pythonista to Working Copy. After updating, you will need to clone each of your repositories again, overwriting any changes not pushed to Working Copy.

  1. Repo information is now stored in a .wcsync file in the repo root directory and doesn't use the currently directory to determine the repo-name. This means that you can rename a folder or move it to a different location (out of the documents dir) and you can still use Working Copy with the repo.
    (You can also move the Working_Copy_Sync.py script to the root directory if you like, but I recommend leaving it in its own directory in order to pull changes from the repo in Working Copy.)
  2. If you run the script (from the action menu) in a folder without a .wcsync file, it will only show the option to clone a new repo from Working Copy. In folders containing a .wcsync file, it will provide the regular fetch, push, etc. options.

Note: The script searches for the .wcsync file recursively (up the folder tree). So you can still have folders within your repo and it should all work. Also, there is an issue with spaces in folder/file names when using URL schemes between Working Copy and Pythonista, so I would avoid spaces.

Link for completeness: https://github.com/ahenry91/wc_sync

mrcoxall

Is there a way to create a new directory in Pythonista add some *.py files and then move the entire directory over to Working Copy as a repo?

At the moment it seems like you need to create a repo in Working Copy, add a "place holder" file, move to Pythonista and clone the repo in and then add your *.py files.

Looking for a way to start in Pythonista and the move to Working Copy.

Thanks

Webmaster4o

@mrcoxall stash has very good git support. I'd use that to push to remote, then open in working copy from there. There's no real reason to use working copy, though, if you're comfortable with command-line git.

andymitchhank

@Webmaster4o I haven't looked at the git support in stash recently. Are you able to use ssh keypairs for authentication? That's the primary reason I moved to Working Copy initially.

Webmaster4o

@ahenry91 I believe so. Search the forum.

mrcoxall

So, yes, I have StaSh and I am using it.

I want to use Working Copy, because I would like to use it with my grade 10 programming class.
They are almost all brand new to programming and just the concept of using GitHub is confusing enough for them, adding in the complexity of command line usually sends them over the deep end.
I like the GUI of Working Copy.

My ultimate workflow would be for them to create a directory in Pythonista, then the .py and .pyui files inside the directory. Then send the directory as a repo to Working Copy and then off to GitHub.

Thanks, Patrick

JonB

I don't believe stash git currently supports ssh keypairs, though the underlying dulwich does. (actually I have not tried it, I can check if dulwich shells out to unix ssh, which might prevent this from working). it does use https though, and your user/pass is saved in the ios keychain.

JonB

I was able to successfully get stash git to authenticate with github using ssh. The steps are a little convoluted at first.

1) add line 136 to stash/bin/git.py i will, get a pull request soon to avoid this step

dulwich.client.get_ssh_vendor = dulwich.client.ParamikoSSHVendor

2) in stash: type following commands

mkdir ~/.ssh
ssh-keygen -t rsa -b 2048
cp $STASH_ROOT/.ssh/* ~/.ssh
pbcopy ~/.ssh/id_rsa.pub

This creates the .ssh folder (where paramiko looks by default, as opposed to the stash ssh command which looks in stash/.ssh. I thing ~/ used to be read only, but now we can write there, so this might be another pull request to let stash use default folder), and creates keys, and copies the public key to the clipboard. If you have ssh keys already, just copy them to the ~/.ssh and copy to clipboard.

3) open up github in safari. go to user settings/ssh keys, click new key, and paste the result into the text box. give the key a name.

4) back in the pythonista console, we will save the github host key.

import os
ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('github.com',username='yourgithubusernamehere')
ssh.get_host_keys().save(os.path.expanduser('~/.ssh/known_hosts')

5) you should be now be all set to connect to github via ssh in stash. I will say this seems slower than connecting via https, maybe due to the big keys. use ssh://git@github.com/USERNAME/REPONAME.git format for urls.

As an example (use your own reponame obviously!)

git clone ssh://git@github.com/jsbain/uicomponents.git uicomponents
cd uicomponents
git commit 'test of ssh' jsbain jsbain
git push     #just leave blanks for user and pass... need to fix this
mfkilgore

I was just pointed to this thread (thanks @ccc). I would like to add my vote for integration with Working Copy. The latest release even does submodules. Of course it would not be required (stash etc still available) but for those of us with the app, it is a great option.

JonB

does working copy support branches/ merging? or it is more geared towards single thread development on master?

mfkilgore

@JonB Take a look, branches and merging supported - http://workingcopyapp.com/manual.html. I have not used every feature yet but works well with what I have tried.

mfkilgore

Just curious, any further work towards this integration either underway or planned?

ccc

@mfkilgore I agree... Working Copy has improved a TON in recent releases. I find It really usable these days but I still have no idea how to do a workflow that goes from GitHub to WorkingCopy to Pythonista to WorkingCopy to GitHub. Stash is awesome but working on a command line on my iPad is not my cup of tea. I do a lot of work at the UNIX command line on my Mac so I have no fear of the command line -- I just does not feel like the right way to go on an iOS device.

ccc

Got it... https://forum.omz-software.com/topic/2382/git-or-gist-workflow-for-pythonista/24