def test_lineinfile_knows_about_ownership(HOME, tmpdir): system = getsystemfn(HOME) # put the 'AAA' line into my file1.txt f1 = HOME + '/file1.txt' contents(f1, 'AAA\n') # create a fake repo and add it tr = TempRepo(tmpdir, 'dotfiles') contents(tr.remotepath + '/HOMELY.py', """ from homely.general import lineinfile lineinfile('file1.txt', 'AAA') lineinfile('file1.txt', 'BBB') """) system(HOMELY('add') + [tr.url]) # check that my file1.txt now has both lines assert contents(f1) == "AAA\nBBB\n" # now remove the repo and do a full update to trigger cleanup system(HOMELY('forget') + [tr.url]) system(HOMELY('update')) # run homely update a few more times to confuse it system(HOMELY('update')) system(HOMELY('update')) # check that only the 'BBB' line was removed assert contents(f1) == "AAA\n"
def test_lineinfile_knows_about_ownership(HOME, tmpdir): system = getsystemfn(HOME) # put the 'AAA' line into my file1.txt f1 = HOME + '/file1.txt' contents(f1, 'AAA\n') # create a fake repo and add it tr = TempRepo(tmpdir, 'dotfiles') contents( tr.remotepath + '/HOMELY.py', """ from homely.general import lineinfile lineinfile('file1.txt', 'AAA') lineinfile('file1.txt', 'BBB') """) system(HOMELY('add') + [tr.url]) # check that my file1.txt now has both lines assert contents(f1) == "AAA\nBBB\n" # now remove the repo and do a full update to trigger cleanup system(HOMELY('forget') + [tr.url]) system(HOMELY('update')) # run homely update a few more times to confuse it system(HOMELY('update')) system(HOMELY('update')) # check that only the 'BBB' line was removed assert contents(f1) == "AAA\n"
def test_homely_remove(tmpdir, HOME): system = getsystemfn(HOME) def _addfake(name, createfile): # create a fake repo and add it tr = TempRepo(tmpdir, name) tf = os.path.join(HOME, createfile) contents(tr.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/%s', 'Hello from %s') """ % (createfile, name)) assert not os.path.exists(tf) system(HOMELY('add') + [tr.url]) assert contents(tf) == "Hello from %s\n" % name return tr r1 = _addfake('repo1', 'file1.txt') r2 = _addfake('repo2', 'file2.txt') r3 = _addfake('repo3', 'file3.txt') # check that all the repos are there checkrepolist(HOME, system, [r1, r2, r3]) assert contents(HOME + '/file1.txt', "Hello from repo1\n") assert contents(HOME + '/file2.txt', "Hello from repo2\n") assert contents(HOME + '/file3.txt', "Hello from repo3\n") # Check that the repo can be removed. system(HOMELY('forget') + [r1.repoid]) checkrepolist(HOME, system, [r2, r3]) assert contents(HOME + '/file1.txt', "Hello from repo1\n") assert contents(HOME + '/file2.txt', "Hello from repo2\n") assert contents(HOME + '/file3.txt', "Hello from repo3\n") # now run an update to make repo1's files go away system(HOMELY('update')) assert not os.path.exists(HOME + '/file1.txt') assert contents(HOME + '/file2.txt', "Hello from repo2\n") assert contents(HOME + '/file3.txt', "Hello from repo3\n") # Test removing multiple repos, but using local path this time # Note that because we don't use --update, the created files will still be # sitting around on disk system(HOMELY('forget') + ['~/repo2', '~/repo3']) checkrepolist(HOME, system, []) # repo2 and repo3 are stilling going to hang around on disk assert os.path.exists(HOME + '/repo2') assert os.path.exists(HOME + '/repo3') assert not os.path.exists(HOME + '/file1.txt') assert contents(HOME + '/file2.txt', "Hello from repo2\n") assert contents(HOME + '/file3.txt', "Hello from repo3\n")
def test_homely_remove(tmpdir, HOME): system = getsystemfn(HOME) def _addfake(name, createfile): # create a fake repo and add it tr = TempRepo(tmpdir, name) tf = os.path.join(HOME, createfile) contents( tr.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/%s', 'Hello from %s') """ % (createfile, name)) assert not os.path.exists(tf) system(HOMELY('add') + [tr.url]) assert contents(tf) == "Hello from %s\n" % name return tr r1 = _addfake('repo1', 'file1.txt') r2 = _addfake('repo2', 'file2.txt') r3 = _addfake('repo3', 'file3.txt') # check that all the repos are there checkrepolist(HOME, system, [r1, r2, r3]) assert contents(HOME + '/file1.txt', "Hello from repo1\n") assert contents(HOME + '/file2.txt', "Hello from repo2\n") assert contents(HOME + '/file3.txt', "Hello from repo3\n") # Check that the repo can be removed. system(HOMELY('forget') + [r1.repoid]) checkrepolist(HOME, system, [r2, r3]) assert contents(HOME + '/file1.txt', "Hello from repo1\n") assert contents(HOME + '/file2.txt', "Hello from repo2\n") assert contents(HOME + '/file3.txt', "Hello from repo3\n") # now run an update to make repo1's files go away system(HOMELY('update')) assert not os.path.exists(HOME + '/file1.txt') assert contents(HOME + '/file2.txt', "Hello from repo2\n") assert contents(HOME + '/file3.txt', "Hello from repo3\n") # Test removing multiple repos, but using local path this time # Note that because we don't use --update, the created files will still be # sitting around on disk system(HOMELY('forget') + ['~/repo2', '~/repo3']) checkrepolist(HOME, system, []) # repo2 and repo3 are stilling going to hang around on disk assert os.path.exists(HOME + '/repo2') assert os.path.exists(HOME + '/repo3') assert not os.path.exists(HOME + '/file1.txt') assert contents(HOME + '/file2.txt', "Hello from repo2\n") assert contents(HOME + '/file3.txt', "Hello from repo3\n")
def test_add_greenfield_repos(tmpdir, HOME): """ Work or at least die with a helpful error message when ... """ from homely._errors import ERR_NO_COMMITS, ERR_NOT_A_REPO, ERR_NO_SCRIPT system = getsystemfn(HOME) def _repolist(): cmd = HOMELY('repolist') + ['--format', '%(localpath)s'] return list(filter(None, system(cmd).strip().split("\n"))) # Target dir is not a git repo notarepo = HOME + '/not_a_repo' os.mkdir(notarepo) contents(notarepo + '/HOMELY.py', "print('YES')\n") output = system(HOMELY('add') + [notarepo], expecterror=1) assert ERR_NOT_A_REPO in output del notarepo, output # this should have resulted in nothing being added to homely assert not len(_repolist()) # Target dir doesn't have any commits nocommits = HOME + '/nocommits' os.mkdir(nocommits) contents(nocommits + '/HOMELY.py', "print('YES')\n") system(['git', 'init'], cwd=nocommits) assert os.path.exists(nocommits + '/.git') output = system(HOMELY('add') + [nocommits], expecterror=1) assert ERR_NO_COMMITS in output del nocommits, output # this should have resulted in nothing being added to homely assert not len(_repolist()) # Target dir doesn't have a HOMELY.py script - when we add a repo that # doesn't have a HOMELY.py script we should raise an error and provide # instructions on how to write a HOMELY.py script (and not try to do the # homely update). noscript = HOME + '/noscript' os.mkdir(noscript) readme = noscript + '/README.md' contents(readme, "Hello world!\n") system(['git', 'init'], cwd=noscript) system(['git', 'config', 'user.name', "fred"], cwd=noscript) system(['git', 'config', 'user.email', "fred@example"], cwd=noscript) system(['git', 'add', 'README.md'], cwd=noscript) system(['git', 'commit', '-m', "Added readme"], cwd=noscript) output = system(HOMELY('add') + [noscript], expecterror=1) assert ERR_NO_SCRIPT in output # the repo should have added to homely assert [noscript] == _repolist()
def test_symlink_recreate(HOME, tmpdir): system = getsystemfn(HOME) def _addfake(name, createfile): # create a fake repo and add it tr = TempRepo(tmpdir, name) tf = os.path.join(tr.remotepath, createfile) with open(tf, 'w') as f: f.write('hello world') contents( tr.remotepath + '/HOMELY.py', """ from homely.files import symlink symlink('%s', '~/%s') """ % (createfile, createfile)) system(HOMELY('add') + [tr.url]) local = '%s/%s' % (tr.suggestedlocal(HOME), createfile) assert os.readlink('%s/%s' % (HOME, createfile)) == local # add a fake repo _addfake('repo1', 'file1.txt') # try doing a homely update system(HOMELY('update'))
def test_symlink_recreate(HOME, tmpdir): system = getsystemfn(HOME) def _addfake(name, createfile): # create a fake repo and add it tr = TempRepo(tmpdir, name) tf = os.path.join(tr.remotepath, createfile) with open(tf, 'w') as f: f.write('hello world') contents(tr.remotepath + '/HOMELY.py', """ from homely.files import symlink symlink('%s', '~/%s') """ % (createfile, createfile)) system(HOMELY('add') + [tr.url]) local = '%s/%s' % (tr.suggestedlocal(HOME), createfile) assert os.readlink('%s/%s' % (HOME, createfile)) == local # add a fake repo _addfake('repo1', 'file1.txt') # try doing a homely update system(HOMELY('update'))
def test_homely_update(HOME, tmpdir): system = getsystemfn(HOME) def _addfake(name, createfile): # create a fake repo and add it tr = TempRepo(tmpdir, name) tf = os.path.join(HOME, createfile) contents( tr.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/%s', 'Hello from %s') """ % (createfile, name)) assert not os.path.exists(tf) system(HOMELY('add') + [tr.url]) assert contents(tf) == "Hello from %s\n" % name return tr template = (""" from homely.files import lineinfile lineinfile(%r, %r) """) # add some fake repos r1 = _addfake('repo1', 'file1.txt') r2 = _addfake('repo2', 'file2.txt') r3 = _addfake('repo3', 'file3.txt') # update the repos slightly, run an update, ensure all changes have gone # through (including cleanup of old content) contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'AAA')) contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'AAA')) contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'AAA')) system(HOMELY('update')) assert contents(HOME + '/file1.txt') == "AAA\n" assert contents(HOME + '/file2.txt') == "AAA\n" assert contents(HOME + '/file3.txt') == "AAA\n" # modify all the repos again contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'BBB')) contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'BBB')) contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'BBB')) # run an update again, but only do it with the 2nd repo system(HOMELY('update') + ['~/repo2']) # 1st and 3rd repos haven't been rerun assert contents(HOME + '/file1.txt') == "AAA\n" assert contents(HOME + '/file3.txt') == "AAA\n" # NOTE that the cleanup of the 2nd repo doesn't happen when we're doing a # single repo assert contents(HOME + '/file2.txt') == "AAA\nBBB\n" # run an update, but specify all repos - this should be enough to trigger # the cleanup system(HOMELY('update') + ['~/repo1', '~/repo3', '~/repo2']) assert contents(HOME + '/file1.txt') == "BBB\n" assert contents(HOME + '/file2.txt') == "BBB\n" assert contents(HOME + '/file3.txt') == "BBB\n" # modify the repos again, but run update with --nopull so that we don't get # any changes contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'CCC')) contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'CCC')) contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'CCC')) system(HOMELY('update') + ['~/repo1', '--nopull']) assert contents(HOME + '/file1.txt') == "BBB\n" assert contents(HOME + '/file2.txt') == "BBB\n" assert contents(HOME + '/file3.txt') == "BBB\n" system(HOMELY('update') + ['--nopull']) assert contents(HOME + '/file1.txt') == "BBB\n" assert contents(HOME + '/file2.txt') == "BBB\n" assert contents(HOME + '/file3.txt') == "BBB\n" # split r1 into multiple sections and just do one of them contents( r1.remotepath + '/HOMELY.py', """ from homely.files import lineinfile from homely.general import section @section def partE(): lineinfile('~/file1.txt', 'EEE') @section def partF(): lineinfile('~/file1.txt', 'FFF') @section def partG(): lineinfile('~/file1.txt', 'GGG') lineinfile('~/file1.txt', 'HHH') """) system(HOMELY('update') + ['~/repo1', '-o', 'partE']) assert contents(HOME + '/file1.txt') == "BBB\nEEE\nHHH\n" os.unlink(HOME + '/file1.txt') system(HOMELY('update') + ['~/repo1', '-o', 'partF', '-o', 'partG']) assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\n" system(HOMELY('update') + ['~/repo1', '-o', 'partF', '-o', 'partG']) assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\n" # ensure that --only isn't allowed with multiple repos system(HOMELY('update') + ['~/repo1', '~/repo2', '-o', 'something'], expecterror=1) # test that cleanup stuff doesn't happen when --only is used system(HOMELY('forget') + ['~/repo2', '~/repo3']) assert os.path.exists(HOME + '/file2.txt') assert os.path.exists(HOME + '/file3.txt') # note that this test also proves that you can use --only without naming a # repo as long as you only have one repo system(HOMELY('update') + ['-o', 'partE']) assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\nEEE\n" # these files are still hanging around because we keep using --only assert os.path.exists(HOME + '/file2.txt') assert os.path.exists(HOME + '/file3.txt') # finally do an update without --only, and file1 and file2 will be cleaned # up system(HOMELY('update')) assert not os.path.exists(HOME + '/file2.txt') assert not os.path.exists(HOME + '/file3.txt')
def test_homely_add_repolist(tmpdir, HOME): system = getsystemfn(HOME) # make a fake repo - create a dir, a folder, and a symlink repo1 = TempRepo(tmpdir, 'repo1') homedir1 = os.path.join(HOME, 'dir1') homelink1 = os.path.join(HOME, 'link1') homedir1file = os.path.join(homelink1, 'file.txt') assert not os.path.exists(homedir1) assert not os.path.islink(homelink1) contents( repo1.remotepath + '/HOMELY.py', """ from homely.files import lineinfile, mkdir, symlink mkdir('~/dir1') symlink('~/dir1', '~/link1') lineinfile('~/link1/file.txt', 'Hello World') """) # add the repo and ensure that everything was created as expected system(HOMELY('add') + [repo1.url]) assert repo1.installedin(HOME) assert os.path.isdir(homedir1) assert os.path.islink(homelink1) assert os.readlink(homelink1) == os.path.realpath(homedir1) assert contents(homedir1file) == "Hello World\n" # make another repo that creates more things repo2 = TempRepo(tmpdir, 'repo2') repo2file = os.path.join(HOME, 'file2.txt') assert not os.path.exists(repo2file) contents( repo2.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/file2.txt', 'Hey There') """) system(HOMELY('add') + [repo2.url]) assert repo2.installedin(HOME) assert contents(repo2file, "Hey There\n") checkrepolist(HOME, system, [repo1, repo2]) # a 3rd repo, but we're going to clone it into our home dir manually repo3 = TempRepo(tmpdir, 'repo3') contents( repo3.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/r3.txt', 'From R3') """) # where would it go in the home dir? localrepo3 = os.path.join(HOME, 'repo3') # use a Repo instance to clone it into our home dir manually from homely._vcs.testhandler import Repo Repo.frompath(repo3.url).clonetopath(localrepo3) # test adding a repo from the local dir assert not os.path.exists(HOME + '/r3.txt') system(HOMELY('add') + [localrepo3]) assert contents(HOME + '/r3.txt') == 'From R3\n' checkrepolist(HOME, system, [repo1, repo2, repo3]) # test that you can't add the same repo again system(HOMELY('add') + [repo2.url]) checkrepolist(HOME, system, [repo1, repo2, repo3]) # test that adding a repo with something like 'homely add .' doesn't record # a stupid path like '.' repo4 = TempRepo(tmpdir, 'repo4') contents( repo4.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/r4.txt', 'From R4') """) localrepo4 = os.path.join(HOME, 'repo4') # use a Repo instance to clone it into our home dir manually from homely._vcs.testhandler import Repo Repo.frompath(repo4.url).clonetopath(localrepo4) system(HOMELY('add') + ['.'], cwd=localrepo4) checkrepolist(HOME, system, [repo1, repo2, repo3, repo4])
def test_homely_updatestatus(HOME, tmpdir): from homely._utils import RUNFILE, FAILFILE, UpdateStatus, STATUSCODES system = getsystemfn(HOME) jobstart = getjobstartfn(HOME) exit_ok = STATUSCODES[UpdateStatus.OK] exit_never = STATUSCODES[UpdateStatus.NEVER] exit_paused = STATUSCODES[UpdateStatus.PAUSED] exit_failed = STATUSCODES[UpdateStatus.FAILED] exit_running = STATUSCODES[UpdateStatus.RUNNING] # create a special HOMELY.py script that we can control easily by putting magic files in the # right places spinfile = HOME + '/spin' diefile = HOME + '/diediedie' xdir1 = HOME + '/xdir1' assert not os.path.isdir(xdir1) # verify that homely updatestatus thinks we have never run an update system(HOMELY('updatestatus'), expecterror=exit_never) # pause autoupdate, and then check the status again system(HOMELY('autoupdate') + ['--pause']) system(HOMELY('updatestatus'), expecterror=exit_paused) # pausing again don't change anything system(HOMELY('autoupdate') + ['--pause']) system(HOMELY('updatestatus'), expecterror=exit_paused) # unpause takes us back to the previous status system(HOMELY('autoupdate') + ['--unpause']) system(HOMELY('updatestatus'), expecterror=exit_never) # add our special repo with our special file repo1 = TempRepo(tmpdir, 'repo1') contents(repo1.remotepath + '/HOMELY.py', """ import os, time, sys from homely.files import mkdir while os.path.exists(%(spinfile)r): time.sleep(0.01) assert not os.path.exists(%(diefile)r), "Incredibly bad things in %(diefile)s" mkdir('~/xdir1') """ % locals()) system(HOMELY('add') + [repo1.url]) assert os.path.isdir(xdir1) # verify that homely updatestatus thinks we have run an update system(HOMELY('updatestatus')) # use the spinfile to make homely update sit in the background while we test some more things contents(spinfile, "spin!") with jobstart(HOMELY('update')) as job: for _ in waitfor('Appearance of RUNFILE %s' % RUNFILE): if os.path.exists(RUNFILE): break # verify that updatestatus says we are currently running system(HOMELY('updatestatus'), expecterror=exit_running) # remove the spinfile so the background job can finish os.unlink(spinfile) # verify that no update is currently running, and that the last run was successful system(HOMELY('updatestatus')) # now touch the errorfile and try a new update contents(diefile, "boom!") system(HOMELY('update'), expecterror=1) # updatestatus should tell us that the previous run failed system(HOMELY('updatestatus'), expecterror=exit_failed) # the error file should exist assert os.path.exists(FAILFILE) # grab the name of the OUTFILE outfile = system(HOMELY('autoupdate') + ['--outfile']).strip() # note that a plain 'homely update' won't create the outfile for us assert not os.path.exists(outfile) # try and kick off an autoupdate daemon ... it should fail miserably because the previous # update has already failed system(HOMELY('autoupdate') + ['--daemon'], expecterror=1) # use autoupdate --reset to allow automatic updates to resume system(HOMELY('autoupdate') + ['--clear']) system(HOMELY('updatestatus'), expecterror=exit_ok) # try and kick off an autoupdate daemon again ... it should fail miserably because the previous # update was too recent system(HOMELY('autoupdate') + ['--daemon'], expecterror=1) # remove the TIMEFILE so that homely thinks an update has never been run before from homely._utils import TIMEFILE os.unlink(TIMEFILE) try: # we use the spinfile to make sure the next autoupdate is going to stall contents(spinfile, "spin!") contents(diefile, "boom!") system(HOMELY('autoupdate') + ['--daemon']) # wait for the RUNFILE to appear for _ in waitfor('Appearance of RUNFILE'): if os.path.exists(RUNFILE): break # assert that our status is "running" system(HOMELY('updatestatus'), expecterror=exit_running) finally: # remove the spinfile so that the daemon can finish os.unlink(spinfile) # wait for the runfile to disappear for _ in waitfor('Disappearance of RUNFILE %s' % RUNFILE): if not os.path.exists(RUNFILE): break # the autoupdate should have failed because of the diefile system(HOMELY('updatestatus'), expecterror=exit_failed) with open(outfile) as f: assert 'Incredibly bad things' in f.read() # let's do this again, but without the diefile os.unlink(diefile) system(HOMELY('autoupdate') + ['--clear']) # we also need to manually remove the timefile os.unlink(TIMEFILE) try: contents(spinfile, "spin!") system(HOMELY('autoupdate') + ['--daemon']) for _ in waitfor('Appearance of RUNFILE'): if os.path.exists(RUNFILE): break system(HOMELY('updatestatus'), expecterror=exit_running) finally: os.unlink(spinfile) for _ in waitfor('Disappearance of RUNFILE %s' % RUNFILE): if not os.path.exists(RUNFILE): break # updatestatus should show that the update was successful system(HOMELY('updatestatus'), expecterror=exit_ok)
def test_homely_update(HOME, tmpdir): system = getsystemfn(HOME) def _addfake(name, createfile): # create a fake repo and add it tr = TempRepo(tmpdir, name) tf = os.path.join(HOME, createfile) contents(tr.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/%s', 'Hello from %s') """ % (createfile, name)) assert not os.path.exists(tf) system(HOMELY('add') + [tr.url]) assert contents(tf) == "Hello from %s\n" % name return tr template = (""" from homely.files import lineinfile lineinfile(%r, %r) """) # add some fake repos r1 = _addfake('repo1', 'file1.txt') r2 = _addfake('repo2', 'file2.txt') r3 = _addfake('repo3', 'file3.txt') # update the repos slightly, run an update, ensure all changes have gone # through (including cleanup of old content) contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'AAA')) contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'AAA')) contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'AAA')) system(HOMELY('update')) assert contents(HOME + '/file1.txt') == "AAA\n" assert contents(HOME + '/file2.txt') == "AAA\n" assert contents(HOME + '/file3.txt') == "AAA\n" # modify all the repos again contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'BBB')) contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'BBB')) contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'BBB')) # run an update again, but only do it with the 2nd repo system(HOMELY('update') + ['~/repo2']) # 1st and 3rd repos haven't been rerun assert contents(HOME + '/file1.txt') == "AAA\n" assert contents(HOME + '/file3.txt') == "AAA\n" # NOTE that the cleanup of the 2nd repo doesn't happen when we're doing a # single repo assert contents(HOME + '/file2.txt') == "AAA\nBBB\n" # run an update, but specify all repos - this should be enough to trigger # the cleanup system(HOMELY('update') + ['~/repo1', '~/repo3', '~/repo2']) assert contents(HOME + '/file1.txt') == "BBB\n" assert contents(HOME + '/file2.txt') == "BBB\n" assert contents(HOME + '/file3.txt') == "BBB\n" # modify the repos again, but run update with --nopull so that we don't get # any changes contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'CCC')) contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'CCC')) contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'CCC')) system(HOMELY('update') + ['~/repo1', '--nopull']) assert contents(HOME + '/file1.txt') == "BBB\n" assert contents(HOME + '/file2.txt') == "BBB\n" assert contents(HOME + '/file3.txt') == "BBB\n" system(HOMELY('update') + ['--nopull']) assert contents(HOME + '/file1.txt') == "BBB\n" assert contents(HOME + '/file2.txt') == "BBB\n" assert contents(HOME + '/file3.txt') == "BBB\n" # split r1 into multiple sections and just do one of them contents(r1.remotepath + '/HOMELY.py', """ from homely.files import lineinfile from homely.general import section @section def partE(): lineinfile('~/file1.txt', 'EEE') @section def partF(): lineinfile('~/file1.txt', 'FFF') @section def partG(): lineinfile('~/file1.txt', 'GGG') lineinfile('~/file1.txt', 'HHH') """) system(HOMELY('update') + ['~/repo1', '-o', 'partE']) assert contents(HOME + '/file1.txt') == "BBB\nEEE\nHHH\n" os.unlink(HOME + '/file1.txt') system(HOMELY('update') + ['~/repo1', '-o', 'partF', '-o', 'partG']) assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\n" system(HOMELY('update') + ['~/repo1', '-o', 'partF', '-o', 'partG']) assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\n" # ensure that --only isn't allowed with multiple repos system(HOMELY('update') + ['~/repo1', '~/repo2', '-o', 'something'], expecterror=1) # test that cleanup stuff doesn't happen when --only is used system(HOMELY('forget') + ['~/repo2', '~/repo3']) assert os.path.exists(HOME + '/file2.txt') assert os.path.exists(HOME + '/file3.txt') # note that this test also proves that you can use --only without naming a # repo as long as you only have one repo system(HOMELY('update') + ['-o', 'partE']) assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\nEEE\n" # these files are still hanging around because we keep using --only assert os.path.exists(HOME + '/file2.txt') assert os.path.exists(HOME + '/file3.txt') # finally do an update without --only, and file1 and file2 will be cleaned # up system(HOMELY('update')) assert not os.path.exists(HOME + '/file2.txt') assert not os.path.exists(HOME + '/file3.txt')
def test_homely_add_repolist(tmpdir, HOME): system = getsystemfn(HOME) # make a fake repo - create a dir, a folder, and a symlink repo1 = TempRepo(tmpdir, 'repo1') homedir1 = os.path.join(HOME, 'dir1') homelink1 = os.path.join(HOME, 'link1') homedir1file = os.path.join(homelink1, 'file.txt') assert not os.path.exists(homedir1) assert not os.path.islink(homelink1) contents(repo1.remotepath + '/HOMELY.py', """ from homely.files import lineinfile, mkdir, symlink mkdir('~/dir1') symlink('~/dir1', '~/link1') lineinfile('~/link1/file.txt', 'Hello World') """) # add the repo and ensure that everything was created as expected system(HOMELY('add') + [repo1.url]) assert repo1.installedin(HOME) assert os.path.isdir(homedir1) assert os.path.islink(homelink1) assert os.readlink(homelink1) == os.path.realpath(homedir1) assert contents(homedir1file) == "Hello World\n" # make another repo that creates more things repo2 = TempRepo(tmpdir, 'repo2') repo2file = os.path.join(HOME, 'file2.txt') assert not os.path.exists(repo2file) contents(repo2.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/file2.txt', 'Hey There') """) system(HOMELY('add') + [repo2.url]) assert repo2.installedin(HOME) assert contents(repo2file, "Hey There\n") checkrepolist(HOME, system, [repo1, repo2]) # a 3rd repo, but we're going to clone it into our home dir manually repo3 = TempRepo(tmpdir, 'repo3') contents(repo3.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/r3.txt', 'From R3') """) # where would it go in the home dir? localrepo3 = os.path.join(HOME, 'repo3') # use a Repo instance to clone it into our home dir manually from homely._vcs.testhandler import Repo Repo.frompath(repo3.url).clonetopath(localrepo3) # test adding a repo from the local dir assert not os.path.exists(HOME + '/r3.txt') system(HOMELY('add') + [localrepo3]) assert contents(HOME + '/r3.txt') == 'From R3\n' checkrepolist(HOME, system, [repo1, repo2, repo3]) # test that you can't add the same repo again system(HOMELY('add') + [repo2.url]) checkrepolist(HOME, system, [repo1, repo2, repo3]) # test that adding a repo with something like 'homely add .' doesn't record # a stupid path like '.' repo4 = TempRepo(tmpdir, 'repo4') contents(repo4.remotepath + '/HOMELY.py', """ from homely.files import lineinfile lineinfile('~/r4.txt', 'From R4') """) localrepo4 = os.path.join(HOME, 'repo4') # use a Repo instance to clone it into our home dir manually from homely._vcs.testhandler import Repo Repo.frompath(repo4.url).clonetopath(localrepo4) system(HOMELY('add') + ['.'], cwd=localrepo4) checkrepolist(HOME, system, [repo1, repo2, repo3, repo4])