Does anyone have a recommended Git or Gist workflow for Pythonista? I'm aware of the "send to gist" feature, but that doesn't support revisions.
Forum Archive
Git or Gist workflow for Pythonista
There are several interesting tools...
- https://github.com/Pythonista-Tools/Pythonista-Tools/blob/master/GitHub%20Tools.md
- https://forum.omz-software.com/topic/1848/working-copy-integration-sidebar
- http://workingcopyapp.com
...but I have never seen a blog post where someone documents the best practices for how to use any of these tools to do a full GitHub lifecycle.
A walk-through of the following steps would be a huge help to me:
- Use Working Copy clone an existing repo from GitHub
- Move one (or all) of the Python files from that local copy into Pythonista
- Make a change in one of those Python files
- Move the modified file from Pythonista back into Working Copy
- 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 ;-).
I have not used working copy, but my impression of the interface to pythonista was that it did not handle branching/merging/etc.
Currently the best option for bi-direction git is the git command in stash. This does (as of march) include an improved set of tools like reset, branch, fetch, and merge, which allow more flexibility, though this is probably not well documented. I probably need to write a more comprehensive tutotial.
I am in the process of a complete overhaul of gitview though it is not ready for prime time.
gistcheck was once a viable system for managing gists of single files. I updated it for ios8 a while back, but honestly I don't use it so not sure if it works in the beta. Also, I seem to recall bookmarklets were crippled in some version of ios, which broke one of the main features of this approach.
Wow, working copy looks great, I want to look at that more. Didn't know about that. Searching the app store for "github" a few years ago, I came up with some pretty crappy apps. I was thinking of writing an automatic github sync with pythonista, which would be ideal because of the functionality with going back to previous versions. That'd be a great backup.
It's a shame about apple's downloading code rule. It's not hard to copy/paste code from the same website you'd be downloading it from if you're willing to put in extra effort. I also don't know how they define 'code'. Workflows could certainly be considered executable code, and yet the gallery allows users to download code snippets. Maybe this isn't concerning to Apple because of the clear limitations of the app, but if they're going to ban the downloading of executable code, they should ban it, not make exceptions for some apps.
I also think it'd make more sense for the rule to be modified to permit apps that only upload/download code written to the user, maybe even to a private server for that app. It'd be great to permit code syncs, just not downloading random code.
It'd be a LOT better to let @omz write built in sync options.
@JonB I just tried gistcheck and it appears not to work, perhaps because of the beta.
@ccc, I can not believe your comments here. I keep th9nking someone has some magic sauce I don't have. It's so frustrating because I know often is not all said here to make sure something stupid does not happen with you know who.
Ccc you have asked me many times to share a project as a repo vrs a gist. Easy enough done, but it's the lifecycle where it all comes apart. I would love to close off my project now and share as a repo for collaboration, but how to update from Pythonista (I mean a button press, not copy and pasting all my files), then also downloading the latest branches or whatever you call them to Pythonista, then also to be able to go back to any branch in the project and restore that to Pythonista. To me this seems like it just should be all reasonable. But the rules or whatever seem to not publicly allow that.
Ccc, I am not having a go at you. I am just venting my frustration. Somehow we are missing out on one of the most important things about python, collaboration! Drives me crazy
@jonb , maybe stash is the way to go. I am sure I have tried with stash. Not saying it does not work, it I don't think it's for dummies like me.
Jonb is it possible to run UI with stash? Just a thought to help simplify the cmd line interface. Eg, can you make a stash object, and call the cmd line from the object. For a powerful cmd line editor like stash, to have it operate as an object or faceless app, whatever the right word is could offer a lot of possibilities to simply chained cmd line directives. Look maybe I don't know what I am talking about. But I just know I wish I could do it easy and in predictable and reliable way, with the knowledge I will not lose data. Eg, stash could have an option to enter a Dropbox account or directory or another other account that it makes a back up or your working copy of files before any merge, pull request etc... Is done before any of the git cmds are executed.
@Phuket2 The way I often put files in a github repo is to modify @omz 's pythonista-backup.py to host a single folder, and then download it on my Mac, and use github-desktop to upload it. This is a pain.
@Webmaster4o , yeah. But not only a pain, it's not controlled. Also if you are out and want to to a pull or push or take from a branch or whatever crazy thing you can do with Github, it's all about copy and pasting. Well as least as far as I know. But really copy and pasting into Github repo's must negate the whole concept of managed source code.
Again, I am not blaming anyone. I am just venting because I really find it frustrating. I would love a practical way here to collaborate with all the guys here on code, but one copy paste mistake, goes to hell. Also, maybe I want to update one line in a function, could be important. Then want to push it to the repo with a comment, should be a no brainer. Then if in 5mins later someone further refines my update, I should be just be able to update my local copy with a click.
Yeah, I go on and on. I would love to see this solved correctly. I know the people here have the skill to do it, but it's walking the fine line I guess
Another way is to make a Kickstarter project to buy Apple π
Right. I'm a little upset about the $10 IAP for working copy push functionality, I'd be happy to pay maybe up to 5, but 10 is excessive.
@Phuket2
i am not sure what a ui shell would look like :) Windows perhaps.
gitview was supposed to be the ui version of a git client. It works, if you are careful in your workflow. Because there is no merge, it is necessary before changing files locally, to pull, then change/commit locally, then push. Don't ever commit directly in github, such as updating readme, without then pulling back to your device. The ui is also probably fairly nonintuitive. I use this in combo with stash -- stash is used for anything complex, gitview is used for selecting which files to commit, and actually committing, and also the diff viewer is slightly more convienent.
I aim to improve the lack of fetch/merge with the next version of gitview, along with a vastly improved ui - a cleaner button bar menu, sliding subframes for branch or remote management, and integrated help).
@JonB , sorry I didn't explain the UI part correctly. But imagine you could create an object, mystash = stash.FacelessApp() from inside Pytonista. So you might have a mystash.exec() method, and the results being returned rather than going to std.io or console or whatever. That would enable others to write a UI using Pythonista around the cmd line interface of stash. I know I have given a very simplified English version here. In theory I have no idea how hard it would be to turn stash into a callable object , but it sounds interesting to me.
But look for me, I have have limited exp. with cmd line interfaces, especially in recent years. I am sure those who are comfortable with them are thinking what the hell is he going on about. But when you are not used to using cmd line , it sucks the life out of you. But that's just me.
But from what I see here, the least understood subjects are about backing up code, and gusts and repo's.
If I am not mistaken, people are scared to make something too powerful or comprehensive because of the possible ramifications.
Let's say it was not so political or sensitive, why would someone not just publish a simple guide to the life cycle as a keynote presentation for example.
Again, I am not blaming anyone. And maybe if I go back to stash I will understand it better now. But really, this would make my year, if I could easily work with a repo in a collaboration way with guys here.
just chiming in with my particular source control workflow if anybody's curious I think it might be pretty unique.
1.) Dropbox sync for all scripts within Pythonista. I have the sync script linked to a launch center action so I can quickly run it from my home screen before/after any editing has taken place anywhere. (have to be meticulous and careful here)
2.) Individual project in it's own subfolder within dropbox folder, symlinked to from an xCode project on my Mac.
3.) xCode's source control from within xCode
@Tizzy , thanks for the info. Had some Dropbox syncing working before. After going to 1.6, I didn't reinstate it. I also didn't do a good job of automating it. I think I could do a better job now. At least I hope so.
I haven't tried an Xcode project yet. Scares the crap out of me. Will have to try it sometime.
If I am working on something and want a snapshot because I am about to refactor the code (which I have to do all the time, because I am hopeless π±) I just use the 'share as gist'
I accept that there are ways to do,all this. But it's just not as simple as it should be. And as you point out, sometimes you have to be very diligent and careful.
I don't understand all the potential problems with storing scripts and or full projects in SQLite databases. It does not solve any problems relating to repo's etc. It could still be a interesting way to back up named/dated versions to a single file, so you only need to back up your sqlite db file. If I ever finish my resource manager, I will give it a go.
But again thanks for your comments, spurred some new thoughts for me
@JonB , oh sorry one more thing I neglected to be clear about. I didn't mean that the whole of stash to been turned into a GUI. Just saying if it was also a callable object that certain cmds could be wrapped up in a UI being powered by stash. I know it's a powerful tool. I would have thought even my powerful if could be called from inside a app.
Anyway, I hope I haven't been offensive, was not my meaning. I am just frustrated about not being able to do it easily and properly (repo's that is). I also accept, that my lack of skill is also a big contributor to that.
stash actually does include a callable object where other python scripts can run commands. So it is possible to write programs that include ui components, although there is sort of a console paradigm that tool authors have tried to honor.
In re-installing stash, I have found that it does not seem to properly install gittle anymore in the beta, I suspect because of the changes to the sys.path. So, that needs to be fixed before git is really viable in stash.
@JonB , ok. When it's resolved I will try again. This time I will give it my all. I really want to get it working in a way I understand it.
Thanksπ
Just read this thread. @Phuket2 stash object is callable since v0.3. So you can do something like from stash import stash; _stash = stash.StaSh(); _stash('Your_Command'). If a script is invoked from within stash, it can access the callable object without import, i.e. just do _stash('some_command').
@ywangd , thanks. I was just trying it inside a script. Is it possible for the _stash(cmd) to do its normal output to the Pythonista console also?
@Phuket2 Yes you can send output to the builtin console with _stash('some_command > &3'). The > character is a redirect operator in shell and &3 is the pointer to builtin console. Please note you need v0.6 for this to work. If you are on earlier version, please run selfupdate first and restart Pythonista.
@ywangd , thanks. I did the selfupdate. I was 0.53
But if I do the following is it valid? I get stopped....
Just trying to understand how I can use it
import os
import shutil
_git_dir = '.git'
_url = 'https://github.com/Phuket2/Pythonista'
_cmd_git_clone = 'git clone {} > &3'
_cmd_cd = 'cd {}'
from stash import stash
_stash = stash.StaSh()
_stash(_cmd_cd.format(os.curdir))
if os.path.exists(_git_dir):
print 'we have a git dir already'
shutil.rmtree(_git_dir)
cmd = _cmd_git_clone.format(_url)
print cmd
print _stash(cmd)
@Phuket2 The "Stopped ..." message is normal. The callable stash object returns a worker thread that runs the given command. The callable interface make sure it returns after the thread finish its job. So the "Stopped" message simply says the command is executed and now the thread has done its job and stopped.
A few things to note for your script:
* The GitHub repo address must have an ending .git, i.e. https://github.com/Phuket2/Pythonista.git.
* git clone ... command generates no output. So this may not be the best command to showcase > &3.
* Your script must run inside the same folder where the repo is to be cloned, i.e. where the .git folder resides. Because os.curdir is always a dot, (.) and cd . does nothing. If you wanna clone into a sub-directory to where your script locates. You can first _stash('mkdir sub_folder') to create the folder and then _stash('cd sub_folder').
@ywangd, thanks. It's very nice. I need to know more but will not bother you now.
But also, I don't feel so stupid now to ask if it's possible to do.
Yes the below is simple. But a nice ui powered by stash is super cool.
# coding: utf-8
import os
import shutil
import editor
'''
ONLY TESTING...DESTRUCTIVE
'''
this_path , fn = os.path.split(editor.get_path())
_git_dir = '.git'
_url = 'https://github.com/Phuket2/Pythonista.git'
_cmd_git_clone = 'git clone {} > &3'
_cmd_cd = 'cd {} > &3'
_clone_dir_name = 'git_clone'
_cmd_mkdir = 'mkdir {}'
from stash import stash
_stash = stash.StaSh()
_stash(_cmd_cd.format(this_path))
_stash(_cmd_mkdir.format(_clone_dir_name))
_stash(_cmd_cd.format(_clone_dir_name))
if os.path.exists(_git_dir):
print 'we have a git dir already'
shutil.rmtree(_git_dir)
cmd = _cmd_git_clone.format(_url)
print _stash(cmd)
@ccc Regarding your wish for a step-by-step documentation of a github lifecycle: I've started a tutorial for my tool gitsynchista which integrates with Working Copy. See here.
I finally created the script which delivers the workflow that I have been looking for...
A simple appex script that enables the use of the share sheet to transfer a repo, file, or directory from the Working Copy app into Pythonista.
https://github.com/cclauss/Pythonista-and-Working-Copy
The new Working Copy release also features iOS Handoff support to keep the code on all of your iOS devices in sync. StaSH and Gitista are super cool but they can (yet!) deliver Handoff like Working Copy can!
Issues and pull requests are most welcome!
@ccc , thanks a lot. Works flawlessly for me.
@ccc It looks nice. Just checking to see that I've understood this... It is a way to check out the files from a git repo into Pythonista. And Working Copy itself can keep the files in sync between iOS devices. But getting changes of the files out of Pythonista is not covered by this solution. Do you copy-paste the changes into Working Copy manually?
How do you use it yourself?
So far all that I have is read_from_working_copy.py which is one-way: Working Copy --> Pythonista
Yes, Working Copy could use Handoff to keep its repos on multiple iOS devices in sync with each other
~~I have not yet figured out how to deliver write_to_working_copy.py to go the other way: Pythonista --> Working Copy.~~ I am open to ideas and Pull Requests.
https://github.com/omz/Pythonista-Issues/issues/98 Would help to close this loop.
@Oscar I figured out the "save to Working Copy" piece too... It is actually builtin! At least on a single file basis (e.g. not a whole folder all at once).
- Open the file of interest in the Pythonista editor
- Click the wrench icon at the upper right
- Click the "Share..." button
- Click "Save in Working Copy" button
- Select the repo that you want to save the file into
- Click "Save As..."
- Change the filename if you want to and click "Save As..." again
- Click "Just Save" if you want to bundle multiple files into a single commit --or-- Type your commit message and click "Commit"
Now we have an end to end workflow: GitHub --> Working Copy --> Pythonista --> Working Copy --> GitHub
@ccc , do you think it would be possible to go one step closer.
Iterate though all the files in the directory asking the user for each file if they wants to send the file to working copy. Then have the share sheet present itself for each file you want to save, from there you take over and do all the work in the share sheet manually.
Then it would be possible to enhance the script to flag files to always ignore, keep a log of files that have been (supposedly) sent back to working copy with info on date and time etc, alert you that a file is new and be beet sent to working copy etc.
I have done next to zero with share sheets, that's why I ask.
I think this would be a fantastic addition, especially if you have a. Number of files in different directories. You can be sure you made a decision about each file.
Anyway....it's fantastic news, it's very exciting. I can start to see the light at the end of the tunnel about the possibility of collaborating with someone via a repo π±π±π±π±
A big thank you @ccc
Thx @Phuket2 I added Pythonista-Issues #121 and #98 to try to get us closer to the vision you set out above.
I think that security concerns prevent you from programmatically invoking Share without human intervention.
However, Working Copy does have a very rich x-callback-url vocabulary so I am sure that more complicate things are possible on that side of the divide.
@ccc , ok great. Not sure if you have seen this behavior or not.
I copied a repo into wc, then used your script to copy the repo to Pythonista. All good.
Then I added a new file with a commit. Github is not updated. Then I tried an overwrite. All looking good in wc, but Github still not showing the new file. Then same file again, I just did a save from Pythonista to wc, thinking that when I went to wc it would let me know that I was ahead of the repo. But it does not. But all the changes I do from Pythonista are reflected correctly in wc.
But ok, then I do a hard restart on wc, and it tells me I am 3 ahead of the repo. Then I can push. The Github repo is updated.
It's not a super big deal. I just tried to explain it here in case others get the same problem. So it's all working, but seems to be some refresh issues in wc.
@ywangd said:
A few things to note for your script:
* The GitHub repo address must have an ending.git, i.e.https://github.com/Phuket2/Pythonista.git.
Why is this? Git on desktop doesn't need need thisβ¦
@Webmaster4o said:
@ywangd said:
A few things to note for your script:
* The GitHub repo address must have an ending.git, i.e.https://github.com/Phuket2/Pythonista.git.Why is this? Git on desktop doesn't need need thisβ¦
Because no one has put in a pull request :)
The HTML and ssh protocol do require this, however git for desktop must detect and corrrect this common mistake.
@ccc, the appex script seems to be broken. I am pretty sure must be due to working copy update. A bunch of file errors. I didn't post them because it's happening on all the repositorys that worked before. I know I haven't changed anything and it doesn't appear the script has changed.
@ccc I've not been able to get the script working. This is the end of the traceback:
with open(src, 'rb') as fsrc:
IsADirectoryError: [Errno 21] Is a directory: '/var/mobile/Containers/Shared/AppGroup/379D48B7-C511-4AF4-80DD-2A91B9CD9D2A/File Provider Storage/Pythonista-and-Working-Copy'
I'm not an experienced Pythonista user though, so I might have installed the script incorrectly. I added it as a URL extension, is that correct? Do we need to put anything in the Arguments field in the Pythonista extension editor? Could someone describe the correct way to install the script?
https://github.com/cclauss/Pythonista-and-Working-Copy Is now working again with the latest version of the Working Copy app. Thanks @Phuket2 and @Utsira for the heads up that it was broken.
@ccc , really thanks. Just updated. Working again... But makes life a lot easier. ππππ
@ccc I've updated to the latest version of the script. This time I'm seeing a different error. I'm trying to send a .py file from Working Copy to Pythonista. Here's the traceback:
Traceback (most recent call last):
File "/private/var/mobile/Containers/Shared/AppGroup/FAB03D8A-5598-46CF-A26A-B76EE628E876/Pythonista3/Documents/read_from_working_copy_app.py", line 6, in
import appex, editor, os, shutil
File "/var/containers/Bundle/Application/AE76B4C7-AEC5-4858-9A87-3F2F77424054/Pythonista3.app/Frameworks/PythonistaKit3.framework/pylib/site-packages/editor.py", line 5, in
raise NotImplementedError('Not available in app extension')
NotImplementedError: Not available in app extension
Sorry @Utsira ... I rolled back the last commit. Please try again.
@MartinPacker as we discussed, you can download a repo directly from GitHub and unpack it into Pythonista in 10 lines of Python.
This version does not require Working Copy... https://github.com/cclauss/Ten-lines-or-less/blob/master/read_zipfile_from_github.py
@ccc I was wondering if there was a Pythonista 2 version of this script somewhere?
https://github.com/cclauss/Pythonista-and-Working-Copy
Hi,
It appears that the script is broken when I try to import a repository to pythonista (latest version).
It was working some 3/4 weeks ago. Don't know why it has stopped working. I noticed that working copy has been updated in February.
Here is the error:
Traceback (most recent call last):
File "/private/var/mobile/Containers/Shared/AppGroup/B6AB638B-3B3D-4649-85A1-8E5C6F750259/Pythonista3/Documents/read_from_working_copy_app.py", line 35, in <module>
main()
File "/private/var/mobile/Containers/Shared/AppGroup/B6AB638B-3B3D-4649-85A1-8E5C6F750259/Pythonista3/Documents/read_from_working_copy_app.py", line 25, in main
print(shutil.copy2(srce_path, dest_path))
File "/var/containers/Bundle/Application/7D651543-38E6-46C5-966F-4EEBA2F1A6CC/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/shutil.py", line 253, in copy2
copyfile(src, dst, follow_symlinks=follow_symlinks)
File "/var/containers/Bundle/Application/7D651543-38E6-46C5-966F-4EEBA2F1A6CC/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/shutil.py", line 100, in copyfile
raise SameFileError("{!r} and {!r} are the same file".format(src, dst))
shutil.SameFileError: '/private/var/mobile/Containers/Data/Application/D82E20BF-DAFE-4D17-AA00-9E6B99A79A39/tmp/Pythonista-and-Working-Copy.zip' and '/private/var/mobile/Containers/Data/Application/D82E20BF-DAFE-4D17-AA00-9E6B99A79A39/tmp/Pythonista-and-Working-Copy.zip' are the same file
It works fine with single files.
Can anyone help me please?
Thanks in advance,
David
The last line of the error message seems to indicate that you are trying to copy a file onto itself.
shutil.SameFileError: 'x' and 'x' are the same file
Very strange.
Have you tried to import a repository recently? Does this error happens to you?
I can replicate. A partial fix can be found at https://github.com/cclauss/Pythonista-and-Working-Copy/commit/e090d2fa9015acd5428a6d9130f2ec520dbb528c
@ccc thanks for fixing
I confirm that the fix works. Will wait for the unzip automatically feature