"""redo-ifchange: build the given targets if they have changed.""" import os, sys, traceback from . import env, builder, deps, helpers, jobserver, logs, state from .logs import debug2, err def should_build(t): f = state.File(name=t) if f.is_failed(): raise helpers.ImmediateReturn(32) dirty = deps.isdirty(f, depth='', max_changed=env.v.RUNID, already_checked=[]) return f.is_generated, dirty == [f] and deps.DIRTY or dirty def main(): rv = 202 try: targets = sys.argv[1:] state.init(targets) if env.is_toplevel and not targets: targets = ['all'] if env.is_toplevel and env.v.LOG: builder.close_stdin() builder.start_stdin_log_reader( status=True, details=True, pretty=True, color=True, debug_locks=False, debug_pids=False) else: logs.setup( tty=sys.stderr, parent_logs=env.v.LOG, pretty=env.v.PRETTY, color=env.v.COLOR) if env.v.TARGET and not env.v.UNLOCKED: me = os.path.join(env.v.STARTDIR, os.path.join(env.v.PWD, env.v.TARGET)) f = state.File(name=me) debug2('TARGET: %r %r %r\n' % (env.v.STARTDIR, env.v.PWD, env.v.TARGET)) else: f = me = None debug2('redo-ifchange: not adding depends.\n') jobserver.setup(0) try: if f: for t in targets: f.add_dep('m', t) f.save() state.commit() rv = builder.run(targets, should_build) finally: try: state.rollback() finally: try: jobserver.force_return_tokens() except Exception as e: # pylint: disable=broad-except traceback.print_exc(100, sys.stderr) err('unexpected error: %r\n' % e) rv = 1 except (KeyboardInterrupt, helpers.ImmediateReturn): if env.is_toplevel: builder.await_log_reader() sys.exit(200) state.commit() if env.is_toplevel: builder.await_log_reader() sys.exit(rv) if __name__ == '__main__': main()